Статьи

Анализ логов nginx

Статистика по запросам:
grep "20/Nov" /var/log/nginx/access.log | cut -d \" -f 2 | cut -d ' ' -f 2 |  sort | uniq -c | sort -n | tail -n 30 

Статистика по доменам:
grep "20/Nov" /var/log/nginx/access.log | cut -d ' ' -f 1 | sort | uniq -c | sort -n | tail -n 30

Количество запросов по часам:
grep "20/Nov" /var/log/nginx/access.log | cut -d [ -f 2 | cut -d ] -f 1 | cut -d : -f 1,2 | uniq -c

Исправление PHP ошибок "Warning: array_filter() expects parameter 1 to be array"

Часто в логах заносятся следующие PHP ошибки:
Warning: array_filter() expects parameter 1 to be array, string given в функции field_collection_item_is_empty() (строка 591 в файле /var/www/.../sites/all/modules/field_collection/field_collection.module).

Связано это с ошибкой в модуле Field Collection, которая исправляется патчем, прикрепленным к данной статье.

Конфигурация бандла через Extension класс

Это перевод оригинальной статьи «How to expose a Semantic Configuration for a Bundle» (Как влиять на семантические настройки бандла). В статье описаны способы конфигурации вашего бандла и его сервисов.

Автоматическое развертывание Drupal сайта на сервере после Git Push

Для большего удобства, можно настроить сайт на сервере так, чтобы он автоматически обновлялся после каждого вашего пуша в основной Git репозиторий, например BitBucket. Для этого в самом репозитории настраиваем web-hook, который будет автоматически отправлять POST запрос по адресу http://site.ru/deploy.php

Содержимое файла deploy.php:

При необходимости можно добавить свои команды в массив $commands.

Изменение текста "Удалить" на виджете загрузки изображения

Для изменения надписи "удалить" для кнопки удаления изображения в форме редактирования:

function hook_image_widget($vars)
{
    $vars['element']['remove_button']['#value'] = "Удалить изображение";
    return theme_image_widget($vars);
}

Для изменения надписи "удалить" для элемента коллекции полей в форме редактирования:  

Конфигурация сервера nginx + apache под Symfony 2

Рассмотрим, как настроить на сервере связку nginx (фронтенд) + apache (бекенд) для корректной работы Symfony 2 с её функциональностью ассетов и пр. Основная идея в том, чтобы статика отдавалась через nginx, а php код через apache. Однако если статика не находится с помощью nginx (что бывает из-за генерации Assets), в этом случае надо вместо 404 ошибки - пробовать направлять запрос в Apache.

В виртуальном хосте nginx прописываем:

server {

Свой вывод страниц ошибок 403, 404 и т.п.

Существует несколько способов темизации страниц ошибок.

Способ 1 - переопределение шаблонов

Самый простой способ - создать в папке /app/Resources/TwigBundle/views/Exception/ файлы с именем error404.html.twig, error403.html.twig, error.html.twig и т.п. Теперь наши шаблоны будут срабатывать при вызове в контроллере:

throw $this->createNotFoundException('Page not found');

Подробнее тут.

 

Парсинг удалённого сайта на Drupal и создание нод

Сперва скачиваем библиотеку QueryPath в корневую папку сайта. Далее создаём файл parser.php и подключаем в нём ядро Друпала и библиотеку QueryPath:

Упрощение админки Drupal для заказчика

CСуществует множество способов как упростить жизнь простым модераторам, работающим с сайтом на Drupal и не владеющими всеми его тонкостями. Вот несколько из них:

1) Simplifyhttps://www.drupal.org/project/simplify
Позволяет скрывать ненужные поля с форм добавления/редактирования материалов, таксономии и т.п.

Загрузка изображений в CkEditor одним нажатием

Существует множество разных способов загрузки изображений внутрь текста с использованием визуального редактора (CkEditor и не только). 

1) Самый неудобный способ - это загружать изображения на сторонний сайт хранилище-изображений и прикреплять картинку в CkEditor по ссылке.

2) Гораздо более правильный способ - это добавления поля "images" и установка модуля Insert, Который позволяет вставлять загруженные изображения в CkEditor одним нажатием, без необходимости копировать их URL.

Ошибка "JQuery Error: $.curCSS is not a function"

Данная ошибка может появляться после обновления jQuery до версии 1.8.x.

Для её исправления необходимо внедрить следующий JS код:

(function($) { $.curCSS = $.css; })(jQuery);

Ограничение доступа по IP через iptables

Отбпасываем все подключения на указанных портах (FTP, SSH).
-A INPUT -p tcp -m multiport --dports 21,22 -j DROP

И выше этого правила указываем ip-адреса, которым разрешен доступ:
-A INPUT -s x.x.x.x/32 -j ACCEPT
-A INPUT -s x.x.x.x/32 -j ACCEPT

