Skip to content

Instantly share code, notes, and snippets.

@renskiy
Created August 22, 2014 05:34
Show Gist options
  • Save renskiy/b4cd875acafa112653e4 to your computer and use it in GitHub Desktop.
Save renskiy/b4cd875acafa112653e4 to your computer and use it in GitHub Desktop.
for TimeWeb
<?php
/**
* Created by PhpStorm.
* User: renskiy
* Date: 15.02.14
* Time: 19:41
*/
class YmlUpdater {
/**
* Where to take updates
* @var string
*/
protected static $UPDATES_FILENAME = 'updates.yml';
/**
* Temporary file for currently processing updates
* @var string
*/
protected static $TEMP_UPDATES_FILENAME = '_updates.yml';
/**
* Where to place final result
* @var string
*/
protected static $PRODUCTS_FILENAME = 'products.yml';
/**
* Temporary file for products
* @var string
*/
protected static $TEMP_PRODUCTS_FILENAME = '_products.yml';
/**
* Template used for $PRODUCTS_FILENAME generation
* @var string
*/
protected static $PRODUCTS_TEMPLATE = 'products.tpl.yml';
/**
* Dynamic array used for storing currently processing product updates
* @var array
*/
protected $updated_products = [];
/**
* Entry point
*/
public function run() {
$this->load_updated_products();
$this->generate_products_file();
$this->remove_temp_files();
}
/**
* Build products file based on predefined template
*/
protected function generate_products_file() {
$template = file_get_contents(self::$PRODUCTS_TEMPLATE);
if ($template === false) {
die(sprintf("Template %s was not found", self::$PRODUCTS_TEMPLATE));
}
list($prefix, $suffix) = explode('{{OFFERS}}', $template, 2);
$new_products = fopen(self::$TEMP_PRODUCTS_FILENAME, 'w');
fwrite($new_products, "$prefix\n");
$this->add_updated_products($new_products);
$this->add_unchanged_products($new_products);
fwrite($new_products, $suffix);
fclose($new_products);
}
/**
* Adds updated products to the given file
* @param resource $new_products
*/
protected function add_updated_products($new_products) {
foreach ($this->updated_products as $product) {
fwrite($new_products, $product);
}
}
/**
* Adds to the given file those products that are not changed
* since last update check
* @param resource $new_products
*/
protected function add_unchanged_products($new_products) {
if (! file_exists(self::$PRODUCTS_FILENAME)) {
return;
}
$old_products = fopen(self::$PRODUCTS_FILENAME, 'r');
while (($product = fgets($old_products)) !== false) {
if ($product_id = self::get_product_id($product)) {
if (! array_key_exists($product_id, $this->updated_products)) {
fwrite($new_products, $product);
}
}
}
fclose($old_products);
}
/**
* Removes all temporary files
*/
protected function remove_temp_files() {
rename(self::$TEMP_PRODUCTS_FILENAME, self::$PRODUCTS_FILENAME);
unlink(self::$TEMP_UPDATES_FILENAME);
}
/**
* Fills $this->updated_products with latest product updates
*/
protected function load_updated_products() {
$updates = $this->get_updates_file();
while (($product = fgets($updates)) !== false) {
if ($product_id = self::get_product_id($product)) {
$this->updated_products[$product_id] = $product;
}
}
fclose($updates);
}
/**
* Tries to get product_id from the given product string in YML format
* @param string $product
* @return string|false
*/
protected static function get_product_id($product) {
if (preg_match('/^\\s*<offer[^>]*\\sid="(\\d+)"/', $product, $match)) {
return $match[1];
}
return false;
}
/**
* File object with product updates
* @return resource
*/
protected static function get_updates_file() {
if (! file_exists(self::$TEMP_UPDATES_FILENAME)) {
if (! file_exists(self::$UPDATES_FILENAME)) {
die("Update file was not found");
}
rename(self::$UPDATES_FILENAME, self::$TEMP_UPDATES_FILENAME);
}
return fopen(self::$TEMP_UPDATES_FILENAME, 'r');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment