Отладка непонятных ошибок в Magento

в 16:45, , рубрики: Magento, php, Веб-разработка, отладка, метки: ,

Наверняка каждый разработчик модулей для Magento попадал в ситуацию, когда вроде бы все сделано правильно, но не работает. Особенно это касается характерных ситуаций: создал роутер, а выдает 404 старницу, создал лэйaут, а контент не выводится, создал темплейт, а страница по прежнему пуста. Отличительной чертой таких ситуация является то, что как правило Magento никак на них не реагирует (не выдается ошибок, логи остаются пустыми). Именно об отладке таких ошибок и пойдет речь в данной статье.

Вдоволь намучавшись с подобными ситуациями, я собрал небольшую коллекцию советов по разработке и методов отладки модулей, которые позволяют быстро справляться с подобными неприятностями. Особенно полезны они будут новичкам, но и опытные разработчики могут найти для себя что-то новое.

Итак, поехали!

Я создал роутер и контроллер для него, но Magento показывает 404 страницу

Почему так происходит:

Скорее всего, неверно назван файл в котором лежит класс контроллера, путь не соответствует названию класса, неверное название класса и подобные ошибки. Быть может это просто опечатка из-за невнимательность, но может случится, что вы не до конца понимаете, как Magento преобразовывает запрос в frontName, controllerName и actionName. В этом случае рекомендую прочитать статью Alan’a Strom’a об определении имени контроллера.

Единственное уточнение, которое следует сделать для новичков — это каким образом вписать в адресс страницы название контроллера, который лежит не в папке controllers, а в ее подкаталогах. Это довольно просто, но с этим иногда возникают проблемы.

Итак, необходимо взять кусок названия контроллера между “Namespace_ModuleName_” и словом “Controller” в конце и привести к нижнему регистру. Например, для имени Namespace_ModuleName_Subfolder1_Subfolder2_IndexController название контреллера в адрессной строке будет следующим subfolder1_subfolder2_index.

Как отлаживать:

Итак, вы хорошо разобрались с тем, как определяется имя контроллера, но все еще видите 404 страницу. Если это случилось, то скорее всего вы положили файл с контроллером не в ту папку или же неправильно назвали сам файл. Самый простой способ это проверить — это вывести путь к контроллеру, который ищет Magento. Для этого идем в класс Mage_Core_Controller_Varien_Router_Standard и ищем там метод _validateControllerClassName(). В этом методе мы получаем полный путь к нашему контроллеру, осталось только вывести его и сверить с нашим.

Вот соответсвующий код:

protected function _validateControllerClassName($realModule, $controller)
{
   $controllerFileName = $this->getControllerFileName($realModule, $controller);
   var_dump($controllerFileName); die(); // added line
   if (!$this->validateControllerFileName($controllerFileName)) {
       return false;
   }

   // …

}

Теперь вместо 404 страницы Magento выдаст путь нашему контроллеру. Исправляем и радуемся.

Если путь содержит Mage/Core/… вместо вашего Namespace/ModuleName, значит вы не определили роутер в config.xml или же сделали это неверно. О том, как это сделать правильно читаем все в той же статье Alan’a Strom’a.

Дальше нас может ожидать еще несколько отображаемых ошибок: а именно Controller file was loaded but class does not exist, которая означает, что мы неверно напечатали название контроллера в файле или же Fatal error: Call to undefined method NameSpace_TestModule_IndexController::hasAction(), которая говорит нам о том, что мы забыли наследовать базовый контроллер Mage_Core_Controller_Front_Action для фронтенда и Mage_Adminhtml_Controller_Action для бекенда.

Я создал роутер, контроллер и метод, но получаю страницу Whoops, our bad...

Почему так происходит:

Очень редкая и простая в исправлении ошибка. Она означает, что наш контроллер не содержит метода, который вы запрашиваете.

Как отлаживать:

Проверьте название вашего метода, скорее всего он назван неверно, возможно вы забыли дописать Action после названия метода.

Мне кажется, что не грузится какой-то из xml-файлов или я хочу посмотреть, какие файлы загружаются

Почему так происходит:

Причин, почему может не подгружать xml-файл достаточно много и рассматривать их в данном топике не имеет смысла. Решение для всех случаев одно и то же, поэтому перейдем сразу к нему.

Как отлаживать:

Простейший способ проверить грузится ли какой-то конкретный xml-файл — это сделать его невалидным. Скажем добавить лишнюю единицу в файл:

<1?xml version="1.0"?>

Теперь при заходе на страницу вы увидите сообщение об ошибке загрузки xml-файла. Если этого сообщения нет, то файл действительно не подгружается. Какие xml-файлы и почему могут не грузится — это тема отдельной статьи и здесь рассматриваться не будет.

Вторая часть нашего вопроса — это узнать, какие xml-файлы все-таки подгружаются. Один из способов это сделать — это дописать несколько строк в файл lib/Varien/Simplexml/Config.php. Ищем метод loadFile, который отвечает за загрузку всех xml-файлов и дописываем туда несколько строк:

public function loadFile($filePath)
{
   if (!is_readable($filePath)) {
       //throw new Exception('Can not read xml file '.$filePath);
       return false;
   }

   // added lines
   $log = fopen("***это путь к вашему каталогу с magento***/var/log/xml.log", "a");
   fwrite($log, "Loading XML file: $filePathn");
   fclose($log);

   // ...

}

Не забудьте вписать ваш путь от корня сервера к каталогу с установленной Magento. А также создать файл xml.log, по указанному пути. Теперь список всех xml-файлов, загруженных при запросе страницы будет записан в указанный log-файл.

Не стоит держать эти строки включенными постоянно, поскольку лог очень быстро достигнет внушительных размеров. Можно просто закомментирвоать их до тех пор, пока они не понадобятся снова.

Я подключил файл с layout’ом, добавил хэндл с блоком, но страница по прежнему остается пустой

Для начала я приведу немного кода:

app/code/local/TestCompany/TestModule/etc/config.xml

<?xml version="1.0"?>
<config>
   <frontend>
       <layout>
           <updates>
               <testmodule>
                   <file>testmodule.xml</file>
               </testmodule>
           </updates>
       </layout>
   </frontend>
</config>

Тут мы подключаем файл с layout’ом. Вот сам этот файл:

app/design/base/default/layouts/testmodule.xml

<?xml version="1.0"?>
<layout version="0.1.0">
   <testmodale_index_index>
       <reference name="root">
           <action method="setTemplate"><template>page/2columns-right.phtml</template></action>
        </reference>
       <reference name="content">
           <block type="core/template" name="testmodule.mainpage" template="testmodule/page" />
       </reference>
   </testmodale_index_index>
</layout>

Этот файл содержит несколько частых ошибок, но мы обсудим их немного позже. Пока же предположим, что в этом файле все написано верно. Также создадим файл с шаблоном:

app/design/base/default/templates/testmodule/page.phtml

<p>Test content.</p>

Итак, теперь причины этой чистой страницы и их решения:

  1. Вы забыли указать в методе контроллера, что нужно подгрузить layout.
    Контроллер должен содержать следующие строки кода:

    	$this->loadLayout();
    	$this->renderLayout();
    	

  2. Не загружается файл с layout’ом.
    Как проверить эту версию вы уже знаете из предыдущего пункта.

  3. Неправильное название хэндла в файле с layout’ом.
    Это одна из ошибок, которые были допущены в нашем примере. В примере, это просто опечатка, необходимо исправить testmodale на testmodule, но иногда так бывает, что вы неправильно определили хэндл для какой-то страницы. Простейшее решение вывести все хэндлы, содержимое которых Magento загрузит для текущей страницы. Для этого добавляем в метод контроллера следующую строку кода:

    	$this->loadLayout();
    	var_dump($this->getLayout()->getUpdate()->getHandles()); die();
    	$this->renderLayout();
    	

    Для нашего примера одним их хэндлов будет testmodule_index_index, который мы указали.

  4. Неправильное название или путь к шаблону.
    Это вторая ошибка, допущенная в нашем примере. Автор кода забыл указать расширение .phtml для файла с шаблоном. Для отладки подобных проблем следует включить так называемые Подсказки пути к шаблонам. Это можно сделать в администраторской части Magento. Переходим в System -> Configuration -> Developer. Выбираем в левом верхнем углу Main Website. Теперь во вкладке Debug появляется два дополнительных поля. Нам необходимо включить Template Path Hints. Теперь при заходе на страницу мы видим путь, по которому находится шаблон, который Magento подключает к странице.

Конечно это не все возможные проблемы, которые могут возникнуть при разработке модуля для Magento, но по крайней мере самые частые и непонятные для новичков теперь, надеюсь, станут не такими уж непонятными. Не забывайте делиться и своими советами в комментариях.

Автор: devoto13

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js