Обновление guid при переносе WordPress с домен на домен
UPDATE wp_posts SET guid = REPLACE(guid,"dev.site.com","www.site.com"); UPDATE wp_posts SET post_content = REPLACE(post_content,"dev.site.com","www.site.com"); UPDATE wp_options SET option_value = REPLACE(option_value,"dev.site.com","www.site.com"); UPDATE wp_links SET link_url = REPLACE(link_url,"dev.site.com","www.site.com"); UPDATE wp_postmeta SET meta_value = REPLACE(meta_value,"dev.site.com","www.site.com");
Отложенное выполнение… меню в Битрикс
Ну это же чудесно. Великолепное нововведение. Битрикс поддерживает отложенное выполнение, исполнение, формирование меню. И как никогда вовремя.
Все очень просто: делаем меню, например, left. Подключаем его в нужное место и выставляем DELAY=Y. Дальше в любом месте любого компонента:
<?$GLOBALS['BX_MENU_CUSTOM']->AddItem('left', array('TEXT' => 'Текст ссылки', 'LINK' => 'ссылка'));?>
Что может быть проще и понятней)
Немного о недокументированной функции CIBlockFormatProperties::GetDisplayValue
Итак, в Битрикс существует недокументированная (вернее плохо документированная) функция CIBlockFormatPropertiesCustom::GetDisplayValue. Что она делает? Она добавляет к массиву, например, в news.detail пару пунктов, в которых содержатся отформатированные значения свойств текущего элемента.
Вот тут человек радостно рассказывает, как круто, что она есть. Однако мне вот тут стало недостаточно функционала. Что мне лично странно: почему у функции форматирования чего бы то ни было в таком фреймворке как Битрикс нет возможности передавать шаблон вывода входящим параметром. Объяснение тут в архитектуре: формат напрямую связан с типом свойства. Например, тип данных "Привязка к элементам" - обозначается буквой E, для это буковки указано в switch, что надо вернуть массив со ссылками! То есть внутренняя функция возвращает закопанный где-то в недрах HTML-код. Против всякой логики отделения логики от представления... Простите тавтологию.
Задача в том, чтобы захачить Битрикс, но не потерять целостность системы. Чтоб при обновлении все не вылетело в трубу, да и вообще хачить ядро Битрикс - дело неблагодарное, сами знаете.
Входящие данные: я хочу показывать на главной странице аккордеон из картинок товаров, вручную подобранных управляющим сайта. Для этого я создал инфоблок, в инфоблоке для удобства раздел, в разделе элемент. Инфоблоку дал свойство Привязка к элементам (другого инфоблока) - множественное. То есть один элемент хранит информацию о привязанных элементах, которые в свою очередь уже имеют картинки для моего аккордеона.
Решение: решение достаточно хитрое, но зато кошерное.
Я создал новый компонент путем прямого копирования родного компонента news.detail. Кто не знает, делается это так: в папке /bitrix/components/ создаем папочку под свои компоненты, например /bitrix/components/my/ - в нее копируем целиком папку /bitrix/components/bitrix/news.detail и переименовываем. Получилось: /bitrix/components/my/news.detail.custom/
Открываем /bitrix/components/my/news.detail.custom/component.php и ищем в нем строку, которая содержит CIBlockFormatProperties::GetDisplayValue. Она там одна должна быть. И именно она отвечает за форматирование свойств элемента инфоблока.
Держим файл открытым и открываем еще один /bitrix/php_interface/init.php. Как известно, это файл, который в логике Битрикс может и должен содержать все наши кастомные настройки, надстройки и хаки. Здесь мы и подменим родной класс форматирования свойств элемента.
Он находится тут: /bitrix/module/iblock/classes/general/comp_formatprops.php. Я сделал так: скопировал весь класс в init.php и переименовал сам класс в CIBlockFormatPropertiesCustom. Таким образом у меня теперь есть свой класс с другим именем, но методы его полностью сохранены. Ядро мы так и не тронули.
Возвращаемся к /bitrix/components/my/news.detail.custom/component.php и редактируем только одну строчку, ту самую где CIBlockFormatProperties - меняем имя класса на CIBlockFormatPropertiesCustom.
Теперь у нас в наличии весь нужный нам функционал - хачим свой класс как угодно и имеем что угодно.
В моем случае получилось вот что:
Ищем:
$rsLink = CIBlockElement::GetList(array(), $arLinkFilter, false, false, array("ID","IBLOCK_ID","NAME","DETAIL_PAGE_URL")); $CACHE["E"][$val] = $rsLink->GetNext();
Заменяем на:
// BOF modification
if($arProperty['CODE'] == 'elements'){
$rsLink = CIBlockElement::GetList(array(), $arLinkFilter, false, false, array("ID","IBLOCK_ID","NAME","PREVIEW_PICTURE","DETAIL_PICTURE","DETAIL_PAGE_URL"));
$CACHE["E"][$val] = $rsLink->GetNext();
$CACHE["E"][$val]['PREVIEW_PICTURE'] = CFile::GetFileArray($CACHE["E"][$val]["PREVIEW_PICTURE"]);
$CACHE["E"][$val]['DETAIL_PICTURE'] = CFile::GetFileArray($CACHE["E"][$val]["DETAIL_PICTURE"]);
} else {
// EOF modification
$rsLink = CIBlockElement::GetList(array(), $arLinkFilter, false, false, array("ID","IBLOCK_ID","NAME","DETAIL_PAGE_URL"));
$CACHE["E"][$val] = $rsLink->GetNext();
// BOF modification
}
// EOF modification
Ищем:
if(is_array($CACHE["E"][$val]))
$arDisplayValue[]='<a href="'.$CACHE["E"][$val]["DETAIL_PAGE_URL"].'">'.$CACHE["E"][$val]["NAME"].'</a>';
Заменяем на:
// BOF modification
if($arProperty['CODE'] == 'elements'){
if(is_array($CACHE["E"][$val]))
$arDisplayValue[] = array(
'PREVIEW_PICTURE' => $CACHE["E"][$val]["PREVIEW_PICTURE"],
'DETAIL_PICTURE' => $CACHE["E"][$val]["DETAIL_PICTURE"],
'DETAIL_PAGE_URL' => $CACHE["E"][$val]["DETAIL_PAGE_URL"]
);
} else {
// EOF modification
if(is_array($CACHE["E"][$val]))
$arDisplayValue[]='<a href="'.$CACHE["E"][$val]["DETAIL_PAGE_URL"].'">'.$CACHE["E"][$val]["NAME"].'</a>';
// BOF modification
}
// EOF modification
Размещаем наш кастомный компонент на странице.
Теперь логика такова: один элемент хранит несколько привязанных элементов в свойстве elements - news.detail.custom берет этот элемент, в свойстве PROPERTY_CODES компонента установлен elements - компонент выполняет обычную работу, но в момент получения отформатированных данных из значений свойств в случае если имя свойства elements создает не обычный массив со ссылками, а массив содержащий пути к превьюшке, пути к большой картинке и ссылки на соответствующие элементы. Дело за малым - создать шаблон для нашего компонента.
ЗЫ. Очевидно, что это не самое оптимальное решение с точки зрения производительности, однако оно наиболее правильно в логике Битрикс. Если вы очень озабочены производительностью - можно спокойно урезать кастомный компонент, убрав лишние запросы.
Гудлак.
Opencart: глобальный файл локализации
Очевидно, но тем не менее постоянно забывается. Файл локализации language/language.php - содержит переменные, которые доступны на всем плацдарме.
Битрикс: манипуляции с боковым меню в Панели управления
Эта задача встречается редко, но тем не менее встречается. Иногда заказчик хочет добавить пару ссылок в боковое меню, чтоб было удобно. Или не хватает родной системы разграничения прав и надо убрать пару пунктов из меню, чтоб не светились.
Так или иначе - официальной документации почти нет. Яндекс находит четыре страницы с обрывками информации, но выход есть! Сделал сам - расскажи другому)
Битрикс: экспорт в Яндекс.Маркет — смешной косяк
С появлением в Битрикс "Проактивной защиты" многие вещи стали непредсказуемыми. Вот, например, попытка экспорта товаров в Яндекс через стандартную процедуру привела к тому, что после выбора инфоблока - разделы его не показываются. в коде страницы -
deleted by bitrix WAF
Что такое - WAF? ваф-ваф))) Это наш фильтр, вернее Веб-антивирус:
| 231045 | 16.07.2010 06:45:45 | Обнаружен вирус | UNKNOWN | 109.188.75.124 | /bitrix/tools/catalog_export/yandex_util.php?IBLOCK_ID=3 |
В общем следите за собой))) и заносите в исключения.
Opencart: маленький хак показывает все дерево категорий в модуле
В стандарте слева показываются категории. В стандарте опять-таки - только рутовые.
Открываем catalog/controller/module/category.php
Находим:
protected function getCategories($parent_id, $current_path = '') { $category_id = array_shift($this->path); $output = ''; $results = $this->model_catalog_category->getCategories($parent_id); if ($results) { $output .= '<ul>'; } foreach ($results as $result) { if (!$current_path) { $new_path = $result['category_id']; } else { $new_path = $current_path . '_' . $result['category_id']; } $output .= '<li>'; $children = ''; if ($category_id == $result['category_id']) { $children = $this->getCategories($result['category_id'], $new_path); } if ($this->category_id == $result['category_id']) { $output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '"><b>' . $result['name'] . '</b></a>'; } else { $output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '">' . $result['name'] . '</a>'; } $output .= $children; $output .= '</li>'; } if ($results) { $output .= '</ul>'; } return $output; }
Заменяем на:
protected function getCategories($parent_id, $current_path = '') { $output = ''; $results = $this->model_catalog_category->getCategories($parent_id); if ($results) { $output .= '<ul>'; } foreach ($results as $result) { if (!$current_path) { $new_path = $result['category_id']; } else { $new_path = $current_path . '_' . $result['category_id']; } $output .= '<li>'; $output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '">' . $result['name'] . '</a>'; $output .= $this->getCategories($result['category_id'], $new_path); $output .= '</li>'; } if ($results) { $output .= '</ul>'; } return $output; }
Получаем дерево)
Модули и дополнения к Opencart
Помимо тех, что есть на оффсайте
Платные:
Несколько реально ценных модов. Например, Layeres Navigation
http://spotonsolutions.net/OpenCart-Mods/commercial-mods
Красивый модуль слайдшоу для главной, но 30 бачей, на мой вкус, многовато:
http://store.jaygilford.com/index.php?route=product/product&path=35_37&product_id=51
Эта небольшая с точки зрения extensions.joomla.org например)) коллекция платных модов - самый крупный репозиторий для опенкарта:
http://theqdomain.com/ocstore/opencart_mods
Создание модуля для Opencart — по-простому
Эта статья - перевод текста с оффсайта
Opencart использует классическую модель MVC (Model View Controller). MVC отделяет котлеты от мух и позволяет разработчикам легко поддерживать код и расширять его отдельными небольшими кусочками, вместо того, чтобы разбирать и пилить огромные коллекции взаимозависимых классов и функций, густо сдобренных html. Перед началом разработки под Opencart авторы крайне рекомендуют ознакомиться с общими принципами MVC, например, вот в Wikipedia.
Opencart — начинаем
Начнем с простого. Найти достойный движок для e-commerce "из коробки" - практически нереально. Все скрипты нижнего уровня ногами растут из osCommerce, и это неизбывное зло. Потому что osCommerce страдал и страдает всеми адскими недугами прошлого века. Он сложен в обслуживании, он не масштабируется, он криво написан, он дыряв, он тупо не красив внутри.
Из всех оскоммерс-лайк скриптов - я остановился на Opencart. Это достойный клон оскоммерса, переписанный с нуля в стиле новой эпохи. MVC, шаблоны, нормальные локализации, тонкий тюнинг, jQuery и прочие радости. Однако информации по нему невероятно мало. То есть практически нет в рунете. Кроме этого опенкарт страдает от родства с оскоммерсом и наследует некоторые его проблемы, поэтому я выбирая Opencart - беру в руки напильник и пилю. К концу июня 2010 я выложу тут допиленную версию Opencart, и это станет веткой от Opencart 1.4.7, которая будет развиваться отдельно. Потому что, увы, как и osCommerce опенкарт - не модулен, и поправить что-нибудь одно и не потерять это при обновлении - не выйдет.
А пока начнем с пачки ссылкок:
http://opencart.com - оффсайт. Растет и развивается, репозиторий плагинов набивается. Форум - англоязычный.
http://myopencart.ru/ - вот тут ребята объявили о том, что это русский дом опенкарта. Жаль, что мало всего. Но локализированную версию можно качать. В остальном пусто.
Самая страшная беда - нет шаблонов... почти никаких нет: ни хороших, ни плохих. А те, что есть - платные.
http://www.opencart-templates.com/index.php?route=product/category&path=41 - шаблоны в пределах $15
http://style.st/opencart-template-leonardo-white - отличная тема (+ в другом цвете) - 50 евро...
http://www.algozone.com/opencart-templates.php?manufacturers_id=30&sort=3a&page=1 - три страницы шаблонов по $140. Похоже, что это template-monster портированный под опенкарт.
http://www.opencartstore.com/OpencartTemplates - четыре зачетные темы по 15 баксов.
http://www.eshopalot.com/index.php?route=product/product&product_id=69 - одна, а жаль. $10.
http://www.alreadymade.com/shop/index.php?route=product/category&path=37_26 - есть несколько приятных... от одного до двадцати долларов.
http://opencarttheme.co.uk/index.php?route=product/category&path=39 - бритиши умеют делать. ничего особенного, но красиво. цены в фунтах - около десяти за штуку.
Но есть и приятные вещи:
http://forum.opencart.com/viewtopic.php?f=21&t=14579 - изящная тема. free. одна из 14 доступных на оффсайте. Почти все остальные - уродливы, как моя пятка...
http://scriptmafia.org/templates/15204-opencart-electronics-template.html - warez
http://www.evohosting.co.uk/blog/web-development/opencart/best-free-opencart-themes/ - подборка фришных тем для опенкарта. качнул все)