forked from rapid7/hackazon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
600014a
commit 6e4362e
Showing
2 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
use App\DataImport\CategoryProductImporter; | ||
|
||
error_reporting(E_ERROR & ~E_NOTICE); | ||
$root = dirname(__DIR__); | ||
$loader = require $root.'/vendor/autoload.php'; | ||
$loader->add('', $root.'/classes/'); | ||
|
||
if ($path = $_SERVER['argv'][1]) { | ||
$path = getcwd() . DIRECTORY_SEPARATOR . preg_replace('#^[\\\\/]+#', '', $path); | ||
|
||
} else { | ||
$path = __DIR__ . '/../Hackazon'; | ||
} | ||
|
||
echo "Your path is: $path \n"; | ||
|
||
if (!file_exists($path) || !is_dir($path)) { | ||
echo "Invalid directory."; | ||
exit; | ||
} | ||
|
||
|
||
$pixie = new \App\Pixie(); | ||
$pixie->bootstrap($root); | ||
$result = CategoryProductImporter::create($pixie)->import($path); | ||
var_dump($result); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,253 @@ | ||
<?php | ||
/** | ||
* Created by IntelliJ IDEA. | ||
* User: Nikolay Chervyakov | ||
* Date: 27.08.2014 | ||
* Time: 15:40 | ||
*/ | ||
|
||
|
||
namespace App\DataImport; | ||
|
||
|
||
use App\Model\Category; | ||
use App\Pixie; | ||
|
||
/** | ||
* Imports categories and products from directory. | ||
* @package App\DataImport | ||
*/ | ||
class CategoryProductImporter | ||
{ | ||
protected $pixie; | ||
|
||
/** | ||
* @var null|Category | ||
*/ | ||
protected $rootCategory = null; | ||
|
||
protected $result = []; | ||
|
||
protected $lastCategoryLevel; | ||
|
||
public function __construct(Pixie $pixie) | ||
{ | ||
$this->pixie = $pixie; | ||
} | ||
|
||
/** | ||
* Main import function. Clears DB and then imports categories and products from path. | ||
* @param string $path Path to directory with categories and products. | ||
* @param int $categoryLevels Number of category levels. | ||
* @return array Debug and statistics information. | ||
* @throws \Exception If path is incorrect. | ||
*/ | ||
public function import($path, $categoryLevels = 2) | ||
{ | ||
$this->lastCategoryLevel = $categoryLevels - 1; | ||
|
||
if (!file_exists($path) || !is_dir($path) || !is_readable($path)) { | ||
throw new \Exception('Product and category path is not accessible'); | ||
} | ||
|
||
$this->result = []; | ||
$this->clearDatabase(); | ||
$this->importCategory($this->getRoot(), $path); | ||
|
||
return $this->result; | ||
} | ||
|
||
/** | ||
* Imports category in certain level. | ||
* @param Category $parent | ||
* @param $path | ||
* @param int $depth | ||
*/ | ||
public function importCategory(Category $parent, $path, $depth = 0) | ||
{ | ||
$dirIterator = new \DirectoryIterator($path); | ||
/** @var \SplFileInfo $fileInfo */ | ||
foreach ($dirIterator as $fileInfo) { | ||
if (!$fileInfo->isDir() || !$fileInfo->isReadable() || in_array($fileInfo->getFilename(), ['.', '..'])) { | ||
continue; | ||
} | ||
|
||
$category = $this->createCategory([ | ||
'name' => $fileInfo->getFilename(), | ||
'enabled' => 1, | ||
'parent' => $parent->id() | ||
], $parent); | ||
$this->result['category_num']++; | ||
|
||
if ($depth < $this->lastCategoryLevel) { | ||
$this->importCategory($category, $fileInfo->getPathname(), $depth + 1); | ||
} else { | ||
$this->importProducts($category, $fileInfo->getPathname()); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Imports all products from a directory. | ||
* @param Category $category | ||
* @param $path | ||
*/ | ||
public function importProducts(Category $category, $path) | ||
{ | ||
$dirIterator = new \DirectoryIterator($path); | ||
/** @var \SplFileInfo $fileInfo */ | ||
foreach ($dirIterator as $fileInfo) { | ||
if (!$fileInfo->isDir() || !$fileInfo->isReadable() || in_array($fileInfo->getFilename(), ['.', '..'])) { | ||
continue; | ||
} | ||
|
||
$this->importProduct($fileInfo->getFilename(), $category, $fileInfo->getPathname()); | ||
} | ||
} | ||
|
||
/** | ||
* Imports single product from its directory. | ||
* Directory must contain a text file. | ||
* @param $name | ||
* @param Category $category | ||
* @param $path | ||
*/ | ||
public function importProduct($name, Category $category, $path) | ||
{ | ||
$dirIterator = new \DirectoryIterator($path); | ||
$text = ''; | ||
$imageBig = ''; | ||
$imageBigNewPath = ''; | ||
$imageBigOldPath = ''; | ||
$imageSmall = ''; | ||
$imageSmallNewPath = ''; | ||
$imageSmallOldPath = ''; | ||
|
||
$targetDir = realpath(__DIR__.'/../../../web/products_pictures/') . DIRECTORY_SEPARATOR; | ||
|
||
/** @var \SplFileInfo $fileInfo */ | ||
foreach ($dirIterator as $fileInfo) { | ||
if (!$fileInfo->isFile() || !$fileInfo->isReadable() || in_array($fileInfo->getFilename(), ['.', '..'])) { | ||
continue; | ||
} | ||
|
||
if ($fileInfo->getExtension() == 'txt') { | ||
$text = file_get_contents($fileInfo->getPathname()); | ||
} | ||
|
||
$ext = strtolower($fileInfo->getExtension()); | ||
$baseName = strtolower($fileInfo->getFilename()); | ||
|
||
if (in_array($ext, ['jpeg', 'jpg', 'gif', 'png'])) { | ||
if ($this->stringContains($baseName, ['small', 'little', 'tiny'])) { | ||
$imageSmall = $this->generateFilename($name) | ||
. '_small_' . substr(sha1($fileInfo->getPathname()), 0, 6) . '.' . $fileInfo->getExtension(); | ||
$imageSmallOldPath = $fileInfo->getPathname(); | ||
$imageSmallNewPath = $targetDir . $imageSmall; | ||
|
||
} else if ($this->stringContains($baseName, ['big', 'large', 'huge'])) { | ||
$imageBig = $this->generateFilename($name) | ||
. '_big_' . substr(sha1($fileInfo->getPathname()), 0, 6) . '.' . $fileInfo->getExtension(); | ||
$imageBigOldPath = $fileInfo->getPathname(); | ||
$imageBigNewPath = $targetDir . $imageBig; | ||
} | ||
} | ||
} | ||
|
||
if (!$text) { | ||
return; | ||
} | ||
|
||
$data = []; | ||
$blocks = array_chunk(preg_split('/\\{([\\w\\d]+)\\}/', $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY), 3); | ||
foreach ($blocks as $block) { | ||
$data[strtolower(trim($block[0]))] = trim($block[1]); | ||
} | ||
|
||
$product = $this->pixie->orm->get('Product'); | ||
$product->values([ | ||
'name' => $data['name'] ?: $name, | ||
'categoryID' => $category->categoryID, | ||
'description' => $data['description'], | ||
'picture' => $imageSmall, | ||
'big_picture' => $imageBig, | ||
'Price' => preg_replace('/\\$/', '', $data['price']) | ||
]); | ||
|
||
$product->save(); | ||
|
||
$this->copyFile($imageSmallOldPath, $imageSmallNewPath); | ||
$this->copyFile($imageBigOldPath, $imageBigNewPath); | ||
|
||
$this->result['product_num']++; | ||
} | ||
|
||
public static function create(Pixie $pixie) | ||
{ | ||
return new self($pixie); | ||
} | ||
|
||
/** | ||
* Get or create root category. | ||
* @return null|Category | ||
*/ | ||
protected function getRoot() | ||
{ | ||
if (!$this->rootCategory) { | ||
$this->rootCategory = $this->createCategory([ | ||
'name' => 'ROOT', | ||
'enabled' => 1 | ||
]); | ||
$this->rootCategory->refresh(); | ||
$this->rootCategory->parent = 0; | ||
$this->rootCategory->save(); | ||
} | ||
|
||
return $this->rootCategory; | ||
} | ||
|
||
protected function createCategory(array $values = [], Category $parent = null) | ||
{ | ||
/** @var Category $category */ | ||
$category = $this->pixie->orm->get('Category'); | ||
$category->values($values); | ||
$category->nested->prepare_append($parent); | ||
$category->save(); | ||
return $category; | ||
} | ||
|
||
protected function clearDatabase() | ||
{ | ||
$this->pixie->db->query('delete')->table('tbl_orders')->execute(); | ||
$this->pixie->db->query('delete')->table('tbl_products')->execute(); | ||
$this->pixie->db->query('delete')->table('tbl_categories')->execute(); | ||
} | ||
|
||
protected function stringContains($haystack, array $needles) | ||
{ | ||
foreach ($needles as $needle) { | ||
if (strpos($haystack, $needle) !== false) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public function generateFilename($fileName, $length = 64) | ||
{ | ||
$name = preg_replace('/[^\w\d_]/', '_', $fileName); | ||
$name = preg_replace('/_+/', '_', $name); | ||
return substr(iconv("UTF-8", "ISO-8859-9//TRANSLIT", $name), 0, $length); | ||
} | ||
|
||
public function copyFile($from, $to) | ||
{ | ||
if ($from && $to) { | ||
if (file_exists($to) && is_file($to)) { | ||
unlink($to); | ||
} | ||
copy($from, $to); | ||
} | ||
} | ||
} |