Для того,чтоб добавить новый ip-адрес в список доверенных необходимо выполнить следующую команду:
iptables -I INPUT -s ip-address -j ACCEPT

Для того, чтоб удалить необходимо выполнить:
iptables -D INPUT -s ip-address -j ACCEPT

Создание своего расширения для Twig

В Twig имеется множество расширений, которые удобно использовать в шаблонах. Однако может возникнуть ситуация, когда будет необходимо написать собственное расширение. Например мы хотим отображать даты в формате: 2 дня назад, 3 месяца назад и т.п.

Пусть это расширение используется следующим образом:

{{ comment.created|created_ago }}

1. Сперва создадим файл для Twig расширения по адресу src/Acme/TestBundle/Twig/Extensions/AcmeTestExtension.php со следующим содержимым:

Синхронизация баз данных и файлов на Drupal

Для переноса контента с удаленного компьютера на локальный (или наоборот) очень помогут команды drush sql-sync и drush rsync, соответственно.

Drupal 7 + Ckeditor 4.4 + SyntaxHighLight 1.7 = подсветка синтаксиса

1) Устанавливаем модуль CKeditor и в пути к библиотеки указываем - //cdn.ckeditor.com/4.4.0/full-all

2) Устанавливаем модуль Syntax Highlighter и включаем его.

2) Скачиваем плагин Syntaxhighlighter Interface и копируем в папку /sites/all/modules/ckeditor/plugins/syntaxhighlight. Так, чтобы в данной директории оказался файл plugin.js.

Перенос сайта Drupal с сервера или на сервер

Процесс переноса сайта на Drupal
с одного сервера на другой

1) Прописать локальный домен в файле hosts:
sudo nano /etc/hosts

2) Добавить конфигурацию сайта в Apache/nginx через Ajenti или вручную. 
Проверить работу сайта на этом этапе.

3) Подлкючаемся по SSH к удаленному сайту:
ssh <username>@<host>

Закрываем от индексации тестовый домен

Для того, чтобы тестовый домен для разработки не попал в индекс поисковых систем необходимо прописать запрет на индексацию в файле robots.txt. Однако основной домен должен остаться в индексе. Для этого создаём отдельный файл test_robots.txt для тестового домена с содержимым:

User-agent: *
Disallow: /

А в файле .htaccess прописываем:

RewriteCond %{HTTP_HOST} ^test.DOMAINNAME.ru$ [NC]
RewriteRule ^robots.txt$ test_robots.txt [L]

Слияние веток git с отображением в дереве изменений (--no-ff)

Часто возникает проблема, когда после сливания ветки в master, а затем выполнения push мастера в репозиторий - в удаленный репозиторий не передаётся информация о том, что было слияние веток. И в дереве изменений коммиты отображаются прямо внутри мастера. Это происходит из-за того, что Git может выполнять слияние веток двумя способами:

Операции с изображениями в командной строке Linux

Для операций с изображениями потребуется пакет imagemagick. Командой данного пакета является - convert.

Изменить размер изображения:

convert -resize 1400x1400 image.jpg image.resized.jpg

Размер можно задавать следующими способами:

Просмотр директорий и их размера в Linux

Консольная программа для анализа свободного места NCDU

ncdu /

Просмотр всех директорий, отсортированных по размеру:
du -mh --max-depth 1 | sort -rn

Просмотр 10 самых больших директорий:
du -mh --max-depth 1 | sort -rn | head -11

Вывод блоков в Drupal

Блок представления:

$block = module_invoke('views', 'block_view', 'catalog-block_2');   		
print render($block['content']);

Или так:

$block = block_load('block', 1);
$arr = _block_get_renderable_array(_block_render_blocks(array($block))); 
$block = drupal_render($arr);
print $block;

Своя функция в template.php:

Вывод материалов по Ajax в собственном модуле

В большинстве случаев для множественного вывода материалов на сайте, построенном на Drupal, достаточно прибегнуть к услугам модуля Views. Данный модуль имеет массу возможностей и доп. модулей. Однако иногда встаёт задача нестандартного вывода нод на странице, когда "ковыряние" во Views окажется более сложным и нудным делом, нежели написание своего модуля. Рассмотрим упорядоченный вывод нод в таблице с постраничной навигацией, сортировкой по любой колонке, фильтрами и всё это через Ajax!

Переход с MySQL на SQLite в Drupal 7.x

