From d8f6fee0b979e29ba04ec78982b251e27501f47e Mon Sep 17 00:00:00 2001 From: Dmitry Mamontov Date: Mon, 16 Nov 2015 09:45:35 -0500 Subject: [PATCH 1/3] add debug mode --- retailcrm/app.php | 2 +- retailcrm/src/Components/Command.php | 15 ++++++++- retailcrm/src/Helpers/DebugHelper.php | 48 +++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 retailcrm/src/Helpers/DebugHelper.php diff --git a/retailcrm/app.php b/retailcrm/app.php index 15bd6ee..7583def 100644 --- a/retailcrm/app.php +++ b/retailcrm/app.php @@ -10,7 +10,7 @@ if ( require_once 'bootstrap.php'; -$options = getopt('luce:m:p:r:h:'); +$options = getopt('dluce:m:p:r:h:'); if (isset($options['e'])) { $command = new Command($options); diff --git a/retailcrm/src/Components/Command.php b/retailcrm/src/Components/Command.php index b4d9539..c4b28aa 100644 --- a/retailcrm/src/Components/Command.php +++ b/retailcrm/src/Components/Command.php @@ -10,6 +10,7 @@ class Command private $limit; private $update; private $container; + private $debug; public function __construct($arguments) { @@ -22,6 +23,7 @@ class Command $this->limit = isset($arguments['l']); $this->update = isset($arguments['u']); $this->custom = isset($arguments['c']); + $this->debug = isset($arguments['d']); $this->container = Container::getInstance(); @@ -40,9 +42,20 @@ class Command return; } + $debug = new DebugHelper(); + if ($this->debug) { + $debug->write(sprintf('Start %s', ucfirst($this->run))); + } + $command = 'run' . ucfirst($this->run); - return $this->$command(); + $result = $this->$command(); + + if ($this->debug) { + $debug->write(sprintf('End %s', ucfirst($this->run))); + } + + return $result; } public function runDump() diff --git a/retailcrm/src/Helpers/DebugHelper.php b/retailcrm/src/Helpers/DebugHelper.php new file mode 100644 index 0000000..8c91eef --- /dev/null +++ b/retailcrm/src/Helpers/DebugHelper.php @@ -0,0 +1,48 @@ +baseMemoryUsage = memory_get_usage(true); + + $proc = getrusage(); + $this->tusage = microtime(true); + $this->rusage = $proc['ru_utime.tv_sec'] * 1e6 + $proc['ru_utime.tv_usec']; + } + + private function formatSize($size) + { + $postfix = array('b', 'Kb', 'Mb', 'Gb', 'Tb'); + $position = 0; + while ($size >= 1024 && $position < 4) { + $size /= 1024; + $position++; + } + + return sprintf('%s %s', round($size, 2), $postfix[$position]); + } + + public function getMemoryUsage() + { + return $this->formatSize(memory_get_usage(true) - $this->baseMemoryUsage); + } + + public function getCpuUsage() + { + $proc = getrusage(); + $proc["ru_utime.tv_usec"] = ($proc["ru_utime.tv_sec"] * 1e6 + $proc["ru_utime.tv_usec"]) - $this->rusage; + $time = (microtime(true) - $this->tusage) * 1000000; + + return $time > 0 ? sprintf("%01.2f", ($proc["ru_utime.tv_usec"] / $time) * 100) : '0.00'; + } + + public function write($string) + { + echo sprintf("%s\t%s\t%s%s", $string, $this->getCpuUsage(), $this->getMemoryUsage(), PHP_EOL); + } +} \ No newline at end of file From c672c93554bf927a7779ac6e4f2b089b191186f0 Mon Sep 17 00:00:00 2001 From: Dmitry Mamontov Date: Mon, 16 Nov 2015 10:02:44 -0500 Subject: [PATCH 2/3] fix concat --- retailcrm/src/Components/Command.php | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/retailcrm/src/Components/Command.php b/retailcrm/src/Components/Command.php index c4b28aa..6f77e03 100644 --- a/retailcrm/src/Components/Command.php +++ b/retailcrm/src/Components/Command.php @@ -23,7 +23,7 @@ class Command $this->limit = isset($arguments['l']); $this->update = isset($arguments['u']); $this->custom = isset($arguments['c']); - $this->debug = isset($arguments['d']); + $this->debug = isset($arguments['d']); $this->container = Container::getInstance(); @@ -47,15 +47,12 @@ class Command $debug->write(sprintf('Start %s', ucfirst($this->run))); } - $command = 'run' . ucfirst($this->run); - - $result = $this->$command(); + $command = sprintf('run%s', ucfirst($this->run)); + $this->$command(); if ($this->debug) { $debug->write(sprintf('End %s', ucfirst($this->run))); } - - return $result; } public function runDump() @@ -65,9 +62,12 @@ class Command $dbName = $this->container->settings['db']['dbname']; $dbHost = $this->container->settings['db']['host']; - $dumpfile = $this->container->saveDir . "dbdump.sql.gz"; + $dumpfile = sprintf('%sdbdump.sql.gz', $this->container->saveDir); - $cmd = "mysqldump -u $dbUser --password=$dbPass --host=$dbHost $dbName | gzip --best > $dumpfile"; + $cmd = sprintf( + 'mysqldump -u %s --password=%s --host=%s %s | gzip --best > %s', + $dbUser, $dbPass, $dbHost, $dbName, $dumpfile + ); passthru($cmd); } @@ -267,12 +267,10 @@ class Command $handler = $rule->getHandler('AmoHandler'); $data = $handler->prepare($amo); - if (!empty($data)) { - if (!empty($data['customers'])) { - $this->requestHelper->uploadCustomers($data['customers']); - if (!empty($data['orders'])) { - $this->requestHelper->uploadOrders($data['orders'], true); - } + if (!empty($data) && !empty($data['customers'])) { + $this->requestHelper->uploadCustomers($data['customers']); + if (!empty($data['orders'])) { + $this->requestHelper->uploadOrders($data['orders'], true); } } } From 9a2bbce480a9ef9fc3d9ea38d18c1ffcb0c0aa97 Mon Sep 17 00:00:00 2001 From: Dmitry Mamontov Date: Mon, 16 Nov 2015 10:03:22 -0500 Subject: [PATCH 3/3] refactoring icml && fix memory usage --- retailcrm/src/Helpers/IcmlHelper.php | 147 ++++++++++++++++----------- 1 file changed, 88 insertions(+), 59 deletions(-) diff --git a/retailcrm/src/Helpers/IcmlHelper.php b/retailcrm/src/Helpers/IcmlHelper.php index dfe3432..1fc94b0 100644 --- a/retailcrm/src/Helpers/IcmlHelper.php +++ b/retailcrm/src/Helpers/IcmlHelper.php @@ -4,6 +4,7 @@ class IcmlHelper { protected $shop; protected $file; + protected $tmpFile; protected $properties = array( 'name', @@ -17,48 +18,93 @@ class IcmlHelper 'productActivity' ); - protected $document; + protected $xml; protected $categories; protected $offers; + protected $chunk = 500; + public function __construct($shop, $file) { $this->shop = $shop; $this->file = $file; + $this->tmpFile = sprintf('%s.tmp', $file); } public function generate($categories, $offers) { - $string = ' - - - '.$this->shop.' - - - - - '; + if (!file_exists($this->tmpFile)) { + $this->writeHead(); + } - $xml = new SimpleXMLElement( - $string, - LIBXML_NOENT |LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE + if (!empty($categories)) { + $this->writeCategories($categories); + unset($categories); + } + + if (!empty($offers)) { + $this->writeOffers($offers); + unset($offers); + } + + $dom = dom_import_simplexml(simplexml_load_file($this->tmpFile))->ownerDocument; + $dom->formatOutput = true; + $formatted = $dom->saveXML(); + + unset($dom, $this->xml); + + file_put_contents($this->tmpFile, $formatted); + rename($this->tmpFile, $this->file); + } + + private function loadXml() + { + return new SimpleXMLElement( + $this->tmpFile, + LIBXML_NOENT | LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_PARSEHUGE, + true + ); + } + + private function writeHead() + { + $string = sprintf( + '%s', + date('Y-m-d H:i:s'), + $this->shop ); - $this->document = new DOMDocument(); - $this->document->preserveWhiteSpace = false; - $this->document->formatOutput = true; - $this->document->loadXML($xml->asXML()); + file_put_contents($this->tmpFile, $string, LOCK_EX); + } - $this->categories = $this->document - ->getElementsByTagName('categories')->item(0); - $this->offers = $this->document - ->getElementsByTagName('offers')->item(0); + private function writeCategories($categories) + { + $chunkCategories = array_chunk($categories, $this->chunk); + foreach ($chunkCategories as $categories) { + $this->xml = $this->loadXml(); - $this->addCategories($categories); - $this->addOffers($offers); + $this->categories = $this->xml->shop->categories; + $this->addCategories($categories); - $this->document->saveXML(); - $this->document->save($this->file); + $this->xml->asXML($this->tmpFile); + } + + unset($this->categories); + } + + private function writeOffers($offers) + { + $chunkOffers = array_chunk($offers, $this->chunk); + foreach ($chunkOffers as $offers) { + $this->xml = $this->loadXml(); + + $this->offers = $this->xml->shop->offers; + $this->addOffers($offers); + + $this->xml->asXML($this->tmpFile); + } + + unset($this->offers); } private function addCategories($categories) @@ -70,16 +116,12 @@ class IcmlHelper continue; } - $e = $this->categories->appendChild( - $this->document->createElement( - 'category', $category['name'] - ) - ); + $e = $this->categories->addChild('category', $category['name']); - $e->setAttribute('id', $category['id']); + $e->addAttribute('id', $category['id']); if (array_key_exists('parentId', $category) && $category['parentId'] > 0) { - $e->setAttribute('parentId', $category['parentId']); + $e->addAttribute('parentId', $category['parentId']); } } } @@ -88,39 +130,33 @@ class IcmlHelper { $offers = DataHelper::filterRecursive($offers); - foreach ($offers as $offer) { + foreach ($offers as $key => $offer) { if (!array_key_exists('id', $offer)) { continue; } - $e = $this->offers->appendChild( - $this->document->createElement('offer') - ); + $e = $this->offers->addChild('offer'); - $e->setAttribute('id', $offer['id']); + $e->addAttribute('id', $offer['id']); if (!array_key_exists('productId', $offer) || empty($offer['productId'])) { $offer['productId'] = $offer['id']; } - $e->setAttribute('productId', $offer['productId']); + $e->addAttribute('productId', $offer['productId']); if (!empty($offer['quantity'])) { - $e->setAttribute('quantity', (int) $offer['quantity']); + $e->addAttribute('quantity', (int) $offer['quantity']); } else { - $e->setAttribute('quantity', 0); + $e->addAttribute('quantity', 0); } if (is_array($offer['categoryId'])) { foreach ($offer['categoryId'] as $categoryId) { - $e->appendChild( - $this->document->createElement('categoryId', $categoryId) - ); + $e->addChild('categoryId', $categoryId); } } else { - $e->appendChild( - $this->document->createElement('categoryId', $offer['categoryId']) - ); + $e->addChild('categoryId', $offer['categoryId']); } if (!array_key_exists('name', $offer) || empty($offer['name'])) { @@ -137,16 +173,14 @@ class IcmlHelper if (array_key_exists('params', $offer) && !empty($offer['params'])) { array_walk($offer['params'], array($this, 'setOffersParams'), $e); } + + unset($offers[$key]); } } private function setOffersProperties($value, $key, &$e) { if (in_array($key, $this->properties) && $key != 'params') { - $e->appendChild( - $this->document->createElement($key) - )->appendChild( - $this->document->createTextNode($value) - ); + $e->addChild($key, htmlspecialchars($value)); } } @@ -159,14 +193,9 @@ class IcmlHelper !empty($value['name']) && !empty($value['value']) ) { - $param = $this->document->createElement('param'); - $param->setAttribute('code', $value['code']); - $param->setAttribute('name', $value['name']); - $param->appendChild( - $this->document->createTextNode($value['value']) - ); - - $e->appendChild($param); + $param = $e->addChild('param', htmlspecialchars($value['value'])); + $param->addAttribute('code', $value['code']); + $param->addAttribute('name', htmlspecialchars($value['name'])); } } }