diff --git a/about/our-web-team-alumni.php b/about/our-web-team-alumni.php new file mode 100644 index 00000000..6d5c117a --- /dev/null +++ b/about/our-web-team-alumni.php @@ -0,0 +1,108 @@ +'Peyton Thibodeaux', + 'title'=>'Webmaster', + 'description'=>"Peyton is a junior, studying computer science with a minor in mathematics. He's the webmaster for UNT Robotics and in charge of the website that you see in front of you. He enjoys learning and using new technologies and have a passion for creating things.", + 'picture_uri'=>'/images/web-team-pics/peyton-thibodeaux.jpg', + 'email'=>'webmaster@untrobotics.com', + 'linkedin_url'=>'https://www.linkedin.com/in/peyton-thibodeaux', + 'github_url'=>'https://www.github.com/peyton232', +// 'twitter_url'=>'' +]; +$members[] = [ + 'name'=>'Nicholas Tindle', + 'title'=>'Team Member', + 'description'=>"Nicholas Tindle is a Computer Engineering student at UNT. He works in software engineering and loves hackathons. You can generally find him wearing a hat and probably a sweatshirt. He has a long history of collaboration with UNT Robotics as the first president, a loyal advisor, and now Project Manager. He has also served as an advisor to the Dean and is currently an officer of Engineering United. Nick has helped host numerous events at the university over the years. In his professional life, he works in data analysis, web development, and python scripting.", + 'picture_uri'=>'/images/web-team-pics/nick-tindle.jpg', + 'linkedin_url'=>'https://www.linkedin.com/in/ntindle', + 'github_url'=>'https://www.github.com/ntindle', +]; +$members[] = [ + 'name'=>'Henry Legay', + 'title'=>'Team Member', + 'description'=>"Henry Legay is a Computer Science Student at UNT focused on web development. He is a web developer in Robotics with ready applicable experience and a willingness to learn.", + 'picture_uri'=>'/images/web-team-pics/henry-legay.jpg', + 'linkedin_url'=>'https://www.linkedin.com/in/henrylegay', + 'github_url'=>'https://www.github.com/henlegay', +]; + +$members[] = [ + 'name'=>'Mason Besmer', + 'title'=>'Team Member', + 'description'=>"Mason Besmer is a Computer Science student at UNT. He is a webmaster for UNT Robotics and participates in many student orgs. He creates many things and comes up with ideas for even more. In his free time, he likes to create environments for games and program the website in front of you. He likes organization and loves to tinker with things. Creator of his own magic mirror, Mason is a advocate for building his own electronics. Currently, he is working on a software solution for his Starcube. You can find out more about it on his LinkedIn.", + 'picture_uri'=>'/images/web-team-pics/mason-besmer.jpg', + 'linkedin_url'=>'https://www.linkedin.com/in/masonbesmer', + 'github_url'=>'https://www.github.com/shotbyapony', +]; +$members[] = [ + 'name'=>'Aryan Damle', + 'title'=>'Team Member', + 'description'=>"Aryan Damle is a Computer Science student at UNT. He is an aspiring full stack web developer and an avid Home Assistant enthusiast. He mentors a high school robotics team and loves to work on robots in his free time. You can find him at your local car meet on weekends if he isn't busy working on a robot or fixing something in his garage.", + 'picture_uri'=>'/images/web-team-pics/aryan-damle.jpg', + 'linkedin_url'=>'https://www.linkedin.com/in/aryan-damle-8691b11bb', + 'github_url'=>'https://www.github.com/aryan-damle', +]; +$members[] = [ + 'name'=>'Mary Plana', + 'title'=>'Team Member', + 'description'=>"Mary Plana is a Computer Science Student at UNT with studies focused on Front End Development. She loves designing and implementing the user interface of a project. She has a natural curiosity about the world and loves to learn and improve her skills. She is currently the president of Application Development Organization. She facilitates the meeting and leads student UI designers to design, implement, and improve the user interface of projects.", + 'picture_uri'=>'/images/web-team-pics/mary-plana.jpg', + 'linkedin_url'=>'https://www.linkedin.com/in/mary-plana', + 'github_url'=>'https://www.github.com/mcp31', +]; +$members[] = [ + 'name'=>'David Thompson', + 'title'=>'Team Member', + 'description'=>"David Thompson is a Computer Science Student at UNT with studies focused on Full Stack Development. He loves solving problems, learning new things, and is currently working with a start up on a social media application that is currently in Apple's TestFlight.", + 'picture_uri'=>'/images/web-team-pics/david-thompson.jpg', + 'linkedin_url'=>'https://www.linkedin.com/in/david-thompson-000', + 'github_url'=>'https://www.github.com/davidkt99', +]; +$members[] = [ + 'name'=>'Samin Yasar', + 'title'=>'Team Member', + 'description'=>"Samin Yasar is a senior Computer Science student at UNT. He is a team member of UNT Robotics webmaster helping maintain UNT Robotics website. He is also a part of the Application Development Organization as a team member. He likes to learn new things and solve complex problems.", + 'picture_uri'=>'/images/web-team-pics/samin-yasar.jpg', + 'linkedin_url'=>'https://www.linkedin.com/in/samin2668', + 'github_url'=>'https://www.github.com/samin2668', +]; +?> +
+ + +
+
+
+
+