Drupal 7 «из коробки» поддерживает сразу несколько хранилищ, а именно: MySQL, PostgreSQL, SQLite. Это значит, что уровень абстракции существующий в API Drupal`а, гарантирует, что одни и те же модули (и сайты в целом) будут с одинаковым успехом работать на любой из этих баз данных.

Для перехода с MySQL на SQLite необходим установить модуль DBTNG Migrator. После чего надо внести изменения в файле settings.php, добавив в него базу данных SQLite под другим индексом. Например так:

Создание простого модуля с шаблоном .tpl.php

Создаем директорию "/sites/all/modules/my_module". В которой добавляем 2 файла:

1) Файл с описанием модуля - my_module.info

2) Файл с самим содержимым модуля - my_module.module

Далее очищаем кеш и включаем модуль в админ панели. И переходим по адресу /custom_page

 

Установка Ruby on Rails на Linux

1) Установка пакетного менеджера rvm:

open vim

\curl -sSL https://get.rvm.io | bash -s stable

reopen a vim

rvm -v

2) Установка ruby:

sudo apt-get purge ruby (this will remove old ruby that is not installed by rvm)

rvm list known (this will show available ruby versions)

rvm install 2.2.0 (it's quite smart, will do a lot check, might take a while)

Как извлечь (распаковать) Архивы [tar], [tar.gz] и [tar.bz2]

Распаковать и Разархивировать Файлы [tar], [tar.gz] и [tar.bz2]

[tar] - Извлечь (распаковать) TAR Архив

$ tar -xvf foo.tar

[tar.gz] - Извлечь и Разархивировать TAR Архив, сжатый с помощью GZIP

$ tar -xvzf foo.tar.gz

[tar.bz2] - Извлечь и Разархивировать TAR Архив, сжатый с помощью BZIP2

$ tar -xvjf foo.tar.bz2
Опции Описание
-x извлечь файлы из архива

Service Container and Dependency Injection in Symfony framework

Иногда одна единственная идея способна изменить все представление о программировании. Для меня одной из такой идей была идея сервис-контейнера. Это как золотой грааль). Вообще-то, идея не сугубо Symfony framework, это просто один из удачных паттернов проектирования приложений, часто используемый в Symfony.

Несовместимость модуля "RobotsTxt" и опции "Сжатие кэшированных страниц"

RobotsTxt - модуль удобен для мультисайтинга на Drupal. Он позволяет прописывать свой robots.txt для каждого домена прямо из админ панели. Однако, у него был обнаружен баг при включенной опции производительности CMS Drupal 7 - "Сжатие кэшированных страниц" на странице /admin/config/development/performance.

Ошибка "FieldCollectionItemEntity::$type в функции yamaps_field_formatter_view()"

При возникновении ошибок в журнале типа:

Notice: Undefined property: FieldCollectionItemEntity::$type в функции yamaps_field_formatter_view() (строка 437 в файле /var/www/nasosdon/data/www/nasosdon.ru/sites/all/modules/yamaps/inc/yamaps.formatter.inc).

Необходимо внести изменения в модуль yamaps в файле /sites/all/modules/yamaps/inc/yamaps.fromatter.inc. Перед строкой 

$id = drupal_html_id(implode('-', array(

Добавить строчку:

Настройка SSH аутентификации с помощью публичного ключа

Настроим доступ с локальном компьютера на удаленный через SSH без ввода пароля - с помощью пары ключей: 

Задачи при завершении работ над сайтом

​Development:

  • ЯндексМетрика
  • ЯндексВебмастер
  • Добавить Favicon
  • Создание менеджера для админки
  • Проверка всех разделов сайта на наличие ошибок

 

SEO:

Наследование бандлов

У Symfony framework  интересная системанаследования бандлов (bundle). Интересная она тем, что действует как ООП наследование с точностью до наоборот. При наследовании бандла модификации задевают родительский.

Правки в модуле "Sitemap" для терминов с одной нодой

Если у нас имеется только один материал, принадлежащий данному термину, то будет логично переходить сразу на карточку данного товара, а не на страницу термина (на которой будет всего 1 ссылка на данный товар). Если мы выводим карту сайта для людей с помощью модуля Sitemap, то необходимо в файле /sites/all/modules/site_map/site_map.module перед строкой elseif ($term->count) { вставить следующий код:

Работа с консолью

Вывод сообщений

$output->writeln('Message');
$output->writeln('<error>This error</error>');

 

Ввод данных

$dialog = $this->getHelper('dialog');
$validator = function ($value) {
    // Проверка $value
    return $value;
};
$ask = $dialog->askAndValidate($output, 'Enter your name: ', $validator);
// Обработка ответа на вопрос $ask

Другие варианты ввода

Удаление метатегов canonical, shortlink, generator из Drupal

В файле template.php необходимо прописать:

function TEMPLATENAME_html_head_alter(&$head_elements) {
    $remove_meta = array('canonical','shortlink','generator');
    foreach ($head_elements as $key => $element) {
      if (isset($element['#name']) && in_array($element['#name'],$remove_meta)) {
        unset($head_elements[$key]); 
      }
    }
}

 

Добавление дополнительных режимов просмотра (full, teaser)

Создаем модуль или используем готовый. В нем прописываем функцию:

<?php
function MODULE_NAME_entity_info_alter(&$entity_info) {
  $entity_info['node']['view modes']['teaser_custom'] = array(
    'label' => t('Teaser custom'),
    'custom settings' => TRUE,
  );
}

Далее включаем модуль и переходим в "Типы материалов" -> нужный тип ноды -> "Управление отображением", включаем нужные поля.

Ядро контроллеров

На каждом сайте существует множество блоков (меню, погода, новости...), чтобы не использовать SonataBlockBundle, не подключать контроллеры в каждом шаблоне - создаем ядро контроллеров

Создадим бандл AcmeDemoBundle, теперь добавим ядро контроллеров (Acme/DemoBundle/Controller/CoreController.php)

Использование параметров и конфигураций

Использование параметров

Параметры задаются в отдельном файле app/config/parameters.yml (также можно и в app/config/config.yml), назначим параметр site_name:

parameters:
    site_name: "Название сайта"

Далее выведем его в контроллере:

echo $this->container->getParameter('site_name');

 

Использование конфигураций

Скрываем лишние элементы с формы добавления/редактирования ноды

.tabledrag-processed { width:100%; }
#block-admin-configure .vertical-tabs,
#edit-visibility-title,
#edit-regions,
.tabledrag-toggle-weight-wrapper, 
.ckeditor_links,
.filter-wrapper.form-wrapper { display:none !important; }

Если большой батон one click upload:

.cke_top .ocupload-processed{position:relative;}
.cke_top .ocupload-processed object {width:20px;height:20px;margin: 0;padding: 0;
    position: absolute;top: 1px;left: 2px;cursor: pointer;opacity: 0;}

CkEditor + OneClickUpload изображение отображается как ссылка

Как только загрузил картинку в CkEditor, при двойном клике по ней - открываются "Свойства ссылки", вместо того, чтобы открыть "Свойства изображения". После сохранения материала и его повторного редактирования - всё становится нормально и теперь при двойном клике открываются именно "Свойства изображения", а также появляется возможность изменять размер изображения. Чтобы избежать этого - необходимо в файле /sites/all/modules/ocupload/static/plugin.js после строчки:

Добавление индивидуального шаблона для конкретной ноды Drupal

При работе по системе GIT+Features возникает проблема с невозможностью создания шаблонов типа node--[nid].tpl.php, так как один и тот же материал может иметь разные nid на сервере и на локальной машине. Для решения данной проблемы применяется следующий подход.

 

FancyBox сохраняются, но не обновляются настройки

 

Заменяем в файле модуля "fancybox.admin.inc" 32 строку

$settings = _fancybox_array_replace_recursive(variable_get('fancybox_settings'), _fancybox_defaults());

на

$settings = variable_get('fancybox_settings');

Вывод фильтров Views в любом месте на странице

Вариант 1 (более короткий):

    $view = views_get_view('taxonomy_term'); // get your view from database
    $view->set_display('page'); // set the display of your view
    $view->init_handlers(); // initialise the handlers
    $exposed_form = $view->display_handler->get_plugin('exposed_form');
    print $exposed_form->render_exposed_form(true);

Вариант 2 (более подробный):

Календарь событий

Для того что бы у нас правильно отображались наши события, нужно получить их с базы данных. 

foreach ($result_services as $val):    

  $result[$key]['title'] = $val->title;

  $result[$key]['publish'] = $val->field_publish_value;

  $result[$key]['day'] = $val->field_day_value;

  $result[$key]['day_month'] = $val->field_num_month_value;

  $result[$key]['datepicker'] = $val->field_datepicker_value;

Редактирование материалов "на лету" по Ajax

Недостаток использования визуальных редакторов - возможное различие между стилями страницы просмотра и правки материала. В результате чего результат форматирования текста в CkEditor может отличаться в связи с тем, что к тексту применяются еще стили, которые проявляются только на странице просмотра материала.

Чтобы избежать данную проблему - воспользуемся прекрасным модулем Edit.

Пошаговая инструкция по установке модуля Edit:

Редирект после авторизации

Часто бывает необходимо перенаправлять авторизованного посетителя сайта сразу после ввода логина и пароля, например, на главную страницу. Так как страница /user/* не содержит никакой полезной информации и только вводит в заблуждение.

Одно из решений - прописать в файле .htaccess следующее правило:

RewriteRule ^users/(\w) / [L,R=301]
RewriteRule ^user/(\d+) / [L,R=301]

 

Статистика использования оперативной памяти в МБ

Для просмотра списка всех процессов, отсортированных по занимаемой оперативной памяти в МБ:
ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }'

Для просмотра общей статистики по оперативной памяти:
free -h