first commit
This commit is contained in:
549
admin/cleaning.php
Normal file
549
admin/cleaning.php
Normal file
@@ -0,0 +1,549 @@
|
||||
<?php
|
||||
|
||||
use KupShop\AdminBundle\Util\Script\ScriptLocator;
|
||||
use KupShop\CatalogBundle\Search\FulltextInterface;
|
||||
use KupShop\KupShopBundle\Config;
|
||||
use KupShop\KupShopBundle\Context\ContextManager;
|
||||
use KupShop\KupShopBundle\Context\LanguageContext;
|
||||
use KupShop\KupShopBundle\Event\CronEvent;
|
||||
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
||||
|
||||
$main_class = 'Cleaning';
|
||||
|
||||
class Cleaning extends Window
|
||||
{
|
||||
public $success = 0;
|
||||
public $failed = 0;
|
||||
|
||||
// Cache
|
||||
public function handleCacheImages()
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
foreach (glob($cfg['Path']['data'].'tmp/[0-9]*/*/*.*') as $file) {
|
||||
if (@unlink($file)) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
|
||||
$path = realpath($cfg['Path']['data'].'tmp/');
|
||||
|
||||
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
|
||||
$folders = [];
|
||||
foreach ($objects as $path => $object) {
|
||||
$folder_name = substr($path, strrpos($path, '/') + 1, strlen($path));
|
||||
if (ctype_digit($folder_name) && strlen($folder_name) == 1) {
|
||||
$folders[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
$folders = array_reverse($folders);
|
||||
|
||||
foreach ($folders as $folder) {
|
||||
@rmdir($folder);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleImageVersionUpgrade()
|
||||
{
|
||||
$dbcfg = Settings::getDefault();
|
||||
|
||||
$lastImageVersion = $dbcfg->loadValue('image_version');
|
||||
|
||||
$dbcfg->saveValue('image_version', $lastImageVersion ? $lastImageVersion + 1 : 2);
|
||||
$dbcfg->clearCache();
|
||||
|
||||
$this->success++;
|
||||
}
|
||||
|
||||
public function handleCacheSections()
|
||||
{
|
||||
clearCache('sections', true);
|
||||
$this->success++;
|
||||
}
|
||||
|
||||
public function handleCacheRuntime()
|
||||
{
|
||||
clearCache('', true);
|
||||
$this->success++;
|
||||
}
|
||||
|
||||
public function handleCacheTemplates()
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
foreach (glob($cfg['Path']['data'].'tmp/templates/*') as $file) {
|
||||
if (@unlink($file)) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleCacheFeeds()
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
foreach (glob($cfg['Path']['data'].'tmp/feed_*_*') as $file) {
|
||||
if (@unlink($file)) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleCacheSitemap()
|
||||
{
|
||||
$cfg = Config::get();
|
||||
|
||||
foreach (glob($cfg['Path']['data'].'tmp/sitemap*') as $file) {
|
||||
if (@unlink($file)) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleCacheStatic()
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
foreach (glob($cfg['Path']['data'].'tmp/cache/*') as $file) {
|
||||
if (@unlink($file)) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->handleCacheRuntime();
|
||||
}
|
||||
|
||||
// Photos
|
||||
public function getImagesUnused()
|
||||
{
|
||||
$SQL = sqlQuery('SELECT id
|
||||
FROM photos p
|
||||
LEFT JOIN photos_products_relation ppr ON p.id = ppr.id_photo
|
||||
LEFT JOIN photos_articles_relation ppa ON p.id = ppa.id_photo
|
||||
LEFT JOIN photos_menu_relation par ON p.id = par.id_photo
|
||||
LEFT JOIN photos_blocks_relation blo ON p.id = blo.id_photo
|
||||
LEFT JOIN photos_blocks_new_relation bln ON p.id = bln.id_photo
|
||||
LEFT JOIN photos_sections_relation psr ON p.id = psr.id_photo
|
||||
WHERE ppr.id_product IS NULL AND ppa.id_art IS NULL AND par.id_menu IS NULL
|
||||
AND blo.id_block IS NULL AND bln.id_block IS NULL AND psr.id_section IS NULL');
|
||||
$files = sqlFetchAll($SQL);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public function handleCacheImagesType()
|
||||
{
|
||||
if (($type = getVal('type')) !== null) {
|
||||
$this->clearImageTypeCache($type);
|
||||
}
|
||||
}
|
||||
|
||||
// clear cache only of defined photo type
|
||||
public function clearImageTypeCache($type)
|
||||
{
|
||||
$cfg = Config::get();
|
||||
|
||||
if (!isset($cfg['Photo']['id_to_type'][$type])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (glob($cfg['Path']['data'].'tmp/'.$type.'/*/*.*') as $file) {
|
||||
if (@unlink($file)) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
|
||||
$path = realpath($cfg['Path']['data'].'tmp/'.$type.'/');
|
||||
|
||||
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
|
||||
$folders = [];
|
||||
foreach ($objects as $path => $object) {
|
||||
$folder_name = substr($path, strrpos($path, '/') + 1, strlen($path));
|
||||
if (ctype_digit($folder_name) && strlen($folder_name) == 1) {
|
||||
$folders[] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
$folders = array_reverse($folders);
|
||||
|
||||
foreach ($folders as $folder) {
|
||||
@rmdir($folder);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleImagesUnused()
|
||||
{
|
||||
$files = $this->getImagesUnused();
|
||||
|
||||
$img = new Photos('product');
|
||||
|
||||
foreach ($files as $file) {
|
||||
if ($img->erasePhoto($file['id'])) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getImagesFiles()
|
||||
{
|
||||
global $cfg;
|
||||
$dir = $cfg['Path']['photos'];
|
||||
|
||||
$dirIterator = new RecursiveDirectoryIterator($dir, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_PATHNAME | FilesystemIterator::SKIP_DOTS);
|
||||
$dirIterator = new RecursiveCallbackFilterIterator($dirIterator, function ($current, $key, $iterator) use ($dir) {
|
||||
// Avoid sliders folder
|
||||
if ($key === $dir.'sliders') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
$files = iterator_to_array(new RecursiveIteratorIterator($dirIterator));
|
||||
|
||||
$db_images = sqlQuery('SELECT CONCAT(:dir, source, image_2) AS path FROM `photos`', ['dir' => $dir]);
|
||||
$db_images = sqlFetchAll($db_images, ['path' => 'path']);
|
||||
|
||||
$files = array_filter($files, function ($file) use ($db_images) {
|
||||
return !isset($db_images[$file]);
|
||||
});
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public function handleImagesFiles()
|
||||
{
|
||||
$files = $this->getImagesFiles();
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (@unlink($file)) {
|
||||
$this->success++;
|
||||
} else {
|
||||
$this->failed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleImagesCorrupted()
|
||||
{
|
||||
global $cfg;
|
||||
$db_images = sqlQuery('SELECT CONCAT(:dir, source, image_2) AS path, id FROM `photos`', ['dir' => $cfg['Path']['photos']]);
|
||||
|
||||
$corrupted_id = [];
|
||||
foreach ($db_images as $file) {
|
||||
if (!file_exists($file['path']) || filesize($file['path']) <= 0/* && wpj_open_image($source) */) {
|
||||
$corrupted_id[] = $file['id'];
|
||||
$this->success++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($corrupted_id)) {
|
||||
sqlQuery('DELETE FROM `photos` WHERE id IN ('.join(', ', $corrupted_id).')');
|
||||
}
|
||||
}
|
||||
|
||||
public function getImagesMissingMain()
|
||||
{
|
||||
return sqlFetchAll(sqlQuery('SELECT id_product FROM photos_products_relation GROUP BY id_product HAVING MAX(show_in_lead)=\'N\''), 'id_product');
|
||||
}
|
||||
|
||||
public function handleImagesMissingMain()
|
||||
{
|
||||
$IDs = $this->getImagesMissingMain();
|
||||
|
||||
foreach ($IDs as $id_product => $_) {
|
||||
Photos::checkLeadPhoto('photos_products_relation', 'id_product', $id_product);
|
||||
}
|
||||
}
|
||||
|
||||
// Products
|
||||
public function handleProductsAll()
|
||||
{
|
||||
$this->success = $this->deleteSQL('products', ['1' => '1']);
|
||||
}
|
||||
|
||||
public function handleProductsAnnotation()
|
||||
{
|
||||
foreach (sqlQuery('SELECT id, short_descr FROM products') as $product) {
|
||||
$product['short_descr'] = trim(html_entity_decode(strip_tags($product['short_descr'])));
|
||||
|
||||
$this->success += $this->updateSQL('products', $product, ['id' => $product['id']], ['id']);
|
||||
}
|
||||
if (findModule(\Modules::TRANSLATIONS)) {
|
||||
foreach (sqlQuery('SELECT id, short_descr FROM products_translations') as $product) {
|
||||
$product['short_descr'] = trim(html_entity_decode(strip_tags($product['short_descr'])));
|
||||
|
||||
$this->success += $this->updateSQL('products_translations', $product, ['id' => $product['id']], ['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handleProductsDescriptions()
|
||||
{
|
||||
foreach (sqlQuery('SELECT id, short_descr, long_descr FROM products') as $product) {
|
||||
$product['short_descr'] = trim(html_entity_decode(strip_tags($product['short_descr'])));
|
||||
$product['long_descr'] = trim(html_entity_decode(strip_tags($product['long_descr'])));
|
||||
|
||||
$this->success += $this->updateSQL('products', $product, ['id' => $product['id']], ['id']);
|
||||
}
|
||||
}
|
||||
|
||||
// Parameters
|
||||
public function handleParameters()
|
||||
{
|
||||
$this->success = $this->deleteSQL('parameters', ['1' => '1']);
|
||||
}
|
||||
|
||||
public function handleParametersValues()
|
||||
{
|
||||
$this->success = $this->deleteSQL('parameters_list', ['1' => '1']);
|
||||
}
|
||||
|
||||
// Sections
|
||||
public function handleSections()
|
||||
{
|
||||
$this->success = $this->deleteSQL('sections', ['(id = 0)' => 'FALSE']);
|
||||
clearCache('sections', true);
|
||||
}
|
||||
|
||||
public function handleSectionsEmpty()
|
||||
{
|
||||
$SQL = sqlQuery('DELETE s FROM sections s
|
||||
LEFT JOIN products_in_sections ps ON ps.id_section = s.id
|
||||
LEFT JOIN sections_relation sr ON sr.id_topsection = s.id
|
||||
WHERE ps.id_product IS NULL AND sr.id_section IS NULL
|
||||
AND s.id <> 0 ');
|
||||
$this->success = sqlNumRows($SQL);
|
||||
|
||||
MenuSectionTree::invalidateCache();
|
||||
clearCache('sections', true);
|
||||
}
|
||||
|
||||
// Producers
|
||||
public function handleProducers()
|
||||
{
|
||||
$this->success = $this->deleteSQL('producers', ['1' => '1']);
|
||||
}
|
||||
|
||||
// Orders
|
||||
public function handleOrders()
|
||||
{
|
||||
$this->success = $this->deleteSQL('orders', ['1' => '1']);
|
||||
}
|
||||
|
||||
// Articles
|
||||
public function handleArticles()
|
||||
{
|
||||
$this->success = $this->deleteSQL('articles', ['1' => '1']);
|
||||
}
|
||||
|
||||
// Users
|
||||
public function handleUsers()
|
||||
{
|
||||
$this->success = $this->deleteSQL('users', ['1' => '1']);
|
||||
}
|
||||
|
||||
// Variations
|
||||
public function handleVariationsDuplicates()
|
||||
{
|
||||
$duplicates = sqlQuery('SELECT t.id_product, GROUP_CONCAT(t.id ORDER BY t.id SEPARATOR \',\') id_variations
|
||||
FROM (
|
||||
SELECT pv.id, pv.id_product, GROUP_CONCAT(pvc.id_value ORDER BY pvc.id_value SEPARATOR \'-\') vals
|
||||
FROM products_variations pv
|
||||
JOIN products_variations_combination pvc ON pv.id = pvc.id_variation
|
||||
GROUP BY pv.id
|
||||
) AS t
|
||||
GROUP BY t.id_product, t.vals
|
||||
HAVING COUNT(*) > 1');
|
||||
|
||||
foreach ($duplicates as $duplicate) {
|
||||
$variations = explode(',', $duplicate['id_variations']);
|
||||
array_shift($variations);
|
||||
$this->success += sqlQueryBuilder()->delete('products_variations')->where(\Query\Operator::inIntArray($variations, 'id'))->execute();
|
||||
}
|
||||
}
|
||||
|
||||
public function handleRegenerateVariationsTitles()
|
||||
{
|
||||
Variations::updateTitle();
|
||||
}
|
||||
|
||||
public function handleFulltextUpdate()
|
||||
{
|
||||
$fulltext = ServiceContainer::getService(FulltextInterface::class);
|
||||
$contextManager = ServiceContainer::getService(ContextManager::class);
|
||||
|
||||
$languages = $fulltext->getFulltextLanguages();
|
||||
if ($lang = getVal('fulltext_language')) {
|
||||
$languages = [$lang => $languages[$lang]];
|
||||
}
|
||||
|
||||
foreach ($languages as $language => $_) {
|
||||
$contextManager->activateContexts([LanguageContext::class => $language], function () use ($fulltext) {
|
||||
$fulltext->updateIndex(getVal('fulltext_index'));
|
||||
$this->success++;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Reviews
|
||||
public function handleReviewsImport()
|
||||
{
|
||||
$reviews = ServiceContainer::getService(\KupShop\CatalogBundle\Util\ReviewsUtil::class);
|
||||
$this->success = $reviews->importReviews();
|
||||
if ($reviews->getError()) {
|
||||
$this->returnError($reviews->getError());
|
||||
}
|
||||
}
|
||||
|
||||
public function handleReviewsAutoConfirm()
|
||||
{
|
||||
$reviews = ServiceContainer::getService(\KupShop\CatalogBundle\Util\ReviewsUtil::class);
|
||||
$this->success = $reviews->autoConfirm();
|
||||
}
|
||||
|
||||
public function handleCronFrequent()
|
||||
{
|
||||
$this->handleCron('FREQUENT');
|
||||
}
|
||||
|
||||
public function handleCronNormal()
|
||||
{
|
||||
$this->handleCron('NORMAL');
|
||||
}
|
||||
|
||||
public function handleCronExpensive()
|
||||
{
|
||||
$this->handleCron('EXPENSIVE');
|
||||
}
|
||||
|
||||
protected function handleCron(string $type)
|
||||
{
|
||||
/** @var \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher */
|
||||
$dispatcher = ServiceContainer::getService('event_dispatcher');
|
||||
$event = new CronEvent($type);
|
||||
$dispatcher->dispatch($event, constant('KupShop\KupShopBundle\Event\CronEvent::RUN_'.$type));
|
||||
}
|
||||
|
||||
public function handleRunScript()
|
||||
{
|
||||
$script = getVal('script');
|
||||
if ($script) {
|
||||
ServiceContainer::getService(ScriptLocator::class)->runScript($script, getVal('script_parameters'));
|
||||
exit("\n============ DONE ==============");
|
||||
}
|
||||
}
|
||||
|
||||
public function getCounts()
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
$counts = [];
|
||||
|
||||
// Cache
|
||||
$counts['cacheImages'] = ['count' => count(glob($cfg['Path']['data'].'tmp/*/*/*.*'))];
|
||||
$counts['cacheSections'] = ['count' => 1];
|
||||
$counts['cacheTemplates'] = ['count' => count(glob($cfg['Path']['data'].'tmp/templates/*'))];
|
||||
$counts['cacheStatic'] = ['count' => count(glob($cfg['Path']['data'].'tmp/cache/*'))];
|
||||
|
||||
// Photos
|
||||
$files = $this->getImagesUnused();
|
||||
$counts['imagesUnused'] = ['count' => count($files), 'links' => array_map(function ($file) {
|
||||
return "javascript:nw('photos', {$file['id']})";
|
||||
}, array_slice($files, 0, 10, true) + array_slice($files, -10, 10, true))];
|
||||
|
||||
$files = $this->getImagesFiles();
|
||||
$counts['imagesFiles'] = ['count' => count($files), 'links' => array_slice($files, 0, 10, true) + array_slice($files, -10, 10, true)];
|
||||
|
||||
$images = $this->getImagesMissingMain();
|
||||
$counts['imagesMissingMain'] = ['count' => count($images)];
|
||||
|
||||
return $counts;
|
||||
}
|
||||
|
||||
public function get_vars()
|
||||
{
|
||||
$vars = parent::get_vars();
|
||||
|
||||
if (getVal('calculate')) {
|
||||
$vars['counts'] = $this->getCounts();
|
||||
}
|
||||
|
||||
$vars['scripts'] = ServiceContainer::getService(ScriptLocator::class)->getScripts();
|
||||
|
||||
$indexes = ServiceContainer::getService(FulltextInterface::class)->getIndexTypes();
|
||||
$vars['fulltext']['indexes'] = array_combine($indexes, $indexes);
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
ini_set('max_execution_time', 600);
|
||||
ini_set('memory_limit', '512M');
|
||||
|
||||
parent::handle();
|
||||
|
||||
if (getVal('acn') != 'edit' && getVal('acn') != 'add') {
|
||||
$this->returnOK("Upraveno {$this->success} položek. Selhalo {$this->failed} položek");
|
||||
}
|
||||
}
|
||||
|
||||
// Do not try to handle exceptions - hides some DB errors
|
||||
public function handleException($e)
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
|
||||
public function hasRights($name = null)
|
||||
{
|
||||
switch ($name) {
|
||||
case Window::RIGHT_SAVE:
|
||||
case Window::RIGHT_DELETE:
|
||||
case Window::RIGHT_DUPLICATE:
|
||||
return false;
|
||||
default:
|
||||
return parent::hasRights($name);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleDiscounts()
|
||||
{
|
||||
$SQL = sqlQuery('DELETE FROM discounts
|
||||
WHERE condition_type != \'generate_coupon\'');
|
||||
$this->success = sqlNumRows($SQL);
|
||||
}
|
||||
|
||||
public function handleAllDiscounts()
|
||||
{
|
||||
$this->success = $this->deleteSQL('discounts', ['1' => '1']);
|
||||
}
|
||||
|
||||
// Variation labels
|
||||
public function handleLabels()
|
||||
{
|
||||
$this->success = $this->deleteSQL('products_variations_choices_labels', ['1' => '1']);
|
||||
}
|
||||
|
||||
public function handleLabelsEmpty()
|
||||
{
|
||||
$SQL = sqlQuery('DELETE vl FROM products_variations_choices_labels vl
|
||||
LEFT JOIN products_variations_combination pvc ON pvc.id_label = vl.id
|
||||
WHERE pvc.id_variation IS NULL');
|
||||
$this->success = sqlNumRows($SQL);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user