Our Web Team Alumni

+
Meet the talented developers who helped shape our website into what it is today.
+
+
+ +
+
+
+ diff --git a/about/our-web-team.php b/about/our-web-team.php index 23b6b742..e7283053 100644 --- a/about/our-web-team.php +++ b/about/our-web-team.php @@ -3,107 +3,22 @@ require('card.php'); head('Our Team', true); $members = array(); -$members[] = [ - 'name'=>'Peyton Thibodeaux', - 'title'=>'Webmaster | Team Member', - 'description'=>"Peyton is a junior, studying computer science with a minor in mathematics. He's the webmaster for UNT Robotics and in charge of the website that you see in front of you. He enjoys learning and using new technologies and have a passion for creating things.", - 'picture_uri'=>'/images/web-team-pics/peyton-thibodeaux.jpg', - 'email'=>'webmaster@untrobotics.com', - 'linkedin_url'=>'https://www.linkedin.com/in/peyton-thibodeaux', - 'github_url'=>'https://www.github.com/peyton232', -// 'twitter_url'=>'' -]; + $members[] = [ 'name'=>'Sebastian King', 'title'=>'Alumni | Team Member', 'description'=>"Sebastian is a post-baccalaureate world languages student, with a degree in Computer Science. His role is to oversee the day-to-day running of the organisation and help ensure the organisation best serves the students at UNT. His expertise are programming and electrical engineering and he specialises in networking and remote control systems. He is also responsible for a lot of the more ambitious projects around campus, including the famous Sofabot and our re-usable weather balloon project.", 'picture_uri'=>'/images/web-team-pics/sebastian-king.jpg', -// 'email'=>'', 'linkedin_url'=>'https://www.linkedin.com/in/sebastian-king', 'github_url'=>'https://www.github.com/sebastian-king', -// 'twitter_url'=>'' -]; -$members[] = [ - 'name'=>'Nicholas Tindle', - 'title'=>'President | Team Member', - 'description'=>"Nicholas Tindle is a Computer Engineering student at UNT. He works in software engineering and loves hackathons. You can generally find him wearing a hat and probably a sweatshirt. He has a long history of collaboration with UNT Robotics as the first president, a loyal advisor, and now Project Manager. He has also served as an advisor to the Dean and is currently an officer of Engineering United. Nick has helped host numerous events at the university over the years. In his professional life, he works in data analysis, web development, and python scripting.", - 'picture_uri'=>'/images/web-team-pics/nick-tindle.jpg', -// 'email'=>'', - 'linkedin_url'=>'https://www.linkedin.com/in/ntindle', - 'github_url'=>'https://www.github.com/ntindle', -// 'twitter_url'=>'' -]; -$members[] = [ - 'name'=>'Henry Legay', - 'title'=>'Team Member', - 'description'=>"Henry Legay is a Computer Science Student at UNT focused on web development. He is a web developer in Robotics with ready applicable experience and a willingness to learn.", - 'picture_uri'=>'/images/web-team-pics/henry-legay.jpg', -// 'email'=>'', - 'linkedin_url'=>'https://www.linkedin.com/in/henrylegay', - 'github_url'=>'https://www.github.com/henlegay', -// 'twitter_url'=>'' -]; -$members[] = [ - 'name'=>'Mason Besmer', - 'title'=>'Team Member', - 'description'=>"Mason Besmer is a Computer Science student at UNT. He is a webmaster for UNT Robotics and participates in many student orgs. He creates many things and comes up with ideas for even more. In his free time, he likes to create environments for games and program the website in front of you. He likes organization and loves to tinker with things. Creator of his own magic mirror, Mason is a advocate for building his own electronics. Currently, he is working on a software solution for his Starcube. You can find out more about it on his LinkedIn.", - 'picture_uri'=>'/images/web-team-pics/mason-besmer.jpg', -// 'email'=>'', - 'linkedin_url'=>'https://www.linkedin.com/in/masonbesmer', - 'github_url'=>'https://www.github.com/shotbyapony', -// 'twitter_url'=>'' -]; -$members[] = [ - 'name'=>'Aryan Damle', - 'title'=>'Team Member', - 'description'=>"Aryan Damle is a Computer Science student at UNT. He is an aspiring full stack web developer and an avid Home Assistant enthusiast. He mentors a high school robotics team and loves to work on robots in his free time. You can find him at your local car meet on weekends if he isn't busy working on a robot or fixing something in his garage.", - 'picture_uri'=>'/images/web-team-pics/aryan-damle.jpg', -// 'email'=>'', - 'linkedin_url'=>'https://www.linkedin.com/in/aryan-damle-8691b11bb', - 'github_url'=>'https://www.github.com/aryan-damle', -// 'twitter_url'=>'' ]; -$members[] = [ - 'name'=>'Mary Plana', - 'title'=>'Team Member', - 'description'=>"Mary Plana is a Computer Science Student at UNT with studies focused on Front End Development. She loves designing and implementing the user interface of a project. She has a natural curiosity about the world and loves to learn and improve her skills. She is currently the president of Application Development Organization. She facilitates the meeting and leads student UI designers to design, implement, and improve the user interface of projects.", - 'picture_uri'=>'/images/web-team-pics/mary-plana.jpg', -// 'email'=>'', - 'linkedin_url'=>'https://www.linkedin.com/in/mary-plana', - 'github_url'=>'https://www.github.com/mcp31', -// 'twitter_url'=>'' -]; -$members[] = [ - 'name'=>'David Thompson', - 'title'=>'Team Member', - 'description'=>"David Thompson is a Computer Science Student at UNT with studies focused on Full Stack Development. He loves solving problems, learning new things, and is currently working with a start up on a social media application that is currently in Apple's TestFlight.", - 'picture_uri'=>'/images/web-team-pics/david-thompson.jpg', -// 'email'=>'', - 'linkedin_url'=>'https://www.linkedin.com/in/david-thompson-000', - 'github_url'=>'https://www.github.com/davidkt99', -// 'twitter_url'=>'' -]; - -$members[] = [ - 'name'=>'Samin Yasar', - 'title'=>'Team Member', - 'description'=>"Samin Yasar is a senior Computer Science student at UNT. He is a team member of UNT Robotics webmaster helping maintain UNT Robotics website. He is also a part of the Application Development Organization as a team member. He likes to learn new things and solve complex problems.", - 'picture_uri'=>'/images/web-team-pics/samin-yasar.jpg', -// 'email'=>'', - 'linkedin_url'=>'https://www.linkedin.com/in/samin2668', - 'github_url'=>'https://www.github.com/samin2668', -// 'twitter_url'=>'' -]; - $members[] = [ 'name'=>'Kenneth Chen', 'title'=>'Team Member', 'description'=>"Kenneth Chen is a Computer Science and Accounting student at UNT. As part of UNT Robotics, he's programmed helpful things, such as the controller connections for Botathon Season 3. He is also the financial director of UNT Robotics. He enjoys learnings and helping others and hopes to make the website more accessible.", 'picture_uri'=>'/images/bio-pics/kenneth-chen.jpg', -// 'email'=>'', 'linkedin_url'=>'https://www.linkedin.com/in/kenneth-w-chen', 'github_url'=>'https://www.github.com/kenneth-w-chen', -// 'twitter_url'=>'' ]; $members[] = [ 'name'=>'Truitt Crozier', @@ -113,7 +28,6 @@ 'linkedin_url'=>'https://www.linkedin.com/in/truitt-crozier-719355293', 'github_url'=>'https://github.com/tjcrozier', ]; - $members[] = [ 'name'=>'Willow Houchin', 'title'=>'Team Member', @@ -122,7 +36,6 @@ 'linkedin_url'=>'https://www.linkedin.com/in/willow-houchin-127147252', 'github_url'=>'https://www.github.com/WillowHouchin', ]; - $members[] = [ 'name'=>'Logan Brewer', 'title'=>'Team Member', @@ -131,7 +44,6 @@ 'linkedin_url'=>'https://www.linkedin.com/in/logan-brewer-26a872256/', 'github_url'=>'https://github.com/loganthebrewer', ]; - ?>
@@ -154,7 +66,8 @@

Our Web Dev Team

-
These are the people who keep this site running.
+
These are the people who keep this site running. Meet our former web devs here. +
query(" + SELECT + id, + config_id, + last_sucessfully_retrieved, + last_attempted_retrieval, + retry_count, + endpoint_args, + UNCOMPRESS(content) AS content + FROM + api_cache + INNER JOIN + outgoing_request_cache_config + ON + api_cache.config_id = outgoing_request_cache_config.id + WHERE + endpoint = '{$db->real_escape_string($endpoint)}' + AND + endpoint_args = '{$db->real_escape_string(serialize($args))}' + "); + if ($q) { + $r = $q->fetch_array(MYSQLI_ASSOC); + return $r; + } + return null; +} + +class CacheResult +{ + /** + * @var string $content The response content + */ + public $content; + /** + * @var bool $fetched_new_content true if curl_exec was called, false otherwise + */ + public $fetched_new_content; + /** + * @var int|null $httpcode HTTP response code from cURL. Null if curl_exec wasn't called + * @var int|null $curl_errno cURL error number. Null if curl_exec wasn't called + */ + public $http_code, $curl_errno; + + /** + * @param string $content + * @param bool $fetched_new_content Defaults to false + * @param int|null $httpcode (optional) + * @param int|null $curl_errno (optional) + */ + public function __construct(string $content, bool $fetched_new_content = false, $httpcode = null, $curl_errno = null) { + $this->content = $content; + $this->fetched_new_content = $fetched_new_content; + $this->http_code = $httpcode; + $this->curl_errno = $curl_errno; + } +} + +/** + * Gets the first entry from the API cache that has a matching endpoint. If the entry is expired or does not exist, returns the results from executing cURL. Updates the cache with fetched results if the entry existed + * @param string $endpoint The endpoint for the API request + * @param resource|CurlHandle $ch The Curl Handle to send the request + * @param mixed ...$args Endpoint args + * @return CacheResult An object containing the response content, and some cURL info if curl_exec was called + */ +function get_valid_cache_entry(string $endpoint, $ch, ...$args) { + global $db; + $q = $db->query(" + SELECT + outgoing_request_cache_config.id AS conf_id, + ttl, + UNCOMPRESS(content) AS content, + last_successfully_retrieved + FROM + outgoing_request_cache_config + LEFT JOIN + api_cache + ON + outgoing_request_cache_config.id = api_cache.config_id + WHERE + endpoint = '{$db->real_escape_string($endpoint)}' + AND + endpoint_args = '{$db->real_escape_string(serialize($args))}' + "); + if ($q === false) { + error_log("Failed to retrieve endpoint \"" . qualify_endpoint($endpoint, ...$args) . "\" from cache table: {$db->error}"); + return null; + } + if ($q && $q->num_rows > 0) { + $r = $q->fetch_array(MYSQLI_ASSOC); + if ($r['content'] !== null) { + $ttl = $r['ttl']; + $now = time(); + $retrieval_time = $r['last_successfully_retrieved']; + if ($retrieval_time !== null && $now - strtotime($retrieval_time . 'UTC') < $ttl) { + return new CacheResult($r['content']); + } + } + $config_id = $r['conf_id']; + $can_be_cached = true; + } + //inserts args into the endpoint at '$#' (e.g., $1, $2, $3, will be replaced by arg 1, arg 2, arg 3, respectively) + + $endpoint_full = qualify_endpoint($endpoint, ...$args); + curl_setopt($ch, CURLOPT_URL, $endpoint_full); + $result = curl_exec($ch); + // add to cache if old cache entry, no errors, and HTTP OK + $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if (!isset($can_be_cached)) { // if set, specific endpoint is already in db, so we can try to cache + $config_id = get_config_id($endpoint); + if ($config_id === null) { + error_log("Failed to check cachability of endpoint \"{$endpoint_full}\". Result not cached."); + return new CacheResult(curl_exec($ch), true, $response_code, curl_errno($ch)); + } + // $config_id should be false if the endpoint can't be cached, otherwise it should be an int + $can_be_cached = $config_id !== false; + } + if ($can_be_cached && !curl_errno($ch) && $response_code >= 200 && $response_code <= 299) { + cache($endpoint, $result, $config_id, ...$args); + } + + return new CacheResult(curl_exec($ch), true, $response_code, curl_errno($ch)); +} + +/** + * Adds or updates an entry into the cache table. Does not check if data should be cached + * @param string $endpoint The endpoint for the API request + * @param string $content The content of API request's response + * @param int $config_id The ID of the config or its name in the config table + * @param mixed ...$args The endpoint args for the API request + */ +function cache(string $endpoint, string $content, int $config_id, ...$args) { + global $db; + $r = get_cached_api_response($endpoint, ...$args); + if ($r) { + $id = $r['id']; + $query_string = ' + UPDATE + api_cache + SET + last_successfully_retrieved = UTC_TIMESTAMP, + last_attempted_retrieval = UTC_TIMESTAMP, + retry_count = 0, + content = COMPRESS(\'' . $db->real_escape_string($content) . '\') + WHERE + id = ' . $id; + } else { + $query_string = " + INSERT INTO + api_cache + (config_id, + last_successfully_retrieved, + last_attempted_retrieval, + endpoint_args, + content) + VALUES + ({$config_id}, + UTC_TIMESTAMP, + UTC_TIMESTAMP, + '{$db->real_escape_string(implode('|', $args))}', + COMPRESS('{$db->real_escape_string($content)}'))"; + } + $q = $db->query($query_string); + if (!$q) { + error_log("Failed to update API cache for endpoint \"" . qualify_endpoint($endpoint, ...$args) . "\": {$db->error}"); + } +} + +/** + * Gives the id of an endpoint for the outgoing_request_cache_config table + * @param string $endpoint The endpoint to check + * @return mixed|null Returns null on MySQLi error. Returns false if no entry exists, or, if one exists, the config ID + * This is not good practice + */ +function get_config_id(string $endpoint) { + global $db; + $q = $db->query(" + SELECT + id + FROM + outgoing_request_cache_config + WHERE + endpoint = '{$db->real_escape_string($endpoint)}' + "); + if ($q === false) { + error_log("Failed to retrieve endpoint {$endpoint} from cache config table: {$db->error}"); + return null; + } + // return $q->fetch_column(0); + if ($q->num_rows < 1) + return false; + return $q->fetch_row()[0]; +} + +///** +// * Deletes an entry from the cache or deletes all entries from the cache. +// * @param string|null $endpoint The endpoint of the API request to be removed. If null, empties the cache +// */ +//function clear_cached(string $endpoint = null) { +// global $db; +// if ($endpoint) { +// $query_string = "DELETE FROM api_cache WHERE endpoint = '" . $db->real_escape_string($endpoint) . "'"; +// } else { +// $query_string = "DELETE FROM api_cache"; +// } +// $q = $db->query($query_string); +// if ($q === false) { +// error_log("Failed to clear API cache: " . $db->error); +// } +//} + +/** + * Adds a new cache config to the config table. + * @param int $ttl The time to live for cached entries, measured in seconds + * @param string $config_name The name of the config + * @param string $endpoint The endpoint for the config + * @return bool|mysqli_result The results of the MySQLi query + */ +function add_new_cache_config(int $ttl, string $config_name, string $endpoint) { + global $db; + return $db->query(" + INSERT INTO + outgoing_request_cache_config (ttl, config_name, endpoint) + VALUES + ({$ttl}, '{$db->real_escape_string($config_name)}', '{$db->real_escape_string($endpoint)}') + "); +} + +/** + * Updates the information of one of the cache configs. Does nothing if both $config_name and $ttl are null + * @param int $id The ID of the config to be updated + * @param string|null $config_name (optional) The name of the config + * @param int|null $ttl (optional) The time to live for cached entries, measured in seconds + */ +function update_cache_config(int $id, $config_name = null, $ttl = null) { + global $db; + if ($config_name === null) { + if ($ttl === null) + return; + $query_string = ' + UPDATE + outgoing_request_cache_config + SET + ttl = ' . $ttl . ' + WHERE + id = ' . $id; + } else if ($ttl === null) { + $query_string = " + UPDATE + outgoing_request_cache_config + SET + config_name = '{$db->real_escape_string($config_name)}' + WHERE + id = {$id}"; + } else { + $query_string = "UPDATE + outgoing_request_cache_config + SET + ttl= {$ttl}, config_name = '{$db->real_escape_string($config_name)}' + WHERE + id = {$id}"; + } + $q = $db->query($query_string); + if (!$q) { + error_log("Failed to update API cache config, ID {$id}: {$db->error}"); + } +} + +/** + * Inserts arguments into an endpoint string. + * The expected format is "$1/$2/$3...$n" + * Forward slashes and other URL symbols will not be added automatically. Include those in the vararg + * @param string $endpoint The endpoint to insert args into + * @param mixed ...$args The arguments to insert into endpoint + * @return string The endpoint with each "$#" replaced with its corresponding vararg + */ +function qualify_endpoint(string $endpoint, ...$args): string { + $search = array(); + for ($i = 1; $i <= count($args); $i++) { + $search[] = '$' . $i; + } + return str_replace($search, $args, $endpoint); +} \ No newline at end of file diff --git a/api/printful/printful.php b/api/printful/printful.php index 488cb2c5..81b148e6 100644 --- a/api/printful/printful.php +++ b/api/printful/printful.php @@ -1,19 +1,16 @@ api_key = $printful_api_key; } - protected function send_request($URI, $data = false) { + protected function send_request($URI, $data = false, ...$args) { $ch = curl_init(); - $headers = array(); $headers[] = 'Authorization: Bearer ' . $this->api_key; - - curl_setopt($ch, CURLOPT_URL, 'https://api.printful.com/' . $URI); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if ($data !== false) { @@ -26,23 +23,22 @@ protected function send_request($URI, $data = false) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - $result = curl_exec($ch); - - $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $cache_result = get_valid_cache_entry('https://api.printful.com/' . $URI, $ch, ...$args); - if (curl_errno($ch)) { - //echo 'Error:' . curl_error($ch); - // TODO: handle errors - throw new PrintfulCustomAPIException("Encountered an error executing the API request at {$URI}: " . curl_error($ch), 1); - } + if($cache_result->fetched_new_content) { + if ($cache_result->curl_errno) { + // TODO: handle errors + throw new PrintfulCustomAPIException("Encountered an error executing the API request at {$URI}: " . curl_error($ch), 1); + } - if ($httpcode != 200) { - throw new PrintfulCustomAPIException("Received non-success response from the API request at {$URI}: {$httpcode} --- RAW: {$result}", 2); + if ($cache_result->http_code != 200) { + throw new PrintfulCustomAPIException("Received non-success response from the API request at {$URI}: {$cache_result->http_code} --- RAW: {$cache_result->content}", 2); + } } curl_close($ch); - return json_decode($result); + return json_decode($cache_result->content); } public function create_order_single($name, $shipping_address, $item_price, $quantity, $sync_variant_id, $options = null, $amount_paid = null) { @@ -86,7 +82,7 @@ public function create_order_single($name, $shipping_address, $item_price, $quan } public function confirm_order($order_id) { - $create_order_results = $this->send_request("orders/{$order_id}/confirm", null); + $create_order_results = $this->send_request("orders/$1/confirm", null, $order_id); $parsed_created_order_results = $this->parse_results($create_order_results); $order = new PrintfulOrder($parsed_created_order_results->get_results()); @@ -98,7 +94,8 @@ public function get_products($search_string = "") { if (!empty($search_string)) { $search_string = "&search=" . $search_string; } - $products_results = $this->send_request("store/products?limit=10" . $search_string); + + $products_results = $this->send_request("store/products$1", false, "?limit=10" . $search_string); $parsed_products_results = $this->parse_results($products_results); foreach ($parsed_products_results->get_results() as $product) { @@ -113,7 +110,7 @@ public function get_product($product_id) { throw new PrintfulCustomAPIException("Null or empty product id passed."); } - $product_results = $this->send_request("store/products/{$product_id}"); + $product_results = $this->send_request("store/products/$1", false, $product_id); $parsed_product_results = $this->parse_results($product_results); if ($parsed_product_results->get_results()) { @@ -128,7 +125,7 @@ public function get_variant($sync_variant_id) { throw new PrintfulCustomAPIException("Null or empty sync variant id passed."); } - $sync_variant_results = $this->send_request("store/variants/{$sync_variant_id}"); + $sync_variant_results = $this->send_request("store/variants/$1", false, $sync_variant_id); $parsed_sync_variant_results = $this->parse_results($sync_variant_results); if ($parsed_sync_variant_results->get_results()) { @@ -149,7 +146,7 @@ public function get_catalog_variant($variant_id) { throw new PrintfulCustomAPIException("Null or empty variant id passed."); } - $variant_results = $this->send_request("products/variant/{$variant_id}"); + $variant_results = $this->send_request("products/variant/$1", false, $variant_id); $parsed_variant_results = $this->parse_results($variant_results); if ($parsed_variant_results->get_results()) { @@ -164,7 +161,7 @@ public function get_catalog_product($product_id) { throw new PrintfulCustomAPIException("Null or empty product id passed."); } - $product_results = $this->send_request("products/{$product_id}"); + $product_results = $this->send_request("products/$1", false, $product_id); $parsed_product_results = $this->parse_results($product_results); if ($parsed_product_results->get_results()) { diff --git a/sql/migrations/URW-178-cache-configs.sql b/sql/migrations/URW-178-cache-configs.sql new file mode 100644 index 00000000..520e9ce2 --- /dev/null +++ b/sql/migrations/URW-178-cache-configs.sql @@ -0,0 +1,5 @@ +INSERT INTO outgoing_request_cache_config (ttl,config_name,endpoint) VALUES (86400, 'printful', 'https://api.printful.com/products/$1'); +INSERT INTO outgoing_request_cache_config (ttl,config_name,endpoint) VALUES (86400, 'printful', 'https://api.printful.com/products/variant/$1'); +INSERT INTO outgoing_request_cache_config (ttl,config_name,endpoint) VALUES (86400, 'printful', 'https://api.printful.com/store/products/$1'); +INSERT INTO outgoing_request_cache_config (ttl,config_name,endpoint) VALUES (86400, 'printful', 'https://api.printful.com/store/products$1'); +INSERT INTO outgoing_request_cache_config (ttl,config_name,endpoint) VALUES (86400, 'printful', 'https://api.printful.com/store/variants/$1'); \ No newline at end of file diff --git a/sql/migrations/URW-64-ftp-users.sql b/sql/migrations/URW-64-ftp-users.sql new file mode 100644 index 00000000..110d98a4 --- /dev/null +++ b/sql/migrations/URW-64-ftp-users.sql @@ -0,0 +1,10 @@ +ALTER TABLE ftpusers + ADD UNIQUE (name); + +ALTER TABLE ftpusers + MODIFY name char(128) NOT NULL; + +ALTER TABLE ftpusers + MODIFY passwd char(128) NOT NULL; + +CREATE TABLE ftpinvites (id int primary key auto_increment, email varchar(255), registration_token varchar(16)); \ No newline at end of file diff --git a/sql/migrations/URW-64.sql b/sql/migrations/URW-64.sql deleted file mode 100644 index 23d1a99b..00000000 --- a/sql/migrations/URW-64.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE TABLE ftpinvites (id int primary key auto_increment, email varchar(255), registration_token varchar(16)); diff --git a/sql/migrations/urw-64.sql b/sql/migrations/urw-64.sql deleted file mode 100644 index 91239695..00000000 --- a/sql/migrations/urw-64.sql +++ /dev/null @@ -1,10 +0,0 @@ -ALTER TABLE ftpusers -ADD UNIQUE (name); - -ALTER TABLE ftpusers -MODIFY name char(128) NOT NULL; - -ALTER TABLE ftpusers -MODIFY passwd char(128) NOT NULL; - -CREATE TABLE ftpinvites (id int primary key auto_increment, email varchar(255), registration_token varchar(16)); diff --git a/sql/outgoing_request_cache.sql b/sql/outgoing_request_cache.sql new file mode 100644 index 00000000..b6a35f8a --- /dev/null +++ b/sql/outgoing_request_cache.sql @@ -0,0 +1,23 @@ +SET FOREIGN_KEY_CHECKS = 0; +DROP TABLE IF EXISTS `outgoing_request_cache_config`; +SET FOREIGN_KEY_CHECKS = 1; +CREATE TABLE `outgoing_request_cache_config`( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ttl` int(6) NOT NULL, -- ttl measured in seconds + `config_name` varchar(255) NOT NULL, + `endpoint` varchar(4000) NOT NULL, -- endpoint with '{}' replacing specific info, e.g., https://api.printful.com/store/products/{} instead of https://api.printful.com/store/products/@5f6ceb2cf3a5e5 + PRIMARY KEY (id) +)AUTO_INCREMENT=8 DEFAULT CHARSET=latin1; + +DROP TABLE IF EXISTS `api_cache`; +CREATE TABLE `api_cache`( + `id` int(11) NOT NULL AUTO_INCREMENT, + `config_id` int(11) NOT NULL, + `last_successfully_retrieved` timestamp DEFAULT CURRENT_TIMESTAMP, + `last_attempted_retrieval` timestamp DEFAULT CURRENT_TIMESTAMP, + `retry_count` int DEFAULT 0, + `endpoint_args` varchar(4000) NOT NULL, -- args used to fill '{}'s in endpoint (e.g., https://api.printful.com/store/$1/$2/not-a-real-endpoint?$3) delimited with a '|' + `content` blob NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (config_id) REFERENCES outgoing_request_cache_config(id) +)AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;