Break out Nextmatch sub-widgets into their own files, and make sure sub widgets can get autoloaded.

This commit is contained in:
Nathan Gray 2016-03-21 18:40:43 +00:00
parent 9905a3f6bd
commit e214a7153c
5 changed files with 142 additions and 79 deletions

View File

@ -308,13 +308,13 @@ class Widget
if (!$widget_registry) // not in instance cache --> rescan from filesystem if (!$widget_registry) // not in instance cache --> rescan from filesystem
{ {
foreach(scandir($dir=__DIR__ . '/Widget') as $filename) foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__)) as $path)
{ {
if(substr($filename, -4) == '.php') if(substr($path, -4) == '.php')
{ {
try try
{ {
include_once($dir.'/'.$filename); include_once($path);
} }
catch(Exception $e) catch(Exception $e)
{ {
@ -390,6 +390,24 @@ class Widget
} }
} }
} }
else if (!class_exists($class_name))
{
// Class in widget registry, but not loaded
// Try for a base class
$subtypes = explode('-',$type);
$basetype = $subtypes[0];
$class_name = __CLASS__.'\\'.implode('\\',array_map('ucfirst',$subtypes));
if(!class_exists($class_name) && self::$widget_registry[$basetype] && self::$widget_registry[$basetype] != $class_name)
{
// Try for base type, it's probably better than the root
$class_name = self::$widget_registry[$basetype];
}
if(!class_exists($class_name))
{
// Fall back to widget class, we can not ignore it, as the widget may contain other widgets
$class_name = __CLASS__;
}
}
if(!$xml) if(!$xml)
{ {

View File

@ -1157,79 +1157,4 @@ class Nextmatch extends Etemplate\Widget
} }
// Registration needs to go here, otherwise customfields won't be loaded until some other cf shows up // Registration needs to go here, otherwise customfields won't be loaded until some other cf shows up
Etemplate\Widget::registerWidget(__NAMESPACE__.'\\Customfields', array('nextmatch-customfields')); Etemplate\Widget::registerWidget(__NAMESPACE__.'\\Customfields', array('nextmatch-customfields'));
/**
* Extend selectbox so select options get parsed properly before being sent to client
*/
class NextmatchFilterHeader extends Select
{
}
Etemplate\Widget::registerWidget(__NAMESPACE__.'\\NextmatchFilterHeader', array('nextmatch-filterheader'));
/**
* Extend selectbox and change type so proper users / groups get loaded, according to preferences
*/
class NextmatchAccountFilter extends Select
{
/**
* Parse and set extra attributes from xml in template object
*
* @param string|XMLReader $xml
* @param boolean $cloned =true true: object does NOT need to be cloned, false: to set attribute, set them in cloned object
*/
public function set_attrs($xml, $cloned=true)
{
parent::set_attrs($xml, $cloned);
$this->attrs['type'] = 'select-account';
}
}
Etemplate\Widget::registerWidget(__NAMESPACE__.'\\NextmatchAccountFilter', array('nextmatch-accountfilter'));
/**
* A filter widget that fakes another (select) widget and turns it into a nextmatch filter widget.
*/
class NextmatchCustomFilter extends Transformer
{
protected $legacy_options = 'type,widget_options';
/**
* Fill type options in self::$request->sel_options to be used on the client
*
* @param string $cname
* @param array $expand values for keys 'c', 'row', 'c_', 'row_', 'cont'
*/
public function beforeSendToClient($cname, array $expand=null)
{
switch($this->attrs['type'])
{
case "link-entry":
self::$transformation['type'] = $this->attrs['type'] = 'nextmatch-entryheader';
break;
default:
list($type) = explode('-',$this->attrs['type']);
if($type == 'select')
{
if(in_array($this->attrs['type'], Select::$cached_types))
{
$widget_type = $this->attrs['type'];
}
$this->attrs['type'] = 'nextmatch-filterheader';
}
self::$transformation['type'] = $this->attrs['type'];
}
$form_name = self::form_name($cname, $this->id, $expand);
$this->setElementAttribute($form_name, 'options', trim($this->attrs['widget_options']) != '' ? $this->attrs['widget_options'] : '');
$this->setElementAttribute($form_name, 'type', $this->attrs['type']);
if($widget_type)
{
$this->setElementAttribute($form_name, 'widget_type', $widget_type);
}
parent::beforeSendToClient($cname, $expand);
}
}
Etemplate\Widget::registerWidget(__NAMESPACE__.'\\NextmatchCustomFilter', array('nextmatch-customfilter'));

View File

@ -0,0 +1,35 @@
<?php
/**
* EGroupware - eTemplate serverside implementation of the nextmatch filter header widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage etemplate
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker@outdoor-training.de>
* @copyright 2002-16 by RalfBecker@outdoor-training.de
* @version $Id$
*/
namespace EGroupware\Api\Etemplate\Widget\Nextmatch;
use EGroupware\Api\Etemplate\Widget;
/**
* Extend selectbox and change type so proper users / groups get loaded, according to preferences
*/
class AccountFilter extends Widget\Select
{
/**
* Parse and set extra attributes from xml in template object
*
* @param string|XMLReader $xml
* @param boolean $cloned =true true: object does NOT need to be cloned, false: to set attribute, set them in cloned object
*/
public function set_attrs($xml, $cloned=true)
{
parent::set_attrs($xml, $cloned);
$this->attrs['type'] = 'select-account';
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* EGroupware - eTemplate serverside implementation of the nextmatch filter header widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage etemplate
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker@outdoor-training.de>
* @copyright 2002-16 by RalfBecker@outdoor-training.de
* @version $Id$
*/
namespace EGroupware\Api\Etemplate\Widget\Nextmatch;
use EGroupware\Api\Etemplate\Widget;
/**
* A filter widget that fakes another (select) widget and turns it into a nextmatch filter widget.
*/
class NextmatchCustomFilter extends Widget\Transformer
{
protected $legacy_options = 'type,widget_options';
/**
* Fill type options in self::$request->sel_options to be used on the client
*
* @param string $cname
* @param array $expand values for keys 'c', 'row', 'c_', 'row_', 'cont'
*/
public function beforeSendToClient($cname, array $expand=null)
{
switch($this->attrs['type'])
{
case "link-entry":
self::$transformation['type'] = $this->attrs['type'] = 'nextmatch-entryheader';
break;
default:
list($type) = explode('-',$this->attrs['type']);
if($type == 'select')
{
if(in_array($this->attrs['type'], Select::$cached_types))
{
$widget_type = $this->attrs['type'];
}
$this->attrs['type'] = 'nextmatch-filterheader';
}
self::$transformation['type'] = $this->attrs['type'];
}
$form_name = self::form_name($cname, $this->id, $expand);
$this->setElementAttribute($form_name, 'options', trim($this->attrs['widget_options']) != '' ? $this->attrs['widget_options'] : '');
$this->setElementAttribute($form_name, 'type', $this->attrs['type']);
if($widget_type)
{
$this->setElementAttribute($form_name, 'widget_type', $widget_type);
}
parent::beforeSendToClient($cname, $expand);
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
* EGroupware - eTemplate serverside implementation of the nextmatch filter header widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage etemplate
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker@outdoor-training.de>
* @copyright 2002-16 by RalfBecker@outdoor-training.de
* @version $Id$
*/
namespace EGroupware\Api\Etemplate\Widget\Nextmatch;
use EGroupware\Api\Etemplate\Widget;
/**
* Extend selectbox so select options get parsed properly before being sent to client
*/
class Filterheader extends Widget\Select
{
}