Решение проблемы с активацией bbPress Attachments

Устанавливал заказчику bbPress и плагин bbPress Attachments 0.2.7. Плагин установился без проблем, но вот незадача: вложения загружаются (создаются файлы на диске), но на форуме не отображаются.

Оказалось, что всё дело портит ошибка в функции активации плагина.

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

Плагин хранит свои настройки непосредственно в коде:

[-]
View Code PHP
$bb_attachments['role']['see']="read";           // minimum role to see list of attachments = read/participate/moderate/administrate
$bb_attachments['role']['inline']="read";    // minimum role to view inline reduced images = read/participate/moderate/administrate
$bb_attachments['role']['download']="participate";  // minimum role to download original = read/participate/moderate/administrate
$bb_attachments['role']['upload']="participate";  // minimum role to upload = participate/moderate/administrate (times out with post edit time)
$bb_attachments['role']['delete']="moderate";  // minimum role to delete = read/participate/moderate/administrate
// ...
$bb_attachments['db']="bb_attachments";   //   $bbdb->prefix."attachments";  // database name - force to "bb_attachments" if you need compatibility with an old install

Процедура активации выглядит так:

[-]
View Code PHP
function bb_attachments_install() {
global $bbdb,$bb_attachments;
$bbdb->query("CREATE TABLE IF NOT EXISTS ".$bb_attachments['db']." (
    id              int(10)        UNSIGNED NOT NULL auto_increment,
    time            int(10)        UNSIGNED NOT NULL default '0',
    post_id         int(10)        UNSIGNED NOT NULL default '0',
    user_id         int(10)        UNSIGNED NOT NULL default '0',
    user_ip         int(10)        UNSIGNED NOT NULL default '0',
    status          tinyint(10)    UNSIGNED NOT NULL default '0',
    downloads       int(10)        UNSIGNED NOT NULL default '0',
    size            int(10)        UNSIGNED NOT NULL default '0',
    ext             varchar(255)            NOT NULL default '',
    mime            varchar(255)            NOT NULL default '',
    filename        varchar(255)            NOT NULL default '',
    PRIMARY KEY ( id ),
    INDEX ( post_id )
    ) CHARSET utf8  COLLATE utf8_general_ci"
);
//..
}

А к MySQL запрос приходит в виде

[-]
View Code MySQL
CREATE TABLE IF NOT EXISTS  ( /* ... */ ) CHARSET utf8  COLLATE utf8_general_ci

Так как имя таблицы пустое, то MySQL возвращает ошибку. Но ведь переменная $bb_attachments объявлена как глобальная и $bb_attachments['db']="bb_attachments". Проблема здесь в том, что bbPress при активации плагина подключает его код не из глобального контекста, а из функции:

[-]
View Code PHP
function bb_activate_plugin( $plugin, $redirect = '' ) {
    $active_plugins = (array) bb_get_option( 'active_plugins' );
    $plugin = bb_plugin_basename( trim( $plugin ) );

    $valid_path = bb_validate_plugin( $plugin );
    if ( is_wp_error( $valid_path ) )
        return $valid_path;

    if ( in_array( $plugin, $active_plugins ) ) {
        return false;
    }

    if ( !empty( $redirect ) ) {
        // We'll override this later if the plugin can be included without fatal error
        wp_redirect( add_query_arg( '_scrape_nonce', bb_create_nonce( 'scrape-plugin_' . $plugin ), $redirect ) );
    }

    ob_start();
    @include( $valid_path ); /* <<< Вот оно! */
    // Add to the active plugins array
    $active_plugins[] = $plugin;
    ksort( $active_plugins );
    bb_update_option( 'active_plugins', $active_plugins );
    do_action( 'bb_activate_plugin_' . $plugin );
    ob_end_clean();

    return $valid_path;
}

Таким образом, в момент активации плагина массив $bb_attachments принадлежит не глобальному пространству имён ($GLOBALS), а функции bb_activate_plugin(). И, как следствие, global $bb_attachments адресует несуществующую на момент активации плагина глобальную переменную.

Решение: перед первым упоминанием переменной $bb_attachments добавить:

[-]
View Code PHP
global $bb_attachments;

После чего код плагина будет выглядеть примерно так:

[-]
View Code PHP
<?php
/*
Plugin Name: bbPress Attachments
Plugin URI: http://bbpress.org/plugins/topic/bb-attachments
Description: Gives members the ability to upload attachments on their posts.
Author: _ck_
Author URI: http://bbShowcase.org
Version: 0.2.7

License: CC-GNU-GPL http://creativecommons.org/licenses/GPL/2.0/

Donate: http://bbshowcase.org/donate/
*/


global $bb_attachments; /* <<< Вот оно! */
$bb_attachments['role']['see']="read";           // minimum role to see list of attachments = read/participate/moderate/administrate

Разработчикам (вообще всем) хочу сказать две вещи:

  1. Глобальные переменные — это плохо.
  2. Если всё же нужно использовать глобальные переменные, то их нужно явно помечать как глобальные. В противном случае при известных обстоятельствах они внезапно могут стать локальными.
Добавить в закладки

Связанные записи

21
Сен
2009

Комментарии к статье «bbPress Attachments 0.2.7: решение проблемы с установкой» (1)  »

  1. Vladimir says:

    Сообщение на форуме bbPress об этой ошибке.

Подписаться на RSS-ленту комментариев к статье «bbPress Attachments 0.2.7: решение проблемы с установкой» Trackback URL: http://blog.sjinks.org.ua/bbpress/641-bbpress-attachments-fixing-installer-bugs/trackback/

Оставить комментарий к записи «bbPress Attachments 0.2.7: решение проблемы с установкой»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, Вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя