alecpl
2010-02-13 48bc52e835bd5485f7443d54399e4fb0d36732d7
program/include/rcube_plugin_api.php
@@ -15,7 +15,7 @@
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 +-----------------------------------------------------------------------+
 $Id: $
 $Id$
*/
@@ -39,7 +39,8 @@
  private $objectsmap = array();
  private $template_contents = array();
  
  private  $required_plugins = array('filesystem_attachments');
  private $required_plugins = array('filesystem_attachments');
  private $active_hook = false;
  /**
   * This implements the 'singleton' design pattern
@@ -61,8 +62,7 @@
   */
  private function __construct()
  {
    $rcmail = rcmail::get_instance();
    $this->dir = realpath($rcmail->config->get('plugins_dir'));
    $this->dir = INSTALL_PATH . $this->url;
  }
  
  
@@ -90,17 +90,21 @@
        if (class_exists($plugin_name, false)) {
          $plugin = new $plugin_name($this);
          // check inheritance and task specification
          if (is_subclass_of($plugin, 'rcube_plugin') && (!$plugin->task || $plugin->task == $rcmail->task)) {
          if (is_subclass_of($plugin, 'rcube_plugin') && (!$plugin->task || preg_match('/^('.$plugin->task.')$/i', $rcmail->task))) {
            $plugin->init();
            $this->plugins[] = $plugin;
          }
        }
        else {
          raise_error(array('code' => 520, 'type' => 'php', 'message' => "No plugin class $plugin_name found in $fn"), true, false);
          raise_error(array('code' => 520, 'type' => 'php',
       'file' => __FILE__, 'line' => __LINE__,
       'message' => "No plugin class $plugin_name found in $fn"), true, false);
        }
      }
      else {
        raise_error(array('code' => 520, 'type' => 'php', 'message' => "Failed to load plugin file $fn"), true, false);
        raise_error(array('code' => 520, 'type' => 'php',
     'file' => __FILE__, 'line' => __LINE__,
     'message' => "Failed to load plugin file $fn"), true, false);
      }
    }
    
@@ -118,15 +122,17 @@
      if (!$loaded) {
        $fn = $plugins_dir->path . DIRECTORY_SEPARATOR . $plugin_name . DIRECTORY_SEPARATOR . $plugin_name . '.php';
        if (file_exists($fn)) {
          include($fn);
          include_once($fn);
          
          if (class_exists($plugin_name, false)) {
            $plugin = new $plugin_name($this);
            // check inheritance
            if (is_subclass_of($plugin, 'rcube_plugin')) {
              $plugin->init();
              $this->plugins[] = $plugin;
              $loaded = true;
         if (!$plugin->task || preg_match('/('.$plugin->task.')/i', $rcmail->task)) {
                $plugin->init();
                $this->plugins[] = $plugin;
              }
         $loaded = true;
            }
          }
        }
@@ -134,7 +140,9 @@
      
      // trigger fatal error if still not loaded
      if (!$loaded) {
        raise_error(array('code' => 520, 'type' => 'php', 'message' => "Requried plugin $plugin_name was not loaded"), true, true);
        raise_error(array('code' => 520, 'type' => 'php',
     'file' => __FILE__, 'line' => __LINE__,
     'message' => "Requried plugin $plugin_name was not loaded"), true, true);
      }
    }
@@ -142,15 +150,6 @@
    $this->register_hook('template_container', array($this, 'template_container_hook'));
    
    // maybe also register a shudown function which triggers shutdown functions of all plugin objects
    // call imap_init right now
    // (should actually be done in rcmail::imap_init() but plugins are not initialized then)
    if ($rcmail->imap) {
      $hook = $this->exec_hook('imap_init', array('fetch_headers' => $rcmail->imap->fetch_add_headers));
      if ($hook['fetch_headers'])
        $rcmail->imap->fetch_add_headers = $hook['fetch_headers'];
    }
  }
  
  
@@ -165,7 +164,9 @@
    if (is_callable($callback))
      $this->handlers[$hook][] = $callback;
    else
      raise_error(array('code' => 521, 'type' => 'php', 'message' => "Invalid callback function for $hook"), true, false);
      raise_error(array('code' => 521, 'type' => 'php',
        'file' => __FILE__, 'line' => __LINE__,
        'message' => "Invalid callback function for $hook"), true, false);
  }
  
  
@@ -179,7 +180,11 @@
   */
  public function exec_hook($hook, $args = array())
  {
    if (!is_array($args))
      $args = array('arg' => $args);
    $args += array('abort' => false);
    $this->active_hook = $hook;
    
    foreach ((array)$this->handlers[$hook] as $callback) {
      $ret = call_user_func($callback, $args);
@@ -190,6 +195,7 @@
        break;
    }
    
    $this->active_hook = false;
    return $args;
  }
@@ -213,7 +219,9 @@
      $this->actionmap[$action] = $owner;
    }
    else {
      raise_error(array('code' => 523, 'type' => 'php', 'message' => "Cannot register action $action; already taken by another plugin"), true, false);
      raise_error(array('code' => 523, 'type' => 'php',
        'file' => __FILE__, 'line' => __LINE__,
        'message' => "Cannot register action $action; already taken by another plugin"), true, false);
    }
  }
@@ -230,7 +238,9 @@
      call_user_func($this->actions[$action]);
    }
    else {
      raise_error(array('code' => 524, 'type' => 'php', 'message' => "No handler found for action $action"), true, true);
      raise_error(array('code' => 524, 'type' => 'php',
        'file' => __FILE__, 'line' => __LINE__,
        'message' => "No handler found for action $action"), true, true);
    }
  }
@@ -254,8 +264,23 @@
      $this->objectsmap[$name] = $owner;
    }
    else {
      raise_error(array('code' => 525, 'type' => 'php', 'message' => "Cannot register template handler $name; already taken by another plugin"), true, false);
      raise_error(array('code' => 525, 'type' => 'php',
        'file' => __FILE__, 'line' => __LINE__,
        'message' => "Cannot register template handler $name; already taken by another plugin"), true, false);
    }
  }
  /**
   * Check if a plugin hook is currently processing.
   * Mainly used to prevent loops and recursion.
   *
   * @param string Hook to check (optional)
   * @return boolean True if any/the given hook is currently processed, otherwise false
   */
  public function is_processing($hook = null)
  {
    return $this->active_hook && (!$hook || $this->active_hook == $hook);
  }
  
  /**
@@ -264,7 +289,7 @@
  public function include_script($fn)
  {
    if ($this->output->type == 'html') {
      $src = $this->ressource_url($fn);
      $src = $this->resource_url($fn);
      $this->output->add_header(html::tag('script', array('type' => "text/javascript", 'src' => $src)));
    }
  }
@@ -275,7 +300,7 @@
  public function include_stylesheet($fn)
  {
    if ($this->output->type == 'html') {
      $src = $this->ressource_url($fn);
      $src = $this->resource_url($fn);
      $this->output->add_header(html::tag('link', array('rel' => "stylesheet", 'type' => "text/css", 'href' => $src)));
    }
  }
@@ -294,15 +319,15 @@
  private function template_container_hook($attrib)
  {
    $container = $attrib['name'];
    return array('content' => $this->template_contents[$container]);
    return array('content' => $attrib['content'] . $this->template_contents[$container]);
  }
  
  /**
   * Make the given file name link into the plugins directory
   */
  private function ressource_url($fn)
  private function resource_url($fn)
  {
    if ($fn[0] != '/' && !eregi('^https?://', $fn))
    if ($fn[0] != '/' && !preg_match('|^https?://|i', $fn))
      return $this->url . $fn;
    else
      return $fn;