Elastic
[ class tree: Elastic ] [ index: Elastic ] [ all elements ]

Source for file module.php

Documentation is available at module.php

  1. <?php
  2. /**
  3.  * The basic unit of a theme.
  4.  * 
  5.  * Contains several APIs.
  6.  * 
  7.  * <br><b>Hooks API:</b>
  8.  * <ul>
  9.  * <li>{@link Module::format_hook()}</li>
  10.  * <li>{@link Module::do_atomic()}</li>
  11.  * <li>{@link Module::do_atomic_specific()}</li>
  12.  * <li>{@link Module::apply_atomic()}</li>
  13.  * <li>{@link Module::apply_atomic_specific()}</li>
  14.  * </ul>
  15.  * 
  16.  * <br><b>Classes API:</b>
  17.  * <ul>
  18.  * <li>{@link Module::add_class()}</li>
  19.  * <li>{@link Module::has_class()}</li>
  20.  * <li>{@link Module::remove_class()}</li>
  21.  * </ul>
  22.  * 
  23.  * <br><b>Views API:</b>
  24.  * <ul>
  25.  * <li>{@link Module::set_view()}</li>
  26.  * <li>{@link Module::has_view()}</li>
  27.  * <li>{@link Module::remove_view()}</li>
  28.  * <li>{@link Module::do_view()}</li>
  29.  * <li>{@link Module::load_views_folder()}</li>
  30.  * <li>{@link Module::load_default_views()}</li>
  31.  * </ul>
  32.  * 
  33.  * <br><b>Search API:</b>
  34.  * <ul>
  35.  * <li>{@link Module::get_module()}</li>
  36.  * <li>{@link Module::get_modules()}</li>
  37.  * <li>{@link Module::get_modules_by_type()}</li>
  38.  * </ul>
  39.  * 
  40.  * @package Elastic Framework
  41.  * @author Daryl Koopersmith
  42.  ***/
  43. class Module extends Object {
  44.     var $id;
  45.     var $type;
  46.     var $classes;
  47.     
  48.     /**
  49.      * Constructs a new Module.
  50.      *
  51.      * @param string $id The id of the module. Must be a unique string.
  52.      * @param string $type Optional. Default, the module's class (lowercase). The type of the module.
  53.      * @author Daryl Koopersmith
  54.      */
  55.     function __construct$id NULL$type NULL {
  56.         ifisset($id) )
  57.             return;
  58.             
  59.         ifisset($type) )
  60.             $type strtolowerget_class$this ) );
  61.             
  62.         $this->id = $id;
  63.         $this->type = $type;
  64.         $this->classes = array();
  65.         $this->add_class$this->type );
  66.         
  67.         $this->load_default_views();
  68.         
  69.         add_filter$this->format_hook'_html_before''admin' )array(&$this'_blank') );
  70.         add_filter$this->format_hook'_html_after''admin' )array(&$this'_blank') );
  71.     }
  72.     
  73.     /**
  74.      * Calls the hooks and generates the output.
  75.      *
  76.      * @author Daryl Koopersmith
  77.      */
  78.     function run({
  79.         $view $this->do_view();
  80.         $prefix elastic_get('module_prefix');
  81.         
  82.         // If view is empty, do not show module.
  83.         if empty$view ) ) {
  84.             $this->do_atomic'_before'$prefix );
  85.             echo $this->apply_atomic'_html_before'$this->_html_before()$prefix );
  86.             echo $this->apply_atomic''$view$prefix );
  87.             echo $this->apply_atomic'_html_after'$this->_html_after()$prefix );
  88.             $this->do_atomic'_after'$prefix );
  89.         }
  90.     }
  91.     
  92.     /**
  93.      * 
  94.      *         H  O  O  K  S     A  P  I
  95.      *
  96.      */
  97.     
  98.     /**
  99.      * Formats a hook for this module.
  100.      *
  101.      * @param string $view 
  102.      * @param string $suffix 
  103.      * @return void 
  104.      * @author Daryl Koopersmith
  105.      */
  106.     function format_hook$suffix ""$view "" {
  107.         return elastic_module_format_hook$this->id . $suffix$view );
  108.     }
  109.     
  110.     /**
  111.      * An interface to {@link elastic_do_atomic()} for an instance of a {@link Module}.
  112.      *
  113.      * @param string $suffix A string appended to the end of the {@link Module::$id}.
  114.      * @return void 
  115.      * @see elastic_do_atomic()
  116.      * @author Daryl Koopersmith
  117.      */
  118.     function do_atomic$suffix '' {
  119.         $preset_args 1;
  120.         $output_args array$this->id . $suffixelastic_get('module_prefix') );
  121.         
  122.         iffunc_num_args($preset_args {
  123.             $args func_get_args();
  124.             array_splice$args0$preset_args$output_args );
  125.             call_user_func_array('elastic_do_atomic'$args);
  126.         else {
  127.             elastic_do_atomic$output_args[0]$output_args[1);
  128.         }
  129.     }
  130.     
  131.     /**
  132.      * An interface to {@link elastic_do_atomic_specific()} for an instance of a {@link Module}.
  133.      *
  134.      * @param string $suffix A string appended to the end of the {@link Module::$id}.
  135.      * @return void 
  136.      * @see elastic_do_atomic_specific()
  137.      * @author Daryl Koopersmith
  138.      */
  139.     function do_atomic_specific$suffix '' {
  140.         $preset_args 1;
  141.         $output_args array$this->id . $suffixelastic_get('module_prefix') );
  142.         
  143.         iffunc_num_args($preset_args {
  144.             $args func_get_args();
  145.             array_splice$args0$preset_args$output_args );
  146.             call_user_func_array('elastic_do_atomic_specific'$args);
  147.         else {
  148.             elastic_do_atomic_specific$output_args[0]$output_args[1);
  149.         }
  150.     }
  151.     
  152.     /**
  153.      * An interface to {@link elastic_apply_atomic()} for an instance of a {@link Module}.
  154.      *
  155.      * @param string $suffix A string appended to the end of the {@link Module::$id}.
  156.      * @param mixed $value The value to be filtered.
  157.      * @return void 
  158.      * @see elastic_apply_atomic()
  159.      * @author Daryl Koopersmith
  160.      */
  161.     function apply_atomic$suffix ''$value {
  162.         $preset_args 2;
  163.         $output_args array$this->id . $suffix$valueelastic_get('module_prefix') );
  164.         
  165.         iffunc_num_args($preset_args {
  166.             $args func_get_args();
  167.             array_splice$args0$preset_args$output_args );
  168.             return call_user_func_array('elastic_apply_atomic'$args);
  169.         else {
  170.             return elastic_apply_atomic$output_args[0]$output_args[1]$output_args[2);
  171.         }
  172.     }
  173.     
  174.     /**
  175.      * An interface to {@link elastic_apply_atomic_specific()} for an instance of a {@link Module}.
  176.      *
  177.      * @param string $suffix A string appended to the end of the {@link Module::$id}.
  178.      * @param mixed $value The value to be filtered.
  179.      * @return void 
  180.      * @see elastic_apply_atomic_specific()
  181.      * @author Daryl Koopersmith
  182.      */
  183.     function apply_atomic_specific$suffix ''$value {
  184.         $preset_args 2;
  185.         $output_args array$this->id . $suffix$valueelastic_get('module_prefix') );
  186.         
  187.         iffunc_num_args($preset_args {
  188.             $args func_get_args();
  189.             array_splice$args0$preset_args$output_args );
  190.             return call_user_func_array('elastic_apply_atomic_specific'$args);
  191.         else {
  192.             return elastic_apply_atomic_specific$output_args[0]$output_args[1]$output_args[2);
  193.         }
  194.     }
  195.     
  196.     /**
  197.      * 
  198.      *         C  L  A  S  S  E  S     A  P  I
  199.      *
  200.      */
  201.  
  202.     function add_class$class {
  203.         $this->classes[$classtrue;
  204.     }
  205.     
  206.     function has_class$class {
  207.         return isset$this->classes[$class);
  208.     }
  209.     
  210.     function remove_class$class {
  211.         if $this->has_class$class ) )
  212.             unset$this->classes[$class);
  213.     }
  214.     
  215.     /**
  216.      * 
  217.      *         V  I  E  W  S     A  P  I
  218.      *
  219.      */
  220.     
  221.     /**
  222.      * Binds a callback to a view. At any time, only one callback will be bound to a view.
  223.      * If the callback is false, the module will not be rendered for the given view.
  224.      *
  225.      * @param string $view 
  226.      * @param string $callback 
  227.      * @param boolean $file Optional. Default false. If true, $callback is a file path, and will be included.
  228.      * @return void 
  229.      * @author Daryl Koopersmith
  230.      */
  231.     function set_view$view$callback$file false {
  232.         $this->remove_view$view );
  233.         
  234.         $hook $this->_format_view_hook$view );
  235.         if$callback === false {
  236.             $callback array(&$this'_blank');
  237.         else if $file {
  238.             $this->_views[$view$callback;
  239.             $callback array(&$this'_load_file_view');
  240.         }
  241.         
  242.         add_action$hook$callback10);
  243.     }
  244.     
  245.     function has_view$view {
  246.         return has_action$this->_format_view_hook$view ) );
  247.     }
  248.  
  249.     /**
  250.      * Removes any view associated with a provided context.
  251.      *
  252.      * @param string $view 
  253.      * @return void 
  254.      * @author Daryl Koopersmith
  255.      */
  256.     function remove_view$view {
  257.         if$this->has_view$view ) )
  258.             remove_all_actions$this->_format_view_hook$view ) );
  259.     }
  260.     
  261.     
  262.     /**
  263.      * Returns the output of the most contextually-specific set view.
  264.      *
  265.      * @return string 
  266.      * @author Daryl Koopersmith
  267.      */
  268.     function do_view({
  269.         ob_start();
  270.         $this->do_atomic_specific$this->_format_view_hook()$this );
  271.         return ob_get_clean();
  272.     }
  273.  
  274.     /**
  275.      * Loads and sets views from a folder.
  276.      * File for global view is named index.php
  277.      *
  278.      * @param string $folder Absolute path to folder
  279.      * @return void 
  280.      * @author Daryl Koopersmith
  281.      */
  282.     function load_views_folder$folder {
  283.         $path trailingslashit$folder $this->type;
  284.         $files glob$path '/*.php');
  285.         
  286.         if$files {
  287.             foreach$files as $file {
  288.                 $view basename$file'.php');
  289.                 $view 'index' === $view '' $view// Global view is named index.php. Can't have a file named '.php'
  290.  
  291.                 $this->set_view$view$filetrue );
  292.             }
  293.         }
  294.     }
  295.  
  296.     /**
  297.      * Loads and sets default views
  298.      *
  299.      * @return void 
  300.      * @author Daryl Koopersmith
  301.      */
  302.     function load_default_views({
  303.         $this->load_views_folderelastic_get_path('fallback-views') );
  304.         $this->load_views_folderelastic_get_path('custom') );
  305.         if elastic_get('has_child') )
  306.             $this->load_views_folderelastic_get_path('custom''child') );
  307.     }
  308.     
  309.     /**
  310.      * Formats the internal view hook.
  311.      *
  312.      * @access private
  313.      * @param string $view Optional. If set, returns a formatted hook. If null, returns the formatted id.
  314.      * @return void 
  315.      * @author Daryl Koopersmith
  316.      */
  317.     function _format_view_hook$view NULL {
  318.         $suffix '_view';
  319.         
  320.         ifisset($view) )
  321.             return $suffix;
  322.         else
  323.             return $this->format_hook$suffix$view );
  324.     }
  325.     
  326.     /**
  327.      * Used in {@link set_view()} to load files.
  328.      *
  329.      * @access private
  330.      * @param string $view 
  331.      * @param string $module 
  332.      * @return void 
  333.      * @author Daryl Koopersmith
  334.      */
  335.     function _load_file_view$view$module {
  336.         include $this->_views[$view];
  337.     }
  338.     
  339.  
  340.     
  341.     /**
  342.      * Returns the html prepended to the module.
  343.      *
  344.      * @access private
  345.      * @todo Add a hook to modify the html.
  346.      * @return string HTML prepended to module.
  347.      * @author Daryl Koopersmith
  348.      */
  349.     function _html_before({
  350.         return "<div id='{$this->id}' class='" . join( ' ', array_keys( $this->classes ) ) "'>";
  351.     }
  352.  
  353.     /**
  354.      * Returns the html appended to the module.
  355.      *
  356.      * @access private
  357.      * @todo Add a hook to modify the html.
  358.      * @return string HTML appended to module.
  359.      * @author Daryl Koopersmith
  360.      */    
  361.     function _html_after() {
  362.         return "</div>";
  363.     }
  364.     
  365.     /**
  366.      * Blank function to be used in conjunction with both filters and actions.
  367.      *
  368.      * @access private
  369.      * @param string $arg 
  370.      * @return string Returns the empty string only if $arg is set.
  371.      * @author Daryl Koopersmith
  372.      */
  373.     function _blank( $arg = NULL ) {
  374.         if ( isset($arg) )
  375.             return '';
  376.     }
  377.     
  378.     
  379.     /**
  380.      * 
  381.      *         S  E  A  R  C  H     A  P  I
  382.      *
  383.      */
  384.     
  385.     /**
  386.      * Function that provides a framework for searching all modules based on a slug and a callback.
  387.      *
  388.      * @param string $slug The value to retrieve.
  389.      * @param callback $condition A function that compares the $slug and each Module.
  390.      * @param string $return Optional. Default 'array'. If 'single', returns the first matched module. If 'selection', returns the matches in a new Selection.
  391.      * @return mixed Return type based on $return value. An array of matched modules. If no matches found, false.
  392.      * @author Daryl Koopersmith
  393.      */
  394.     function get_modules($slug, $condition, $return = 'array') {
  395.         $matches = array();
  396.         
  397.         $stack = array($this);
  398.         while( ! empty($stack) ) {
  399.             $ptr = array_shift( $stack );
  400.             
  401.             if( call_user_func_array( $condition, array( $slug, $ptr ) ) ) {
  402.                 $matches[] = $ptr;
  403.                 if( 'single' === $return )
  404.                     break;
  405.             }
  406.             
  407.             if ( isset($ptr->children) )
  408.                 $stack array_merge($stack$ptr->children);
  409.                 
  410.         }
  411.         
  412.         if( ! empty( $matches ) ) {
  413.             if ( 'single' === $return )
  414.                 return $matches[0];
  415.             else if ( 'selection' === $return )
  416.                  return new Selection( $matches );
  417.             else
  418.                 return $matches;
  419.         } else {
  420.             return false;
  421.         }
  422.     }
  423.     
  424.     /**
  425.      * Get a module by id.
  426.      *
  427.      * @param string $id 
  428.      * @return Module
  429.      * @author Daryl Koopersmith
  430.      */
  431.     function get_module($id) {
  432.         return $this->get_modules($idarray($this'_get_module')'single');
  433.     }
  434.     
  435.     /**
  436.      * Callback for get_module (modules by id).
  437.      *
  438.      * @access private
  439.      * @param string $id 
  440.      * @param string $ptr 
  441.      * @return void
  442.      * @author Daryl Koopersmith
  443.      */
  444.     function _get_module( $id, $ptr ) {
  445.         return ( $id === $ptr->id );
  446.     }
  447.     
  448.     /**
  449.      * Get a module by type.
  450.      *
  451.      * @param string $type
  452.      * @param boolean $selection Optional. Default false. If true, return matches in a new Selection.
  453.      * @return void
  454.      * @author Daryl Koopersmith
  455.      */
  456.     function get_modules_by_type( $type, $selection = false ) {
  457.         return $this->get_modules$typearray($this'_get_modules_by_type')$selection 'selection' 'array' );
  458.     }
  459.     
  460.     /**
  461.      * Callback for get_module_by_type
  462.      * 
  463.      * @access private
  464.      * @param string $type 
  465.      * @param string $ptr 
  466.      * @return void
  467.      * @author Daryl Koopersmith
  468.      */
  469.     function _get_modules_by_type( $type, $ptr ) {
  470.         return ( $type === $ptr->type );
  471.     }
  472. }
  473.  

Documentation generated on Sat, 24 Oct 2009 17:17:45 -0500 by phpDocumentor 1.4.3