2010-01-18 1 views
1

Wordpress имеет приятную систему api. Я изо всех сил пытаюсь создать равную гибкость, используя более традиционную интерпретацию MVC. Типичный класс представления может выглядеть так:Wordpress-подобная модель для просмотра системы событий api (MVC)

class View 
{ 
    public function set($name, $value) 
    { 
     $this->data[$name] = $value 
    } 

    public function __get($name) ... you know how it works 
} 

Прецедент будет контроллер добавления порядка содержат строки заказа:

$view->add('order', $orderModel); 

Затем файл шаблона может иметь что-то вроде

foreach ($this->order->getOrderLines() as $orderLine) 
{ 
    ?><div><?php echo $orderLine->getItemName(); ?><div><?php 
} 

По крайней мере, это то, что обычно наблюдается во многих фреймворках PHP MVC. Я открыт для альтернативных вариантов, которые решают вопрос:

Как добавить систему событий, такую ​​как wordpress? Например, имя OrderLineItemName.

+1

Что вы пытаетесь отфильтровать на ваш взгляд? Фильтры WordPress вызывается во время (или непосредственно перед) рендеринга. – funwhilelost

+0

@ infamouse: Все может быть кандидатом. – koen

+0

Это не помогает помощнику. Вам нужно будет дать более конкретный пример того, что вы хотите сделать. Тем не менее, я постараюсь ответить на ваш вопрос. –

ответ

2

Хорошо,

Я не 100% именно то, что вы хотите сделать, но у меня есть идея.

Может быть, вы имеете в виду что-то вроде этого:

class View { 
    public $hooks = array('getsomeVar'); 
    public $hooks_functions = array(); 
    public $attributes = array(); 
    public function __set($k,$v) { 
     $this->attributes[$k] = $v; 
    } 
    public function __get($k) { 
     if (isset($this->attributes[$k])){ 
      $hooks = $this->get_functions_by_hook('get' . $k); 
      if (!empty($hooks)){ 
       foreach ($hooks as $klass=>$methods) { 
        if (class_exists($klass)){ 
         $class = new $klass(); 
         foreach ($methods as $method) { 
          if (method_exists($class,$method)){ 
           $this->attributes[$k] = $class->$method($this->attributes[$k]); 
          } 
         } 
        } 
       } 
      } 
      return $this->attributes[$k]; 
     } else { 
      throw new Exception($k . " is not a view variable"); 
     } 
    } 

    public function register_filter($name,$class,$method) { 
     if (in_array($name,$this->hooks)){ 
      $this->hooks_functions[$name][$class][] = $method; 
     } else { 
      throw new Exception($name . ' is not a valid hook'); 
     } 
    } 

    public function get_functions_by_hook($name) { 
     if (array_key_exists($name,$this->hooks_functions)){ 
      return $this->hooks_functions[$name]; 
     } 
     return array(); 
    } 
} 
class MyPlugin { 
    public function fix_string($str) { 
     return str_replace("ruby",'php',$str); 
    } 
} 

$v = new View(); 
$v->someVar = 'ruby is great'; 
$v->register_filter('getsomeVar','MyPlugin','fix_string'); 
echo $v->someVar; 

или вы можете использовать этот метод, который является более событием, как. Снова пример кода, но вы должны быть в состоянии его cannabalize.

