nooku is a Public Portfolio from Assembla

Assembla offers free public and private SVN/Git repositories and project hosting with bug/issue tracking and collaboration tools.

Create your own Portfolio or check out other free and subscription products from Assembla that will help accelerate your development projects.

nooku-framework

Commit 4482

User picture
  • Author: johanjanssens
  • 2012-02-10 20:50 (about 2 years ago)

Merged from development

Files Affected

 
44814482
20
class ComDefaultControllerBehaviorCacheable extends KControllerBehaviorAbstract
20
class ComDefaultControllerBehaviorCacheable extends KControllerBehaviorAbstract
21
{
21
{
22
    /**
22
    /**
23
     * List of modules to cache
 
 
24
     *
 
 
25
     * @var    array
 
 
26
     */
 
 
27
    protected $_modules;
 
 
28
    
 
 
29
    /**
 
 
30
     * The cached state of the resource
23
     * The cached state of the resource
31
     * 
24
     * 
32
     * @var boolean
25
     * @var boolean
...
 
...
 
34
    protected $_output = ''; 
27
    protected $_output = ''; 
35
 
28
 
36
    /**
29
    /**
37
     * Constructor
 
 
38
     *
 
 
39
     * @param     object     An optional KConfig object with configuration options.
 
 
40
     */
 
 
41
    public function __construct(KConfig $config)
 
 
42
    {
 
 
43
        parent::__construct($config);
 
 
44
 
 
 
45
        // Set the view identifier
 
 
46
        $this->_modules = KConfig::unbox($config->modules);
 
 
47
    }
 
 
48
 
 
 
49
    /**
 
 
50
     * Initializes the options for the object
 
 
51
     *
 
 
52
     * Called from {@link __construct()} as a first step of object instantiation.
 
 
53
     *
 
 
54
     * @param     object     An optional KConfig object with configuration options
 
 
55
     * @return void
 
 
56
     */
 
 
57
    protected function _initialize(KConfig $config)
 
 
58
    {
 
 
59
        $config->append(array(
 
 
60
            'modules'    => array('toolbar', 'title', 'submenu')
 
 
61
          ));
 
 
62
          
 
 
63
        parent::_initialize($config);
 
 
64
       }
 
 
65
    
 
 
66
    /**
 
 
67
     * Fetch the unrendered view data from the cache
30
     * Fetch the unrendered view data from the cache
68
     *
31
     *
69
     * @param   KCommandContext    A command context object
32
     * @param   KCommandContext    A command context object
70
     * @return     void    
33
     * @return     void    
71
     */
34
     */
72
    protected function _beforeGet(KCommandContext $context)
35
    protected function _beforeControllerGet(KCommandContext $context)
73
    { 
36
    { 
74
        $view   = $this->getView();
37
        $view   = $this->getView();
75
        $cache  = JFactory::getCache($this->_getGroup(), 'output');
38
        $cache  = JFactory::getCache($this->_getGroup(), 'output');
76
        $key    = $this->_getKey();
39
        $key    = $this->_getKey();
77
 
40
            
78
        if($data = $cache->get($key))
41
        if($data = $cache->get($key))
79
        {
42
        {
80
            $data = unserialize($data);
43
            $data = unserialize($data);
...
 
...
 
88
            } 
51
            } 
89
            else $context->result = $data['component'];
52
            else $context->result = $data['component'];
90
 
53
 
91
            //Render the modules
 
 
92
            if(isset($data['modules']))
 
 
93
            {
 
 
94
                foreach($data['modules'] as $name => $content) {
 
 
95
                    JFactory::getDocument()->setBuffer($content, 'modules', $name);
 
 
96
                }
 
 
97
            }  
 
 
98
 
 
 
99
            //Dequeue the commandable behavior from the chain
 
 
100
            if($commandable = $this->getBehavior('commandable')) {
 
 
101
                $this->getCommandChain()->dequeue($commandable);
 
 
102
            }
 
 
103
           
 
 
104
            $this->_output = $context->result;
54
            $this->_output = $context->result;
105
        }
55
        }
106
    }
56
    }
...
 
...
 
111
     * @param   KCommandContext    A command context object
61
     * @param   KCommandContext    A command context object
112
     * @return     void
62
     * @return     void
113
     */
63
     */
114
    protected function _afterGet(KCommandContext $context)
64
    protected function _afterControllerGet(KCommandContext $context)
115
    {
65
    {
116
        if(empty($this->_output))
66
        if(empty($this->_output))
117
        {
67
        {
...
 
...
 
118
            $view   = $this->getView();
68
            $view   = $this->getView();
119
            $cache  = JFactory::getCache($this->_getGroup(), 'output');
69
            $cache  = JFactory::getCache($this->_getGroup(), 'output');
120
            $key    = $this->_getKey();
70
            $key    = $this->_getKey();
121
 
71
      
122
            $data  = array();
72
            $data  = array();
123
 
73
 
124
            //Store the unrendered view output
74
            //Store the unrendered view output
125
            if($view instanceof KViewTemplate) 
75
            if($view instanceof KViewTemplate) {
126
            {
 
 
127
                $data['component'] = (string) $view->getTemplate();
76
                $data['component'] = (string) $view->getTemplate();
 
 
77
            } else {
 
 
78
                $data['component'] = $context->result;
 
 
79
            }
128
 
80
 
129
                $buffer = JFactory::getDocument()->getBuffer();
 
 
130
                if(isset($buffer['modules'])) {       
 
 
131
                    $data['modules'] = array_intersect_key($buffer['modules'], array_flip($this->_modules));
 
 
132
                }
 
 
133
            } 
 
 
134
            else $data['component'] = $context->result;
 
 
135
            
 
 
136
            $cache->store(serialize($data), $key);
81
            $cache->store(serialize($data), $key);
137
        }
82
        }
138
    }
83
    }
...
 
...
 
146
     * @param   KCommandContext    A command context object
91
     * @param   KCommandContext    A command context object
147
     * @return     void
92
     * @return     void
148
     */
93
     */
149
    protected function _afterRead(KCommandContext $context)
94
    protected function _afterControllerRead(KCommandContext $context)
150
    { 
95
    { 
151
        if(!empty($this->_output)) {
96
        if(!empty($this->_output)) {
152
            $context->result = $this->_output;
97
            $context->result = $this->_output;
...
 
...
 
162
     * @param   KCommandContext    A command context object
107
     * @param   KCommandContext    A command context object
163
     * @return     void
108
     * @return     void
164
     */
109
     */
165
    protected function _beforeBrowse(KCommandContext $context)
110
    protected function _beforeControllerBrowse(KCommandContext $context)
166
    {
111
    {
167
        if(!empty($this->_output)) 
112
        if(!empty($this->_output)) 
168
        {
113
        {
...
 
...
 
177
     * @param   KCommandContext    A command context object
122
     * @param   KCommandContext    A command context object
178
     * @return     boolean
123
     * @return     boolean
179
     */
124
     */
180
    protected function _afterAdd(KCommandContext $context)
125
    protected function _afterControllerAdd(KCommandContext $context)
181
    {
126
    {
182
        $status = $context->result->getStatus();
127
        $status = $context->result->getStatus();
183
 
128
 
...
 
...
 
194
     * @param   KCommandContext    A command context object
139
     * @param   KCommandContext    A command context object
195
     * @return     boolean
140
     * @return     boolean
196
     */
141
     */
197
    protected function _afterDelete(KCommandContext $context)
142
    protected function _afterControllerDelete(KCommandContext $context)
198
    {
143
    {
199
        $status = $context->result->getStatus();
144
        $status = $context->result->getStatus();
200
 
145
 
...
 
...
 
211
     * @param   KCommandContext    A command context object
156
     * @param   KCommandContext    A command context object
212
     * @return     boolean
157
     * @return     boolean
213
     */
158
     */
214
    protected function _afterEdit(KCommandContext $context)
159
    protected function _afterControllerEdit(KCommandContext $context)
215
    {
160
    {
216
        $status = $context->result->getStatus();
161
        $status = $context->result->getStatus();
217
 
162
 
44814482
61
         */  
61
         */  
62
 
62
 
63
        $config->append(array(
63
        $config->append(array(
64
            'persistable'    => (KRequest::type() == 'HTTP' && KRequest::get('get.tmpl','cmd') != 'component'),
64
            'persistable' => (KRequest::type() == 'HTTP' && KRequest::get('get.tmpl','cmd') !=
'component'),
 
 
65
            'toolbars'    => array('menubar', $this->getIdentifier()->name),
65
            'limit'          => array('max' => 100, 'default' =>
JFactory::getApplication()->getCfg('list_limit'))
66
            'limit'          => array('max' => 100, 'default' =>
JFactory::getApplication()->getCfg('list_limit'))
66
        ));
67
        ));
67
 
68
 
44814482
28
    protected function  _initialize(KConfig $config) 
28
    protected function  _initialize(KConfig $config) 
29
      {        
29
      {        
30
        $config->append(array(
30
        $config->append(array(
31
            //'behaviors'     =>  array('cacheable')
31
            'toolbars'   => array('menubar', $this->getIdentifier()->name),
32
        ));
32
        ));
33
 
33
 
34
          parent::_initialize($config);
34
          parent::_initialize($config);
44814482
19
 */
19
 */
20
class ComDefaultControllerToolbarDefault extends KControllerToolbarDefault
20
class ComDefaultControllerToolbarDefault extends KControllerToolbarDefault
21
{
21
{
 
 
22
    /**
 
 
23
     * Array of parts to render
 
 
24
     *
 
 
25
     * @var array
 
 
26
     */
 
 
27
    protected $_render;
 
 
28
 
 
 
29
    /**
 
 
30
     * Constructor
 
 
31
     *
 
 
32
     * @param     object     An optional KConfig object with configuration options.
 
 
33
     */
 
 
34
    public function __construct(KConfig $config)
 
 
35
    {
 
 
36
        parent::__construct($config);
 
 
37
 
 
 
38
        $this->_render  = KConfig::unbox($config->render);
 
 
39
    }
 
 
40
 
 
 
41
    /**
 
 
42
     * Initializes the default configuration for the object
 
 
43
     *
 
 
44
     * Called from {@link __construct()} as a first step of object instantiation.
 
 
45
     *
 
 
46
     * @param     object     An optional KConfig object with configuration options.
 
 
47
     * @return void
 
 
48
     */
 
 
49
    protected function _initialize(KConfig $config)
 
 
50
    {
 
 
51
        $config->append(array(
 
 
52
            'render'  => array('toolbar', 'title')
 
 
53
        ));
 
 
54
 
 
 
55
        parent::_initialize($config);
 
 
56
    }
 
 
57
 
 
 
58
    /**
 
 
59
     * Push the toolbar into the view
 
 
60
     * .
 
 
61
     * @param    KEvent    A event object
 
 
62
     */
 
 
63
    public function onBeforeControllerGet(KEvent $event)
 
 
64
    {   
 
 
65
        $event->caller->getView()->toolbar = $this;
 
 
66
    }
 
 
67
 
 
 
68
    /**
 
 
69
     * Add default toolbar commands and set the toolbar title
 
 
70
     * .
 
 
71
     * @param    KEvent    A event object
 
 
72
     */
 
 
73
    public function onAfterControllerRead(KEvent $event)
 
 
74
    { 
 
 
75
        $name = ucfirst($this->getController()->getIdentifier()->name);
 
 
76
 
 
 
77
        if($this->getController()->getModel()->getState()->isUnique()) 
 
 
78
        {        
 
 
79
            $saveable = $this->getController()->canEdit();
 
 
80
            $title    = 'Edit '.$name;
 
 
81
        } 
 
 
82
        else 
 
 
83
        {
 
 
84
            $saveable = $this->getController()->canAdd();
 
 
85
            $title    = 'New '.$name;  
 
 
86
        }
 
 
87
 
 
 
88
        if($saveable)
 
 
89
        {
 
 
90
            $this->setTitle($title)
 
 
91
                 ->addCommand('save')
 
 
92
                 ->addCommand('apply');
 
 
93
        }
 
 
94
 
 
 
95
        $this->addCommand('cancel',  array('attribs' => array('data-novalidate' => 'novalidate')));       
 
 
96
    }
 
 
97
 
22
    /**
98
    /**
 
 
99
     * Add default toolbar commands
 
 
100
     * .
 
 
101
     * @param    KEvent    A event object
 
 
102
     */
 
 
103
    public function onAfterControllerBrowse(KEvent $event)
 
 
104
    {    
 
 
105
        if($this->getController()->canAdd()) 
 
 
106
        {
 
 
107
            $identifier = $this->getController()->getIdentifier();
 
 
108
            $config     = array('attribs' => array(
 
 
109
                            'href' => JRoute::_(
'index.php?option=com_'.$identifier->package.'&view='.$identifier->name)
 
 
110
                          ));
 
 
111
 
 
 
112
            $this->addCommand('new', $config);
 
 
113
        }
 
 
114
 
 
 
115
        if($this->getController()->canDelete()) {
 
 
116
            $this->addCommand('delete');    
 
 
117
        }
 
 
118
    }
 
 
119
 
 
 
120
    /**
23
     * Enable toolbar command
121
     * Enable toolbar command
24
     * 
122
     * 
25
     * @param   object  A KControllerToolbarCommand object
123
     * @param   object  A KControllerToolbarCommand object
44814482
10
 */
10
 */
11
 
11
 
12
/**
12
/**
13
 * Default Menubar
13
 * Default Menubar 
14
.*
14
.*
15
 * @author      Johan Janssens <johan@nooku.org>
15
 * @author      Johan Janssens <johan@nooku.org>
16
 * @category    Nooku
16
 * @category    Nooku
...
 
...
 
17
 * @package     Nooku_Components
17
 * @package     Nooku_Components
18
 * @subpackage  Default
18
 * @subpackage  Default
19
 */
19
 */
20
class ComDefaultControllerToolbarMenubar extends KControllerToolbarDefault
20
class ComDefaultControllerToolbarMenubar extends KControllerToolbarAbstract
21
{
21
{
 
 
22
    /**
 
 
23
     * Push the menubar into the view
 
 
24
     * .
 
 
25
     * @param    KEvent    A event object
 
 
26
     */
 
 
27
    public function onBeforeControllerGet(KEvent $event)
 
 
28
    {   
 
 
29
        $event->caller->getView()->menubar = $this;
 
 
30
    }
 
 
31
 
22
     /**
32
     /**
23
     * Add a command
33
     * Add a command
24
     * 
34
     * 
...
 
...
 
63
                foreach($xml->administration->submenu->children() as $menu)
73
                foreach($xml->administration->submenu->children() as $menu)
64
                {
74
                {
65
                    $view = (string)$menu['view'];
75
                    $view = (string)$menu['view'];
 
 
76
 
 
 
77
                    if(!isset($menu['href'])) {
 
 
78
                       $menu['href'] = 'index.php?option=com_'.$package.'&view='.$view;
 
 
79
                    }
 
 
80
 
 
 
81
                    if(!isset($menu['active'])) {
 
 
82
                        $menu['active'] = ($name == KInflector::singularize($view));
 
 
83
                    }
66
 
84
 
67
                    $this->addCommand(JText::_((string)$menu), array(
85
                    $this->addCommand(JText::_((string)$menu), array(
68
                        'href'   => JRoute::_('index.php?option=com_'.$package.'&view='.$view),
86
                        'href'   => JRoute::_($menu['href']),
69
                        'active' => ($name == KInflector::singularize($view))
87
                        'active' => (string) $menu['active']
70
                    ));
88
                    ));
71
                }
89
                }
72
            }
90
            }
44814482
10
 */
10
 */
11
 
11
 
12
/**
12
/**
13
 * Default Dispatcher
13
 * Default Dispatcher Class
14
.*
14
.*
15
 * @author      Johan Janssens <johan@nooku.org>
15
 * @author      Johan Janssens <johan@nooku.org>
16
 * @category    Nooku
16
 * @category    Nooku
...
 
...
 
77
    protected function _actionDispatch(KCommandContext $context)
77
    protected function _actionDispatch(KCommandContext $context)
78
    {
78
    {
79
        //Redirect if no view information can be found in the request
79
        //Redirect if no view information can be found in the request
80
        if(!KRequest::has('get.view')) 
80
        if(!$this->getRequest()->view) 
81
        {
81
        {
82
            $package = $this->getIdentifier()->package;
82
            $route    = $this->getController()->getView()->getRoute();   
83
            $view    = $this->getController()->getView()->getName();
 
 
84
            $route = JRoute::_('index.php?option=com_'.$package.'&view='.$view, false);
 
 
85
            
 
 
86
            JFactory::getApplication()->redirect($route);
83
            JFactory::getApplication()->redirect($route);
87
        }
84
        }
88
 
85
 
44814482
64
                    'params'    => '',    
64
                    'params'    => '',    
65
                    'title'        => '',
65
                    'title'        => '',
66
                    'class'        => '',
66
                    'class'        => '',
67
                    'prepend'   => true
67
                    'content'   => 'prepend'
68
                );
68
                );
69
 
69
 
70
                $attributes = array_merge($attributes, $this->_parseAttributes($matches[1][$key])); 
70
                $attributes = array_merge($attributes, $this->_parseAttributes($matches[1][$key])); 
...
 
...
 
81
                $module->user      = 0;
81
                $module->user      = 0;
82
                $module->module    = 'mod_dynamic';
82
                $module->module    = 'mod_dynamic';
83
 
83
 
 
 
84
                //Store the module for rendering
84
                JFactory::getDocument()->modules[$attributes['position']][] = $module;
85
                JFactory::getDocument()->modules[$attributes['position']][] = $module;
85
            }
86
            }
86
        }
87
        }
...
 
...
 
111
        {
112
        {
112
            foreach($this->_doc->modules[$position] as $module) 
113
            foreach($this->_doc->modules[$position] as $module) 
113
            { 
114
            { 
114
                if($module->attribs['prepend']) {
115
                switch($module->attribs['content'])
115
                    array_push($modules, $module);   
116
                {
116
                } else {
117
                    case 'append'  :  
117
                    array_unshift($modules, $module);
118
                        array_unshift($modules, $module); 
 
 
119
                        break;
 
 
120
                         
 
 
121
                    case 'replace' :
 
 
122
                         unset($modules);
 
 
123
                        $modules[] = $module;
 
 
124
                        break;
 
 
125
                        
 
 
126
                    case 'prepend' :    
 
 
127
                    default        :
 
 
128
                        array_push($modules, $module); 
118
                }
129
                }
119
            }
130
            }
120
        }
131
        }
44814482
29
     * @see     http://developer.yahoo.com/ypatterns/navigation/pagination/
29
     * @see     http://developer.yahoo.com/ypatterns/navigation/pagination/
30
     */
30
     */
31
    public function pagination($config = array())
31
    public function pagination($config = array())
32
    {
32
    { 
33
        $config = new KConfig($config);
33
        $config = new KConfigPaginator($config);
34
        $config->append(array(
34
        $config->append(array(
35
            'total'      => 0,
35
            'total'      => 0,
36
            'display'    => 4,
36
            'display'    => 4,
...
 
...
 
39
            'show_limit' => true,
39
            'show_limit' => true,
40
            'show_count' => true
40
            'show_count' => true
41
        ));
41
        ));
42
 
42
         
43
        $this->_initialize($config);
 
 
44
        
 
 
45
        $html   = '<div class="container">';
43
        $html   = '<div class="container">';
46
        $html  .= '<div class="pagination">';
44
        $html  .= '<div class="pagination">';
47
        if($config->show_limit) {
45
        if($config->show_limit) {
48
            $html .= '<div class="limit">'.JText::_('Display NUM').'
'.$this->limit($config).'</div>';
46
            $html .= '<div class="limit">'.JText::_('Display NUM').'
'.$this->limit($config).'</div>';
49
        }
47
        }
50
        $html .=  $this->_pages($this->_items($config));
48
        $html .=  $this->pages($config);
51
        if($config->show_count) {
49
        if($config->show_count) {
52
            $html .= '<div class="limit"> '.JText::_('Page').' '.$config->current.'
'.JText::_('of').' '.$config->count.'</div>';
50
            $html .= '<div class="limit"> '.JText::_('Page').' '.$config->current.'
'.JText::_('of').' '.$config->count.'</div>';
53
        }
51
        }
...
 
...
 
63
     * This function is overriddes the default behavior to render the links in the khepri template
61
     * This function is overriddes the default behavior to render the links in the khepri template
64
     * backend style.
62
     * backend style.
65
     *
63
     *
66
     * @param   araay   An array of page data
64
     * @param   array   An optional array with configuration options
67
     * @return  string  Html
65
     * @return  string  Html
68
     */
66
     */
69
    protected function _pages($pages)
67
    public function pages($config = array())
70
    {
68
    {
71
        $class = $pages['first']->active ? '' : 'off';
69
        $config = new KConfigPaginator($config);
72
        $html  = '<div class="button2-right '.$class.'"><div class="start">'.$this->_link($pages['first'], 'First').'</div></div>';
70
        $config->append(array(
 
 
71
            'total'      => 0,
 
 
72
            'display'    => 4,
 
 
73
            'offset'     => 0,
 
 
74
            'limit'         => 0,
 
 
75
            'attribs'    => array(),
 
 
76
        ));
 
 
77
       
 
 
78
        $class = $config->pages->first->active ? '' : 'off';
 
 
79
        $html  = '<div class="button2-right '.$class.'"><div class="start">'.$this->link($config->pages->first).'</div></div>';
73
 
80
 
74
        $class = $pages['previous']->active ? '' : 'off';
81
        $class = $config->pages->prev->active ? '' : 'off';
75
        $html  .= '<div class="button2-right '.$class.'"><div class="prev">'.$this->_link($pages['previous'], 'Prev').'</div></div>';
82
        $html  .= '<div class="button2-right '.$class.'"><div class="prev">'.$this->link($config->pages->prev).'</div></div>';
76
 
83
 
77
        $html  .= '<div class="button2-left"><div class="page">';
84
        $html  .= '<div class="button2-left"><div class="page">';
78
        foreach($pages['pages'] as $page) {
85
        foreach($config->pages->offsets as $offset) {
79
            $html .= $this->_link($page, $page->page);
86
            $html .= $this->link($offset);
80
        }
87
        }
81
        $html .= '</div></div>';
88
        $html .= '</div></div>';
82
 
89
 
83
        $class = $pages['next']->active ? '' : 'off';
90
        $class = $config->pages->next->active ? '' : 'off';
84
        $html  .= '<div class="button2-left '.$class.'"><div class="next">'.$this->_link($pages['next'], 'Next').'</div></div>';
91
        $html  .= '<div class="button2-left '.$class.'"><div class="next">'.$this->link($config->pages->next).'</div></div>';
85
 
92
 
86
        $class = $pages['last']->active ? '' : 'off';
93
        $class = $config->pages->last->active ? '' : 'off';
87
        $html  .= '<div class="button2-left '.$class.'"><div class="end">'.$this->_link($pages['last'], 'Last').'</div></div>';
94
        $html  .= '<div class="button2-left '.$class.'"><div class="end">'.$this->link($config->pages->last).'</div></div>';
88
 
95
 
89
        return $html;
96
        return $html;
90
    }
97
    }
91
    
 
 
92
    protected function _link($page, $title)
 
 
93
    {
 
 
94
        $url   = clone KRequest::url();
 
 
95
        $query = $url->getQuery(true);
 
 
96
 
 
 
97
        //For compatibility with Joomla use limitstart instead of offset
 
 
98
        $query['limit']      = $page->limit;
 
 
99
        $query['limitstart'] = $page->offset;   
 
 
100
        
 
 
101
        $url->setQuery($query);
 
 
102
 
 
 
103
        $class = $page->current ? 'class="active"' : '';
 
 
104
 
 
 
105
        if($page->active && !$page->current) {
 
 
106
            $html = '<a href="'.$url.'" '.$class.'>'.JText::_($title).'</a>';
 
 
107
        } else {
 
 
108
            $html = '<span '.$class.'>'.JText::_($title).'</span>';
 
 
109
        }
 
 
110
 
 
 
111
        return $html;
 
 
112
    }
 
 
113
}
98
}
44814482
44
    protected function _initialize(KConfig $config)
44
    protected function _initialize(KConfig $config)
45
    {
45
    {
46
        $config->append(array(
46
        $config->append(array(
47
            'layout' => KInflector::isSingular($this->getName()) ? 'form' : 'default'
47
            'layout'           => KInflector::isSingular($this->getName()) ? 'form' : 'default',
 
 
48
            'template_filters' => array('module'),
48
        ));
49
        ));
49
 
50
 
50
        parent::_initialize($config);
51
        parent::_initialize($config);
44814482
42
 
42
 
43
        parent::__construct($config);
43
        parent::__construct($config);
44
 
44
 
45
        $this->_dispatcher = $config->dispatcher;
45
         if(is_null($config->event_dispatcher)) {
 
 
46
            throw new KMixinException('event_dispatcher [KEventDispatcher] option is required');
 
 
47
        }
 
 
48
        
 
 
49
        $this->_event_dispatcher = $config->event_dispatcher;
46
    }
50
    }
47
 
51
 
48
    /**
52
    /**
...
 
...
 
56
    protected function _initialize(KConfig $config)
60
    protected function _initialize(KConfig $config)
57
    {
61
    {
58
        $config->append(array(
62
        $config->append(array(
59
            'dispatcher'   => $this->getService('koowa:event.dispatcher')
63
            'event_dispatcher'   => null
60
        ));
64
        ));
61
 
65
 
62
        parent::_initialize($config);
66
        parent::_initialize($config);
...
 
...
 
87
        $parts = explode('.', $name);   
91
        $parts = explode('.', $name);   
88
        $event = 'on'.ucfirst(array_shift($parts)).ucfirst($type).KInflector::implode($parts);
92
        $event = 'on'.ucfirst(array_shift($parts)).ucfirst($type).KInflector::implode($parts);
89
 
93
 
90
        $this->_dispatcher->dispatchEvent($event, clone($context));
94
        $this->_event_dispatcher->dispatchEvent($event, clone($context));
91
 
95
 
92
        return true;
96
        return true;
93
    }
97
    }
44814482
33
     *
33
     *
34
     * @var array
34
     * @var array
35
     */
35
     */
36
    protected $_actions;
36
    protected $_actions = array();
37
 
37
 
38
    /**
38
    /**
39
     * Has the controller been dispatched
39
     * Has the controller been dispatched
...
 
...
 
49
     */
49
     */
50
    protected $_request = null;
50
    protected $_request = null;
51
 
51
 
52
    /**
 
 
53
     * List of behaviors
 
 
54
     * 
 
 
55
     * Associative array of behaviors, where key holds the behavior identifier string
 
 
56
     * and the value is an identifier object.
 
 
57
     * 
 
 
58
     * @var    array
 
 
59
     */
 
 
60
    protected $_behaviors = array();
 
 
61
 
 
 
62
    /**
52
    /**
63
     * Constructor.
53
     * Constructor.
64
     *
54
     *
...
 
...
 
71
 
61
 
72
        parent::__construct($config);
62
        parent::__construct($config);
73
 
63
 
74
         //Set the dispatched state
64
        //Set the dispatched state
75
        $this->_dispatched = $config->dispatched;
65
        $this->_dispatched = $config->dispatched;
76
 
66
 
77
        // Mixin the command chain
67
        //Set the mixer in the config
78
        $this->mixin(new KMixinCommandchain($config->append(array('mixer' => $this))));
68
        $config->mixer = $this;
79
 
69
 
80
        // Set the table behaviors
70
        // Mixin the command interface
81
        if(!empty($config->behaviors)) {
71
        $this->mixin(new KMixinCommand($config));
82
            $this->addBehavior($config->behaviors);
72
 
83
        } 
73
        // Mixin the behavior interface
84
 
74
        $this->mixin(new KMixinBehavior($config));
 
 
75
            
85
        //Set the request
76
        //Set the request
86
        $this->setRequest((array) KConfig::unbox($config->request));
77
        $this->setRequest((array) KConfig::unbox($config->request));
87
    }
78
    }
...
 
...
 
97
    protected function _initialize(KConfig $config)
88
    protected function _initialize(KConfig $config)
98
    {
89
    {
99
        $config->append(array(
90
        $config->append(array(
100
            'command_chain'     =>  new KCommandChain(),
91
            'command_chain'     => $this->getService('koowa:command.chain'),
101
            'dispatch_events'   => true,
92
            'dispatch_events'   => true,
 
 
93
            'event_dispatcher'  => $this->getService('koowa:event.dispatcher'),
102
            'enable_callbacks'  => true,
94
            'enable_callbacks'  => true,
103
            'dispatched'        => false,
95
            'dispatched'        => false,
104
            'request'            => null,
96
            'request'            => null,
...
 
...
 
147
            $method = '_action'.ucfirst($command);
139
            $method = '_action'.ucfirst($command);
148
 
140
 
149
            if(!method_exists($this, $method)) 
141
            if(!method_exists($this, $method)) 
150
            {
142
            {             
151
                //Lazy mix behaviors
 
 
152
                if(!isset($this->_mixed_methods[$method]))
 
 
153
                {
 
 
154
                    foreach($this->getBehaviors() as $behavior) {
 
 
155
                        $this->mixin($behavior);
 
 
156
                    }
 
 
157
                }
 
 
158
               
 
 
159
                if(isset($this->_mixed_methods[$command])) {      
143
                if(isset($this->_mixed_methods[$command])) {      
160
                    $context->result = $this->_mixed_methods[$command]->execute('action.'.$command, $context);
144
                    $context->result = $this->_mixed_methods[$command]->execute('action.'.$command, $context);
161
                } else {
145
                } else {
...
 
...
 
184
        return $context->result;
168
        return $context->result;
185
    }
169
    }
186
 
170
 
 
 
171
    /**
 
 
172
     * Mixin an object 
 
 
173
     *
 
 
174
     * @param   object  An object that implements KMinxInterface
 
 
175
     * @return  KObject
 
 
176
     */
 
 
177
    public function mixin(KMixinInterface $object)
 
 
178
    {
 
 
179
        if($object instanceof KControllerBehaviorAbstract) 
 
 
180
        {
 
 
181
            foreach($object->getMethods() as $method)
 
 
182
            {
 
 
183
                if(substr($method, 0, 7) == '_action') {
 
 
184
                    $this->_actions[] = strtolower(substr($method, 7));
 
 
185
                }  
 
 
186
            }
 
 
187
 
 
 
188
            $this->_actions = array_unique(array_merge($this->_actions, array_keys($this->_action_map)));
 
 
189
        }
 
 
190
 
 
 
191
        return parent::mixin($object);   
 
 
192
    }
 
 
193
 
187
    /**
194
    /**
188
     * Gets the available actions in the controller.
195
     * Gets the available actions in the controller.
189
     *
196
     *
190
     * @return  array Array[i] of action names.
197
     * @return  array Array[i] of action names.
191
     */
198
     */
192
    public function getActions($reload = false)
199
    public function getActions()
193
    {
200
    {
194
        if(!$this->_actions || $reload)
201
        if(!$this->_actions)
195
        {
202
        {
196
            $this->_actions = array();
203
            $this->_actions = array();
197
 
204
 
...
 
...
 
202
                }  
209
                }  
203
            }
210
            }
204
 
211
 
205
            foreach($this->_behaviors as $behavior) 
 
 
206
            {
 
 
207
                foreach($behavior->getMethods() as $method)
 
 
208
                {
 
 
209
                    if(substr($method, 0, 7) == '_action') {
 
 
210
                        $this->_actions[] = strtolower(substr($method, 7));
 
 
211
                    }  
 
 
212
                }
 
 
213
            }
 
 
214
            
 
 
215
            $this->_actions = array_unique(array_merge($this->_actions, array_keys($this->_action_map)));
212
            $this->_actions = array_unique(array_merge($this->_actions, array_keys($this->_action_map)));
216
        }
213
        }
217
 
214
 
...
 
...
 
243
 
240
 
244
        return $this;
241
        return $this;
245
    }
242
    }
246
    
243
 
247
    /**
 
 
248
     * Check if a behavior exists
 
 
249
     *
 
 
250
     * @param     string    The name of the behavior
 
 
251
     * @return  boolean    TRUE if the behavior exists, FALSE otherwise
 
 
252
     */
 
 
253
    public function hasBehavior($behavior)
 
 
254
    { 
 
 
255
        return isset($this->_behaviors[$behavior]); 
 
 
256
    }
 
 
257
    
 
 
258
    /**
 
 
259
     * Add one or more behaviors to the controller
 
 
260
     *
 
 
261
     * @param   array   Array of one or more behaviors to add.
 
 
262
     * @return  KControllerAbstract
 
 
263
     */
 
 
264
    public function addBehavior($behaviors)
 
 
265
    { 
 
 
266
        $behaviors = (array) KConfig::unbox($behaviors);
 
 
267
         
 
 
268
        foreach($behaviors as $behavior)
 
 
269
        {
 
 
270
            if (!($behavior instanceof KControllerBehaviorInterface)) { 
 
 
271
                $behavior = $this->getBehavior($behavior);
 
 
272
            }
 
 
273
               
 
 
274
            //Add the behaviors
 
 
275
            $this->_behaviors[$behavior->getIdentifier()->name] = $behavior;
 
 
276
            
 
 
277
            if($this->getCommandChain()->enqueue($behavior)) {
 
 
278
                $this->_actions = null; //reset the actions
 
 
279
            }
 
 
280
        }
 
 
281
        
 
 
282
        return $this;
 
 
283
    }
 
 
284
   
 
 
285
    /**
 
 
286
     * Get a behavior by identifier
 
 
287
     *
 
 
288
     * @return KControllerBehaviorAbstract
 
 
289
     */
 
 
290
    public function getBehavior($behavior, $config = array())
 
 
291
    {
 
 
292
       if(!($behavior instanceof KServiceIdentifier))
 
 
293
       {
 
 
294
            //Create the complete identifier if a partial identifier was passed
 
 
295
           if(is_string($behavior) && strpos($behavior, '.') === false )
 
 
296
           {
 
 
297
               $identifier = clone $this->getIdentifier();
 
 
298
               $identifier->path = array('controller', 'behavior');
 
 
299
               $identifier->name = $behavior;
 
 
300
           }
 
 
301
           else $identifier = $this->getIdentifier($behavior);
 
 
302
       }
 
 
303
           
 
 
304
       if(!isset($this->_behaviors[$identifier->name])) 
 
 
305
       {
 
 
306
           $behavior = $this->getService($identifier, array_merge($config, array('mixer' => $this)));
 
 
307
           
 
 
308
           //Check the behavior interface
 
 
309
           if(!($behavior instanceof KControllerBehaviorInterface)) {
 
 
310
               throw new KControllerBehaviorException("Controller behavior $identifier does not implement KControllerBehaviorInterface");
 
 
311
           }
 
 
312
       } 
 
 
313
       else $behavior = $this->_behaviors[$identifier->name];
 
 
314
       
 
 
315
       return $behavior;
 
 
316
    }
 
 
317
    
 
 
318
    /**
244
    /**
319
     * Gets the behaviors of the table
 
 
320
     *
 
 
321
     * @return array    An asscociate array of table behaviors, keys are the behavior names
 
 
322
     */
 
 
323
    public function getBehaviors()
 
 
324
    {
 
 
325
        return $this->_behaviors;
 
 
326
    }
 
 
327
   
 
 
328
    /**
 
 
329
     * Register (map) an action to a method in the class.
245
     * Register (map) an action to a method in the class.
330
     *
246
     *
331
     * @param   string  The action.
247
     * @param   string  The action.
...
 
...
 
342
        }    
258
        }    
343
 
259
 
344
        //Force reload of the actions
260
        //Force reload of the actions
345
        $this->getActions(true);
261
        $this->_actions = array_unique(array_merge($this->_actions, array_keys($this->_action_map)));
346
 
262
 
347
        return $this;
263
        return $this;
348
    }
264
    }
...
 
...
 
386
     * @see execute()
302
     * @see execute()
387
     */
303
     */
388
    public function __call($method, $args)
304
    public function __call($method, $args)
389
    {
305
    {  
390
        //Handle action alias method
306
        //Handle action alias method
391
        if(in_array($method, $this->getActions())) 
307
        if(in_array($method, $this->getActions())) 
392
        {
308
        {
...
 
...
 
401
                $context->result = false;
317
                $context->result = false;
402
            } 
318
            } 
403
            else $context = $data;
319
            else $context = $data;
404
            
320
 
405
            //Execute the action
321
            //Execute the action
406
            return $this->execute($method, $context);
322
            return $this->execute($method, $context);
407
        }
323
        }
...
 
...
 
411
 
327
 
412
        if($parts[0] == 'is' && isset($parts[1]))
328
        if($parts[0] == 'is' && isset($parts[1]))
413
        {
329
        {
414
            //Lazy mix behaviors
330
            if(!isset($this->_mixed_methods[$method])) { 
415
            $behavior = strtolower($parts[1]);
 
 
416
            
 
 
417
            if(!isset($this->_mixed_methods[$method]))
 
 
418
            { 
 
 
419
                if($this->hasBehavior($behavior)) 
 
 
420
                {
 
 
421
                    $this->mixin($this->getBehavior($behavior));
 
 
422
                    return true;
 
 
423
                }
 
 
424
          
 
 
425
                return false;
331
                return false;
426
            }
332
            }
427
 
333
 
44814482
16
 * @package     Koowa_Controller
16
 * @package     Koowa_Controller
17
 * @subpackage     Behavior
17
 * @subpackage     Behavior
18
 */
18
 */
19
abstract class KControllerBehaviorAbstract extends KMixinAbstract implements KControllerBehaviorInterface
19
abstract class KControllerBehaviorAbstract extends KBehaviorAbstract
20
{
20
{
21
    /**
21
    /**
22
     * The behavior priority
 
 
23
     *
 
 
24
     * @var integer
 
 
25
     */
 
 
26
    protected $_priority;
 
 
27
    
 
 
28
    /**
 
 
29
     * The service identifier
 
 
30
     *
 
 
31
     * @var KServiceIdentifier
 
 
32
     */
 
 
33
    private $__service_identifier;
 
 
34
    
 
 
35
    /**
 
 
36
     * The service container
 
 
37
     *
 
 
38
     * @var KServiceInterface
 
 
39
     */
 
 
40
    private $__service_container;
 
 
41
    
 
 
42
    /**
 
 
43
     * Constructor.
 
 
44
     *
 
 
45
     * @param     object     An optional KConfig object with configuration options
 
 
46
     */
 
 
47
    public function __construct( KConfig $config = null) 
 
 
48
    { 
 
 
49
        //Set the service container
 
 
50
        if(isset($config->service_container)) {
 
 
51
            $this->__service_container = $config->service_container;
 
 
52
        }
 
 
53
        
 
 
54
        //Set the service identifier
 
 
55
        if(isset($config->service_identifier)) {
 
 
56
            $this->__service_identifier = $config->service_identifier;
 
 
57
        }
 
 
58
        
 
 
59
        parent::__construct($config);
 
 
60
        
 
 
61
        $this->_priority = $config->priority;
 
 
62
        
 
 
63
        //Automatically mixin the behavior
 
 
64
        if($config->auto_mixin) {
 
 
65
            $this->mixin($this);
 
 
66
        }
 
 
67
    }
 
 
68
    
 
 
69
    /**
 
 
70
     * Initializes the options for the object
 
 
71
     *
 
 
72
     * Called from {@link __construct()} as a first step of object instantiation.
 
 
73
     *
 
 
74
     * @param     object     An optional KConfig object with configuration options
 
 
75
     * @return void
 
 
76
     */
 
 
77
    protected function _initialize(KConfig $config)
 
 
78
    {
 
 
79
        $config->append(array(
 
 
80
            'priority'   => KCommand::PRIORITY_NORMAL,
 
 
81
            'auto_mixin' => false
 
 
82
          ));
 
 
83
          
 
 
84
        parent::_initialize($config);
 
 
85
       }
 
 
86
    
 
 
87
    /**
 
 
88
     * Get the priority of a behavior
 
 
89
     *
 
 
90
     * @return    integer The command priority
 
 
91
     */
 
 
92
      public function getPriority()
 
 
93
      {
 
 
94
          return $this->_priority;
 
 
95
      }
 
 
96
    
 
 
97
    /**
 
 
98
     * Command handler
22
     * Command handler
99
     * 
23
     * 
100
     * This function transmlated the command name to a command handler function of 
24
     * This function transmlated the command name to a command handler function of 
...
 
...
 
107
     */
31
     */
108
    public function execute( $name, KCommandContext $context) 
32
    public function execute( $name, KCommandContext $context) 
109
    {
33
    {
110
        $identifier = clone $context->caller->getIdentifier();
34
        $this->setMixer($context->caller);
111
        $type       = array_pop($identifier->path);
35
 
112
    
 
 
113
        $parts  = explode('.', $name);
36
        $parts  = explode('.', $name);
114
        $method = '_'.$parts[0].ucfirst($parts[1]);
37
        if($parts[0] == 'action') 
 
 
38
        {
 
 
39
            $method = '_action'.ucfirst($parts[1]);
115
 
40
 
116
        if(method_exists($this, $method)) 
41
            if(method_exists($this, $method)) {
117
        {
42
                return $this->$method($context);
118
            $this->setMixer($context->caller);
43
            }
119
            return $this->$method($context);
 
 
120
        }
44
        }
121
 
45
 
122
        return true;
46
        return parent::execute($name, $context);
123
    }
47
    }
124
     
 
 
125
    /**
 
 
126
     * Get an object handle
 
 
127
     * 
 
 
128
     * This function only returns a valid handle if one or more command handler 
 
 
129
     * functions are defined. A commend handler function needs to follow the 
 
 
130
     * following format : '_afterX[Event]' or '_beforeX[Event]' to be 
 
 
131
     * recognised.
 
 
132
     * 
 
 
133
     * @return string A string that is unique, or NULL
 
 
134
     * @see execute()
 
 
135
     */
 
 
136
    public function getHandle()
 
 
137
    {
 
 
138
        $methods = $this->getMethods();
 
 
139
        
 
 
140
        foreach($methods as $method) 
 
 
141
        {
 
 
142
            if(substr($method, 0, 7) == '_before' || substr($method, 0, 6) == '_after') {
 
 
143
                return parent::getHandle(); 
 
 
144
            }
 
 
145
        }
 
 
146
        
 
 
147
        return null;
 
 
148
    }
 
 
149
    
 
 
150
    /**
 
 
151
     * Get the methods that are available for mixin based 
 
 
152
     * 
 
 
153
     * This function also dynamically adds a function of format is[Behavior] 
 
 
154
     * to allow client code to check if the behavior is callable. 
 
 
155
     * 
 
 
156
     * @param object The mixer requesting the mixable methods. 
 
 
157
     * @return array An array of methods
 
 
158
     */
 
 
159
    public function getMixableMethods(KObject $mixer = null)
 
 
160
    {
 
 
161
        $methods   = parent::getMixableMethods($mixer);
 
 
162
        $methods[] = 'is'.ucfirst($this->getIdentifier()->name);
 
 
163
          
 
 
164
        foreach($this->getMethods() as $method)
 
 
165
        {
 
 
166
            if(substr($method, 0, 7) == '_action') {
 
 
167
                $methods[] = strtolower(substr($method, 7));
 
 
168
            }  
 
 
169
        }
 
 
170
     
 
 
171
        return array_diff($methods, array('execute', 'getIdentifier', 'getPriority', 'getHandle', 'getService', 'getIdentifier'));
 
 
172
    }
 
 
173
    
 
 
174
    /**
 
 
175
     * Get an instance of a class based on a class identifier only creating it
 
 
176
     * if it doesn't exist yet.
 
 
177
     *
 
 
178
     * @param    string|object    The class identifier or identifier object
 
 
179
     * @param    array              An optional associative array of configuration settings.
 
 
180
     * @throws    KServiceServiceException
 
 
181
     * @return    object          Return object on success, throws exception on failure
 
 
182
     * @see     KObjectServiceable
 
 
183
     */
 
 
184
    final public function getService($identifier, array $config = array())
 
 
185
    {
 
 
186
        return $this->__service_container->get($identifier, $config);
 
 
187
    }
 
 
188
    
 
 
189
    /**
 
 
190
     * Gets the service identifier.
 
 
191
     *
 
 
192
     * @return    KServiceIdentifier
 
 
193
     * @see     KObjectServiceable
 
 
194
     */
 
 
195
    final public function getIdentifier($identifier = null)
 
 
196
    {
 
 
197
        if(isset($identifier)) {
 
 
198
            $result = $this->__service_container->getIdentifier($identifier);
 
 
199
        } else {
 
 
200
            $result = $this->__service_identifier; 
 
 
201
        }
 
 
202
        
 
 
203
        return $result;
 
 
204
    }
 
 
205
}
48
}
44814482
17
 * @package     Koowa_Controller
17
 * @package     Koowa_Controller
18
 * @subpackage  Behavior
18
 * @subpackage  Behavior
19
 */
19
 */
20
class KControllerBehaviorException extends KControllerException {}
20
class KControllerBehaviorException extends KBehaviorException {}
44814482
28
     * @param     KCommandContext        The active command context
28
     * @param     KCommandContext        The active command context
29
     * @return     void
29
     * @return     void
30
     */
30
     */
31
    protected function _beforeBrowse(KCommandContext $context)
31
    protected function _beforeControllerBrowse(KCommandContext $context)
32
    {
32
    {
33
        // Built the session identifier based on the action
33
        // Built the session identifier based on the action
34
        $identifier  = $this->getModel()->getIdentifier().'.'.$context->action;
34
        $identifier  = $this->getModel()->getIdentifier().'.'.$context->action;
...
 
...
 
47
     * @param     KCommandContext        The active command context
47
     * @param     KCommandContext        The active command context
48
     * @return     void
48
     * @return     void
49
     */
49
     */
50
    protected function _afterBrowse(KCommandContext $context)
50
    protected function _afterControllerBrowse(KCommandContext $context)
51
    {
51
    {
52
        $model  = $this->getModel();
52
        $model  = $this->getModel();
53
        $state  = $model->get();
53
        $state  = $model->getState();
54
 
54
        
 
 
55
        $vars = array();
 
 
56
        foreach($state->toArray(false) as $var) 
 
 
57
        {
 
 
58
            if(!$var->unique) {
 
 
59
                $vars[$var->name] = $var->value;
 
 
60
            }  
 
 
61
        }
 
 
62
        
55
        // Built the session identifier based on the action
63
        // Built the session identifier based on the action
56
        $identifier  = $model->getIdentifier().'.'.$context->action;
64
        $identifier  = $model->getIdentifier().'.'.$context->action;
57
 
65
 
...
 
...
 
59
        KRequest::set('session.'.$identifier, null);
67
        KRequest::set('session.'.$identifier, null);
60
 
68
 
61
        //Set the state in the session
69
        //Set the state in the session
62
        KRequest::set('session.'.$identifier, $state);
70
        KRequest::set('session.'.$identifier, $vars);
63
    }
71
    }
64
}
72
}
44814482
17
 * @subpackage     Toolbar
17
 * @subpackage     Toolbar
18
 * @uses        KInflector
18
 * @uses        KInflector
19
 */
19
 */
20
abstract class KControllerToolbarAbstract extends KObject
20
abstract class KControllerToolbarAbstract extends KEventListener implements KControllerToolbarInterface
21
{
21
{
22
    /**
22
    /**
23
     * The toolbar title
23
     * The toolbar title
...
 
...
 
59
 
59
 
60
        parent::__construct($config);
60
        parent::__construct($config);
61
 
61
 
 
 
62
        if(is_null($config->controller)) {
 
 
63
            throw new KMixinException('controller [KController] option is required');
 
 
64
        }
 
 
65
 
62
        // Set the controller
66
        // Set the controller
63
        $this->_controller = $config->controller;
67
        $this->_controller = $config->controller;
64
 
68
 
...
 
...
 
80
    protected function _initialize(KConfig $config)
84
    protected function _initialize(KConfig $config)
81
    {
85
    {
82
        $config->append(array(
86
        $config->append(array(
83
            'title'         => KInflector::humanize($this->getName()),
87
            'title'         => KInflector::humanize(KInflector::pluralize($this->getName())),
84
            'icon'          => $this->getName(),
88
            'icon'          => $this->getName(),
85
            'controller'    => null,
89
            'controller'    => null,
86
        ));
90
        ));
...
 
...
 
112
     * Set the toolbar's title
116
     * Set the toolbar's title
113
     *
117
     *
114
     * @param   string  Title
118
     * @param   string  Title
115
     * @return  KToolbarInterface
119
     * @return  KControllerToolbarAbstract
116
     */
120
     */
117
    public function setTitle($title)
121
    public function setTitle($title)
118
    {
122
    {
...
 
...
 
134
     * Set the toolbar's icon
138
     * Set the toolbar's icon
135
     *
139
     *
136
     * @param   string  Icon
140
     * @param   string  Icon
137
     * @return  KControllerToolbarInterface
141
     * @return  KControllerToolbarAbstract
138
     */
142
     */
139
    public function setIcon($icon)
143
    public function setIcon($icon)
140
    {
144
    {
...
 
...
 
155
    /**
159
    /**
156
     * Add a separator
160
     * Add a separator
157
     *
161
     *
158
     * @return  KControllerToolbarInterface
162
     * @return  KControllerToolbarAbstract
159
     */
163
     */
160
    public function addSeparator()
164
    public function addSeparator()
161
    {
165
    {
...
 
...
 
168
     *
172
     *
169
     * @param   string    The command name
173
     * @param   string    The command name
170
     * @param    mixed    Parameters to be passed to the command
174
     * @param    mixed    Parameters to be passed to the command
171
     * @return  KControllerToolbarInterface
175
     * @return  KControllerToolbarAbstract
172
     */
176
     */
173
    public function addCommand($name, $config = array())
177
    public function addCommand($command, $config = array()) 
174
    {
178
    {
175
        //Create the config object 
179
        if (!($command instanceof  KControllerToolbarCommand)) { 
176
        $command = new KControllerToolbarCommand($name, $config);
180
            $command = $this->getCommand($command, $config);
177
        
 
 
178
        //Find the command function to call
 
 
179
        if(method_exists($this, '_command'.ucfirst($name))) 
 
 
180
        {
 
 
181
            $function =  '_command'.ucfirst($name);
 
 
182
            $this->$function($command);
 
 
183
        } 
 
 
184
        else 
 
 
185
        {
 
 
186
            //Don't set an action for GET commands
 
 
187
            if(!isset($command->attribs->href)) 
 
 
188
            {
 
 
189
                $command->append(array(
 
 
190
                     'attribs'    => array(
 
 
191
                           'data-action'  => $command->getName()
 
 
192
                    )
 
 
193
                ));
 
 
194
            }
 
 
195
        }
181
        }
196
 
182
                       
197
        $this->_commands[$name] = $command;
183
        $this->_commands[$command->getName()] = $command;
198
        return $this;
184
        return $this;
199
    }
185
    }
200
 
186
 
 
 
187
    /** 
 
 
188
     * Get a command by name
 
 
189
     * 
 
 
190
     * @param string The command name
 
 
191
     * @param array An optional associative array of configuration settings
 
 
192
     * @return mixed KControllerToolbarCommand if found, false otherwise.  
 
 
193
     */ 
 
 
194
    public function getCommand($name, $config = array()) 
 
 
195
    { 
 
 
196
        if (!isset($this->_commands[$name])) 
 
 
197
        { 
 
 
198
            //Create the config object 
 
 
199
            $command = new KControllerToolbarCommand($name, $config);
 
 
200
 
 
 
201
            //Find the command function to call
 
 
202
            if(method_exists($this, '_command'.ucfirst($name))) 
 
 
203
            {
 
 
204
                $function =  '_command'.ucfirst($name);
 
 
205
                $this->$function($command);
 
 
206
            }     
 
 
207
            else 
 
 
208
            {
 
 
209
                //Don't set an action for GET commands
 
 
210
                if(!isset($command->attribs->href)) 
 
 
211
                {
 
 
212
                    $command->append(array(
 
 
213
                         'attribs'    => array(
 
 
214
                               'data-action'  => $command->getName()
 
 
215
                        )
 
 
216
                    ));
 
 
217
                }
 
 
218
            }
 
 
219
        } 
 
 
220
        else $command = $this->_commands[$name]; 
 
 
221
 
 
 
222
        return $command;
 
 
223
    } 
 
 
224
 
201
     /**
225
     /**
202
     * Get the list of commands
226
     * Get the list of commands
203
     *
227
     *
...
 
...
 
211
    /**
235
    /**
212
     * Reset the commands array
236
     * Reset the commands array
213
     *
237
     *
214
     * @return  KConttrollerToolbarInterface
238
     * @return  KConttrollerToolbarAbstract
215
     */
239
     */
216
    public function reset()
240
    public function reset()
217
    {
241
    {
...
 
...
 
218
        $this->_commands = array();
242
        $this->_commands = array();
219
        return $this;
243
        return $this;
220
    }
244
    }
221
    
245
 
222
     /**
246
     /**
223
     * Add a command by it's name
247
     * Add a command by it's name
224
     *
248
     *
44814482
3
 * @version     $Id$
3
 * @version     $Id$
4
 * @category    Koowa
4
 * @category    Koowa
5
 * @package     Koowa_Controller
5
 * @package     Koowa_Controller
6
 * @subpackage     Toolba
6
 * @subpackage     Toolbar
7
 * @copyright   Copyright (C) 2007 - 2012 Johan Janssens. All rights reserved.
7
 * @copyright   Copyright (C) 2007 - 2012 Johan Janssens. All rights reserved.
8
 * @license     GNU GPLv3 <http://www.gnu.org/licenses/gpl.html>
8
 * @license     GNU GPLv3 <http://www.gnu.org/licenses/gpl.html>
9
 * @link        http://www.nooku.org
9
 * @link        http://www.nooku.org
44814482
115
        // Set the connection options
115
        // Set the connection options
116
        $this->_options = $config->options;
116
        $this->_options = $config->options;
117
 
117
 
118
        // Mixin a command chain
118
         //Set the mixer in the config
119
        $this->mixin(new KMixinCommandchain($config->append(array('mixer' => $this))));
119
        $config->mixer = $this;
 
 
120
        
 
 
121
        // Mixin the command interface
 
 
122
        $this->mixin(new KMixinCommand($config));
120
    }
123
    }
121
 
124
 
122
    /**
125
    /**
...
 
...
 
144
            'charset'            => 'UTF-8',
147
            'charset'            => 'UTF-8',
145
                'table_prefix'      => 'jos_',
148
                'table_prefix'      => 'jos_',
146
            'table_needle'        => '#__',
149
            'table_needle'        => '#__',
147
            'command_chain'     =>  new KCommandChain(),
150
            'command_chain'     => $this->getService('koowa:command.chain'),
148
            'dispatch_events'   => true,
151
            'dispatch_events'   => true,
 
 
152
            'event_dispatcher'  => $this->getService('koowa:event.dispatcher'),
149
            'enable_callbacks'     => false,
153
            'enable_callbacks'     => false,
150
            'connection'        => null,
154
            'connection'        => null,
151
        ));
155
        ));
44814482
16
 * @package     Koowa_Database
16
 * @package     Koowa_Database
17
 * @subpackage     Behavior
17
 * @subpackage     Behavior
18
 */
18
 */
19
abstract class KDatabaseBehaviorAbstract extends KMixinAbstract implements KDatabaseBehaviorInterface
19
abstract class KDatabaseBehaviorAbstract extends KBehaviorAbstract
20
{
20
{
21
    /**
21
    /**
22
     * The behavior priority
 
 
23
     *
 
 
24
     * @var integer
 
 
25
     */
 
 
26
    protected $_priority;
 
 
27
    
 
 
28
    /**
 
 
29
     * The service identifier
 
 
30
     *
 
 
31
     * @var KServiceIdentifier
 
 
32
     */
 
 
33
    private $__service_identifier;
 
 
34
    
 
 
35
    /**
 
 
36
     * The service container
 
 
37
     *
 
 
38
     * @var KServiceInterface
 
 
39
     */
 
 
40
    private $__service_container;
 
 
41
    
 
 
42
    /**
 
 
43
     * Constructor.
 
 
44
     *
 
 
45
     * @param     object     An optional KConfig object with configuration options
 
 
46
     */
 
 
47
    public function __construct( KConfig $config = null) 
 
 
48
    { 
 
 
49
        //Set the service container
 
 
50
        if(isset($config->service_container)) {
 
 
51
            $this->__service_container = $config->service_container;
 
 
52
        }
 
 
53
        
 
 
54
        //Set the service identifier
 
 
55
        if(isset($config->service_identifier)) {
 
 
56
            $this->__service_identifier = $config->service_identifier;
 
 
57
        }
 
 
58
        
 
 
59
        parent::__construct($config);
 
 
60
        
 
 
61
        $this->_priority = $config->priority;
 
 
62
        
 
 
63
        //Automatically mixin the behavior with the mixer (table object)
 
 
64
        if($config->auto_mixin) {
 
 
65
            $this->mixin($this);
 
 
66
        }
 
 
67
    }
 
 
68
    
 
 
69
    /**
 
 
70
     * Initializes the options for the object
 
 
71
     *
 
 
72
     * Called from {@link __construct()} as a first step of object instantiation.
 
 
73
     *
 
 
74
     * @param     object     An optional KConfig object with configuration options
 
 
75
     * @return void
 
 
76
     */
 
 
77
    protected function _initialize(KConfig $config)
 
 
78
    {
 
 
79
        $config->append(array(
 
 
80
            'priority'   => KCommand::PRIORITY_NORMAL,
 
 
81
            'auto_mixin' => false
 
 
82
          ));
 
 
83
 
 
 
84
        parent::_initialize($config);
 
 
85
       }
 
 
86
    
 
 
87
    /**
 
 
88
     * Get the priority of a behavior
 
 
89
     *
 
 
90
     * @return    integer The command priority
 
 
91
     */
 
 
92
      public function getPriority()
 
 
93
      {
 
 
94
          return $this->_priority;
 
 
95
      }
 
 
96
    
 
 
97
    /**
 
 
98
     * Command handler
22
     * Command handler
99
     * 
23
     * 
100
     * This function transmlated the command name to a command handler function of 
24
     * This function transmlated the command name to a command handler function of 
101
     * the format '_beforeX[Command]' or '_afterX[Command]. Command handler
25
     * the format '_before[Command]' or '_after[Command]. Command handler
102
     * functions should be declared protected.
26
     * functions should be declared protected.
103
     * 
27
     * 
104
     * @param     string      The command name
28
     * @param     string      The command name
...
 
...
 
105
     * @param     object       The command context
29
     * @param     object       The command context
106
     * @return     boolean        Can return both true or false.  
30
     * @return     boolean        Can return both true or false.  
107
     */
31
     */
108
    final public function execute( $name, KCommandContext $context) 
32
    public function execute( $name, KCommandContext $context) 
109
    {
33
    {
110
        $identifier = clone $context->caller->getIdentifier();
34
        if($context->data instanceof KDatabaseRowInterface) {
111
        $type       = array_pop($identifier->path);
35
            $this->setMixer($context->data);
112
    
 
 
113
        $parts  = explode('.', $name);
 
 
114
        $method = '_'.$parts[0].ucfirst($type).ucfirst($parts[1]);
 
 
115
    
 
 
116
        if(method_exists($this, $method)) 
 
 
117
        {
 
 
118
            if($context->data instanceof KDatabaseRowInterface) {
 
 
119
                 $this->setMixer($context->data);
 
 
120
            }
 
 
121
            
 
 
122
            return $this->$method($context);
 
 
123
        }
36
        }
124
 
37
 
125
        return true;
38
        return parent::execute($name, $context);
126
    }
39
    }
127
 
40
 
128
    /**
41
    /**
...
 
...
 
163
    }
76
    }
164
 
77
 
165
    /**
78
    /**
166
     * Get an object handle
 
 
167
     * 
 
 
168
     * This function only returns a valid handle if one or more command handler 
 
 
169
     * functions are defined. A commend handler function needs to follow the 
 
 
170
     * following format : '_afterX[Event]' or '_beforeX[Event]' to be 
 
 
171
     * recognised.
 
 
172
     * 
 
 
173
     * @return string A string that is unique, or NULL
 
 
174
     * @see execute()
 
 
175
     */
 
 
176
    public function getHandle()
 
 
177
    {
 
 
178
        $methods = $this->getMethods();
 
 
179
        
 
 
180
        foreach($methods as $method) 
 
 
181
        {
 
 
182
            if(substr($method, 0, 7) == '_before' || substr($method, 0, 6) == '_after') {
 
 
183
                return parent::getHandle(); 
 
 
184
            }
 
 
185
        }
 
 
186
        
 
 
187
        return null;
 
 
188
    }
 
 
189
    
 
 
190
    /**
 
 
191
     * Get the methods that are available for mixin based 
79
     * Get the methods that are available for mixin based 
192
     * 
80
     * 
193
     * This function also dynamically adds a function of format is[Behavior] 
81
     * This function also dynamically adds a function of format is[Behavior] 
...
 
...
 
198
     */
86
     */
199
    public function getMixableMethods(KObject $mixer = null)
87
    public function getMixableMethods(KObject $mixer = null)
200
    {
88
    {
201
        $methods   = parent::getMixableMethods($mixer);
89
        $methods = parent::getMixableMethods($mixer);       
202
        $methods[] = 'is'.ucfirst($this->getIdentifier()->name);
90
        return array_diff($methods, array('save', 'delete'));
203
            
 
 
204
        return array_diff($methods, array('execute', 'save', 'delete', 'getHandle', 'getPriority', 'getIdentifier', 'getService'));
 
 
205
    }
91
    }
206
    
 
 
207
    /**
 
 
208
     * Get an instance of a class based on a class identifier only creating it
 
 
209
     * if it doesn't exist yet.
 
 
210
     *
 
 
211
     * @param    string|object    The class identifier or identifier object
 
 
212
     * @param    array              An optional associative array of configuration settings.
 
 
213
     * @throws    KServiceServiceException
 
 
214
     * @return    object          Return object on success, throws exception on failure
 
 
215
     * @see     KObjectServiceable
 
 
216
     */
 
 
217
    final public function getService($identifier, array $config = array())
 
 
218
    {
 
 
219
        return $this->__service_container->get($identifier, $config);
 
 
220
    }
 
 
221
    
 
 
222
    /**
 
 
223
     * Gets the service identifier.
 
 
224
     *
 
 
225
     * @return    KServiceIdentifier
 
 
226
     * @see     KObjectServiceable
 
 
227
     */
 
 
228
    final public function getIdentifier($identifier = null)
 
 
229
    {
 
 
230
        if(isset($identifier)) {
 
 
231
            $result = $this->__service_container->getIdentifier($identifier);
 
 
232
        } else {
 
 
233
            $result = $this->__service_identifier; 
 
 
234
        }
 
 
235
        
 
 
236
        return $result;
 
 
237
    }
 
 
238
}
92
}
44814482
17
 * @package     Koowa_Database
17
 * @package     Koowa_Database
18
 * @subpackage  Behavior
18
 * @subpackage  Behavior
19
 */
19
 */
20
class KDatabaseBehaviorException extends KDatabaseException {}
20
class KDatabaseBehaviorException extends KBehaviorException {}
44814482
135
    {
135
    {
136
        return (bool) $this->getTable();
136
        return (bool) $this->getTable();
137
    }
137
    }
 
 
138
 
 
 
139
    /**
 
 
140
     * Add rows to the rowset
 
 
141
     *
 
 
142
     * @param  array    An associative array of row data to be inserted. 
 
 
143
     * @param  boolean  If TRUE, mark the row(s) as new (i.e. not in the database yet). Default TRUE
 
 
144
     * @return  KDatabaseRowsetAbstract
 
 
145
     * @see __construct
 
 
146
     */
 
 
147
    public function addData(array $data, $new = true)
 
 
148
    {   
 
 
149
        if($this->isConnected()) {
 
 
150
            parent::addData($data, $new);
 
 
151
        }
 
 
152
 
 
 
153
        return $this;
 
 
154
    }
138
 
155
 
139
    /**
156
    /**
140
     * Get an empty row
157
     * Get an empty row
44814482
77
     * @var    array
77
     * @var    array
78
     */
78
     */
79
    public $columns = array();
79
    public $columns = array();
80
 
80
        
81
    /**
81
    /**
82
     * List of behaviors
 
 
83
     * 
 
 
84
     * Associative array of behaviors, where key holds the behavior identifier string
 
 
85
     * and the value is an KDatabaseBehavior object.
 
 
86
     * 
 
 
87
     * @var    array
 
 
88
     */
 
 
89
    public $behaviors = array();
 
 
90
    
 
 
91
    /**
 
 
92
     * List of indexes
82
     * List of indexes
93
     * 
83
     * 
94
     * Associative array of indexes, where key holds the index name and the
84
     * Associative array of indexes, where key holds the index name and the
44814482
112
                $this->getColumn($column, true)->filter = KConfig::unbox($filter);
112
                $this->getColumn($column, true)->filter = KConfig::unbox($filter);
113
            }       
113
            }       
114
        }
114
        }
115
 
115
        
116
        // Mixin a command chain
116
        //Set the mixer in the config
117
         $this->mixin(new KMixinCommandchain($config->append(array('mixer' => $this))));
117
        $config->mixer = $this;
118
           
118
 
119
        // Set the table behaviors
119
        // Mixin the command interface
120
        if(!empty($config->behaviors)) {
120
        $this->mixin(new KMixinCommand($config));
121
            $this->addBehavior($config->behaviors);
121
 
122
        } 
122
        // Mixin the behavior interface
 
 
123
        $this->mixin(new KMixinBehavior($config));
123
    }
124
    }
124
 
125
 
125
    /**
126
    /**
...
 
...
 
142
            'filters'           => array(),
143
            'filters'           => array(),
143
            'behaviors'         => array(),
144
            'behaviors'         => array(),
144
            'identity_column'   => null,
145
            'identity_column'   => null,
145
            'command_chain'     => new KCommandChain(),
146
            'command_chain'     => $this->getService('koowa:command.chain'),
146
            'dispatch_events'   => false,
147
            'dispatch_events'   => false,
 
 
148
            'event_dispatcher'  => null,
147
            'enable_callbacks'  => false,
149
            'enable_callbacks'  => false,
148
        ))->append(
150
        ))->append(
149
            array('base'        => $config->name)
151
            array('base'        => $config->name)
...
 
...
 
228
        return $keys;
230
        return $keys;
229
    }
231
    }
230
 
232
 
231
    /**
 
 
232
     * Check if a behavior exists
 
 
233
     *
 
 
234
     * @param     string    The name of the behavior
 
 
235
     * @return  boolean    TRUE if the behavior exists, FALSE otherwise
 
 
236
     */
 
 
237
    public function hasBehavior($behavior)
 
 
238
    { 
 
 
239
        return isset($this->getSchema()->behaviors[$behavior]); 
 
 
240
    }
 
 
241
    
 
 
242
    /**
 
 
243
     * Register one or more behaviors to the table
 
 
244
     *
 
 
245
     * @param   array   Array of one or more behaviors to add.
 
 
246
     * @return  KDatabaseTableAbstract
 
 
247
     */
 
 
248
    public function addBehavior($behaviors)
 
 
249
    {
 
 
250
        $behaviors = (array) KConfig::unbox($behaviors);
 
 
251
                
 
 
252
        foreach($behaviors as $behavior)
 
 
253
        {
 
 
254
            if (!($behavior instanceof KDatabaseBehaviorInterface)) { 
 
 
255
                $behavior   = $this->getBehavior($behavior); 
 
 
256
            } 
 
 
257
              
 
 
258
            //Add the behavior
 
 
259
            $this->getSchema()->behaviors[$behavior->getIdentifier()->name] = $behavior;
 
 
260
            $this->getCommandChain()->enqueue($behavior);
 
 
261
        }
 
 
262
        
 
 
263
        return $this;
 
 
264
    }
 
 
265
    
 
 
266
    /**
 
 
267
     * Get a behavior by identifier
 
 
268
     *
 
 
269
     * @param  
 
 
270
     * @return KControllerBehaviorAbstract
 
 
271
     */
 
 
272
    public function getBehavior($behavior, $config = array())
 
 
273
    {
 
 
274
       if(!($behavior instanceof KServiceIdentifier))
 
 
275
       {
 
 
276
            //Create the complete identifier if a partial identifier was passed
 
 
277
           if(is_string($behavior) && strpos($behavior, '.') === false )
 
 
278
           {
 
 
279
               $identifier = clone $this->getIdentifier();
 
 
280
               $identifier->path = array('database', 'behavior');
 
 
281
               $identifier->name = $behavior;
 
 
282
           }
 
 
283
           else $identifier = $this->getIdentifier($behavior);
 
 
284
       }
 
 
285
       
 
 
286
       if(!isset($this->getSchema()->behaviors[$identifier->name])) 
 
 
287
       {
 
 
288
           $behavior = $this->getService($identifier, array_merge($config, array('mixer' => $this)));
 
 
289
           
 
 
290
           //Check the behavior interface
 
 
291
           if(!($behavior instanceof KDatabaseBehaviorInterface)) {
 
 
292
               throw new KDatabaseTableException("Database behavior $identifier does not implement KDatabaseBehaviorInterface");
 
 
293
           }
 
 
294
       } 
 
 
295
       else $behavior = $this->getSchema()->behaviors[$identifier->name];
 
 
296
       
 
 
297
       return $behavior;
 
 
298
    }
 
 
299
       
 
 
300
    /**
 
 
301
     * Gets the behaviors of the table
 
 
302
     *
 
 
303
     * @return array    An asscociate array of table behaviors, keys are the behavior names
 
 
304
     */
 
 
305
    public function getBehaviors()
 
 
306
    {
 
 
307
        return $this->getSchema()->behaviors;
 
 
308
    }    
 
 
309
    
 
 
310
    /**
233
    /**
311
     * Gets the schema of the table
234
     * Gets the schema of the table
312
     *
235
     *
...
 
...
 
500
        //The rowset default options
423
        //The rowset default options
501
        $options['table'] = $this; 
424
        $options['table'] = $this; 
502
        $options['identity_column'] = $this->mapColumns($this->getIdentityColumn(), true);
425
        $options['identity_column'] = $this->mapColumns($this->getIdentityColumn(), true);
503
 
426
        
504
        return $this->getService($identifier, $options);
427
        return $this->getService($identifier, $options);
505
    }
428
    }
506
 
429
 
...
 
...
 
581
            {
504
            {
582
                case KDatabase::FETCH_ROW    : 
505
                case KDatabase::FETCH_ROW    : 
583
                {
506
                {
584
                    $context->data = $this->getRow();
507
                    $options = array();
585
                    if(isset($data) && !empty($data)) {
508
                    if(isset($data) && !empty($data)) 
586
                       $context->data->setData($data, false)->setStatus(KDatabase::STATUS_LOADED);
509
                    {
 
 
510
                        $options = array(
 
 
511
                            'data'   => $data,
 
 
512
                            'new'    => false,
 
 
513
                            'status' => KDatabase::STATUS_LOADED
 
 
514
                        );
587
                    }
515
                    }
 
 
516
 
 
 
517
                    $context->data = $this->getRow($options);
588
                    break;
518
                    break;
589
                }
519
                }
590
 
520
 
591
                case KDatabase::FETCH_ROWSET : 
521
                case KDatabase::FETCH_ROWSET : 
592
                {
522
                {
593
                    $context->data = $this->getRowset();
523
                    $options = array();
594
                    if(isset($data) && !empty($data)) {
524
                    if(isset($data) && !empty($data)) 
595
                        $context->data->addData($data, false);
525
                    {
 
 
526
                        $options = array(
 
 
527
                            'data'   => $data,
 
 
528
                            'new'    => false,
 
 
529
                        );
596
                    }
530
                    }
 
 
531
 
 
 
532
                    $context->data = $this->getRowset($options);
597
                    break;
533
                    break;
598
                }
534
                }
599
 
535
 
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff
File was changed - ok, show the diff