По долгу работы пришлось столкнуться в жизни с плагином Event Calendar. Скажу честно: если бы не жёсткий дедлайн, я бы не стал пытаться исправлять его и затачивать напильником под конкретные нужды, быстрее было бы переписать. Причина, по которой я не хотел бы его использовать — плагин не вышел из стадии RC3 с конца октября прошлого (2007) года и имеет одиннадцать открытых багов в багтрекере.
Сегодня я расскажу о такой интересной ошибке как "Unknown column 'wp_posts.ec3_sch.start' in 'order clause'
".
Столкнувшись с проблемой, я начал грешить на плагин Disclose Secret, который, как я знал, также переписывает регулярными выражениями запросы WordPress. Как оказалось впоследствии, я был не прав: проблема была в функции ec3_filter_posts_orderby
:
{
global $ec3;
$regexp='/\bpost_date\b( DESC\b| ASC\b)?/i';
if($ec3->order_by_start && preg_match($regexp,$orderby,$match))
{
if($match[1] && $match[1]==' DESC')
$orderby=preg_replace($regexp,'ec3_sch.start',$orderby);
else
$orderby=preg_replace($regexp,'ec3_sch.start DESC',$orderby);
}
return $orderby;
}
Более конкретно — в регулярном выражении в строке $regexp='/\bpost_date\b( DESC\b| ASC\b)?/i';
.
Если посмотреть на код запроса:
FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
LEFT JOIN wp_ec3_schedule ec3_sch ON ec3_sch.post_id=id AND ec3_sch.end>='2008-08-28 00:00:00'
WHERE
1=1 AND
wp_term_taxonomy.taxonomy = 'category' AND
wp_term_taxonomy.term_id IN ('3') AND
wp_posts.post_type = 'post' AND
(wp_posts.post_status = 'publish') AND
ec3_sch.post_id IS NOT NULL
GROUP BY wp_posts.ID
ORDER BY wp_posts.ec3_sch.start
LIMIT 0, 10
То можно заметить, что вышеприведённое регулярное выражение не учитывает, что в ORDER BY
может присутствовать имя таблицы. Если же мы изменим регулярное выражение следующим образом:
То функция будет работать так, как надо.
По традиции привожу патч в формате unified diff, решающий эту проблему:
+++ eventcalendar3.php 2008-08-28 22:44:13.000000000 +0300
@@ -240,7 +240,7 @@
function ec3_filter_posts_orderby(&$orderby)
{
global $ec3;
- $regexp='/\bpost_date\b( DESC\b| ASC\b)?/i';
+ $regexp='/\b(?:[a-z0-9_]*posts\\.)?post_date\b( DESC\b| ASC\b)?/i';
if($ec3->order_by_start && preg_match($regexp,$orderby,$match))
{
if($match[1] && $match[1]==' DESC')