class EventDispatcher { 
    public static $listeners = array(); 
    public static function registerListener(&$instance) { 
     if (!in_array($isntance,self::$listeners)){ 
      array_push(self::$listeners,$instance); 
     } 
    } 
    public static function dispatchEvent($name,&$value) { 
     foreach (self::$listeners as $listener) { 
      if (method_exists($listener,'interests')){ 
       $funcs = $listener->interests(); 
       if (array_key_exists($name,$funcs)){ 
        foreach ($funcs as $f) { 
         $value = $listener->$f($value); 
        } 
       } 
      } 
     } 
    } 
} 
class Plugin { 
    public static function registerPlugin($class_name) { 
     if (class_exists($class_name)){ 
      EventDispatcher::registerListener(new $class_name()); 
     } 
    } 
} 
class Model { 
    public function __construct() { 
     EventDispatcher::registerListener($this); 
    } 
    public function special($value) { 
     echo "I got called too!\n\n"; 
     return $value; 
    } 
    public function interests() { 
     return array(
      "getsomeVar" => "special", 
     ); 
    } 
} 
class View { 
    public $attributes = array(); 
    public function __set($k,$v) { 
     $this->attributes[$k] = $v; 
    } 
    public function __get($k) { 
     if (isset($this->attributes[$k])){ 
      EventDispatcher::dispatchEvent('get' . $k,$this->attributes[$k]); 
      return $this->attributes[$k]; 
     } else { 
      throw new Exception($k . " is not a view variable"); 
     } 
    } 
} 
class MyPlugin { 
    public function fix_string($str) { 
     return str_replace("ruby",'php',$str); 
    } 
    public function interests() { 
     return array(
      "getsomeVar" => "fix_string", 
     ); 
    } 
} 
Plugin::registerPlugin('MyPlugin'); 
$model = new Model(); 
$v = new View(); 
$v->someVar = 'ruby is great'; 
echo $v->someVar; 

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

Приветствие, Jason

Добавление:

Большая часть этого материала составляет около WP кодовых.

WP обращается набор переменных в глобальной области, которые изменяются следующим образом:

function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { 
    global $wp_filter, $merged_filters; 

    $idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority); 
    $wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args); 
    unset($merged_filters[ $tag ]); 
    return true; 
} 

Это некоторые другие функции, такие как, has_filter и т.д ...

function apply_filters($tag, $value) { 
    global $wp_filter, $merged_filters, $wp_current_filter; 

    $args = array(); 
    $wp_current_filter[] = $tag; 

    // Do 'all' actions first 
    if (isset($wp_filter['all'])) { 
     $args = func_get_args(); 
     _wp_call_all_hook($args); 
    } 

    if (!isset($wp_filter[$tag])) { 
     array_pop($wp_current_filter); 
     return $value; 
    } 

    // Sort 
    if (!isset($merged_filters[ $tag ])) { 
     ksort($wp_filter[$tag]); 
     $merged_filters[ $tag ] = true; 
    } 

    reset($wp_filter[ $tag ]); 

    if (empty($args)) 
     $args = func_get_args(); 

    do { 
     foreach((array) current($wp_filter[$tag]) as $the_) 
      if (!is_null($the_['function'])){ 
       $args[1] = $value; 
       $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args'])); 
      } 

    } while (next($wp_filter[$tag]) !== false); 

    array_pop($wp_current_filter); 

    return $value; 
} 

Это не событийная system, это таблица поиска методов, которая представляет собой просто гигантский хеш, который ищет пользовательские функции для вызова.

apply_filters, и все плагин, как функции называются процедурно как код оказывается, вот пример

if ($prefixed) { 
     $value = apply_filters("pre_$field", $value); 
     $value = apply_filters("${field_no_prefix}_save_pre", $value); 
    } else { 
     $value = apply_filters("pre_post_$field", $value); 
     $value = apply_filters("${field}_pre", $value); 
    } 

Или для действий, в реальной точки зрения шаблона, как так:

<p class="submit"><input type="submit" class="button" name="submit" value="<?php esc_attr_e('Add Category'); ?>" /></p> 
<?php do_action('edit_link_category_form', $category); ?> 
</form> 
+0

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

+0

jolierouge, спасибо вам за усилия. Во-первых, я думаю, что ваше решение eventDispatcher имеет большее значение, поскольку диспетчерские события/фильтры, по-видимому, несут ответственность за представление.
Проблема, которую я вижу с обоими, заключается в том, что она, похоже, не позволяет фильтровать что-то в цикле. Например, чтобы вернуться к wordpress, категория отображает несколько сообщений в цикле. В цикле он имеет фильтрацию событий. Я не вижу, как это можно сделать внутри цикла: $ view-> posts = $ latestTenPostsInCategoryX; foreach этих сообщений: echo $ post-> title(); // и название отфильтровано – koen

+0

Вот еще один фокус моей общей цели: http://stackoverflow.com/questions/2074317/viewhelper-newable-injectable-dilemma – koen

Смежные вопросы