3 * NP_List - Output various lists (with sub-plugins) for NucleusCMS
10 * v0.4 2008-05-14 Support itemvars. (yu)
11 * Add operator "=~"(LIKE) and "!~"(NOT LIKE) in filter. (yu)
12 * Fix filter bug ("!=" and "<>" weren't worked correctly). (yu)
13 * v0.32 2008-05-13 Support current memberid in getFilter(). (yu)
14 * v0.31 2008-05-08 Fix subplugin loader (NP_ListOf*Uppercase-first*). (yu)
15 * v0.3 2008-05-06 Refine subplugin class. (yu)
16 * v0.2 2008-05-02 Add new methods in subplugin class. (yu)
17 * v0.1 2008-04-30 First release. (yu)
19 class NP_List extends NucleusPlugin
21 function getName() { return 'List'; }
22 function getAuthor() { return 'yu'; }
23 function getURL() { return 'http://nucleus.datoka.jp/'; }
24 function getVersion() { return '0.4'; }
25 function getMinNucleusVersion() { return 330; }
26 function supportsFeature($what) { return (int)($what == 'SqlTablePrefix'); }
27 // function getPluginDep() { return array('NP_Container'); }
29 function getDescription()
31 return "Output various lists with sub-plugins.";
40 global $manager, $blogid;
42 $this->params = array();
43 $this->parts = array();
45 //if NP_Container is installed, hold reference of container instance.
46 if ($manager->pluginInstalled('NP_Container')) {
47 $this->container =& $manager->getPlugin('NP_Container');
51 function doItemVar(&$item)
55 //check container parts
56 $this->checkContainer();
59 $this->params = array(); //initialize
60 $this->params['blogid'] = $blogid;
61 $this->params['skintype'] = 'item';
62 $this->params['item'] =& $item;
65 $params = func_get_args();
66 array_shift($params); // remove item reference
67 $this->setParams($params);
69 if ($this->params['type']) {
71 $sub =& $this->callSubPlugin($this->params['type']);
72 if (is_object($sub)) $sub->main();
76 function doSkinVar($skinType)
80 //check container parts
81 $this->checkContainer();
84 $this->params = array(); //initialize
85 $this->params['blogid'] = $blogid;
86 $this->params['skintype'] = $skinType;
89 $params = func_get_args();
90 array_shift($params); // remove skintype parameter
91 $this->setParams($params);
93 if ($this->params['type']) {
95 $sub =& $this->callSubPlugin($this->params['type']);
96 if (is_object($sub)) $sub->main();
101 * parse param string and set them to $this->params
104 * @param $params array of parameters
107 function setParams($params)
109 foreach ($params as $param) {
110 if ($flg_esc = (strpos($param, '\:') !== false)) $param = str_replace('\:', '[[ESCAPED-COLON]]', $param);
111 list($key, $value) = explode(':', $param);
112 if ($flg_esc) $value = str_replace('[[ESCAPED-COLON]]', ':', $value);
116 $this->params['amount'] = (int)$value;
120 $this->params['length'] = (int)$value;
124 $this->params['template'] = $value;
127 $this->params[$key] = $value;
133 * check container parts in skin data
139 function checkContainer()
141 static $flg_setparts;
143 //get container parts (if exists)
144 if (isset($this->container) and !$flg_setparts) {
145 if ( is_array($cparts = $this->container->getParts($this->getName())) ) {
146 foreach ($cparts as $ckey => $cval) {
147 list($ckey2, $ckey3) = split('_', $ckey, 2);
148 $this->parts[$ckey2][$ckey3] = $cval;
151 $flg_setparts = true;
156 * generate/reuse an instance of sub plugin
159 * @param $name sub plugin name
160 * @return object reference
162 function &callSubPlugin($name)
166 if (empty($name) or preg_match('/[^0-9a-zA-Z_-]/', $name)) return false;
168 $classname = 'NP_ListOf'. ucfirst($name);
169 if (!class_exists($classname)) {
170 $filename = $DIR_PLUGINS .'list/'. $classname .'.php';
171 if (!file_exists($filename)) {
172 ACTIONLOG::add(WARNING, 'Plugin ' . $classname . ' was not loaded (File not found)');
176 include_once($filename);
178 if (!class_exists($classname)) {
179 ACTIONLOG::add(WARNING, 'Plugin ' . $classname . ' was not loaded (Class not found in file, possible parse error)');
184 //$classname::show(&$params); //PHP5.3~
185 //eval($classname .'::show($params);'); //call static class
187 //eval('$sub =& '. $classname .'::getInstance($this);'); //get instance (singleton) from subplugin
188 eval('$sub =& $this->getInstance('.$classname.');'); //get instance (singleton) from instance manager
194 * get an instance of the class (singleton)
197 * @param $classname class name
200 function &getInstance($classname)
203 if ($instances[$classname] == null) {
204 $instances[$classname] =& new $classname();
205 $instances[$classname]->init($this);
208 $instances[$classname]->reset(); //reset flags and template
211 return $instances[$classname];
215 * get parsed filter string
218 * @param $filter filter string
219 * @param $aliasmap key 'search' has an array of alias name
220 * key 'replace' has an array of column name
221 * @param $current an array of current values
224 function getFilter($filter, $aliasmap, $current='')
226 global $blogid, $catid, $memberid, $archive;
228 $fparams = split(' ', $filter);
230 if (! is_array($current)) {
234 'memberid' => $memberid,
235 'arcdate' => $archive,
240 foreach ($fparams as $fil) {
241 //replace '@' to current id
242 if (substr($fil, -1, 1) == '@') {
243 preg_match('/^([a-z]+?)[!=<>]/', $fil, $match); //pick up left side
244 if ($current[ $match[1] ]) {
245 $fil = substr($fil, 0, -1) . $current[ $match[1] ];
247 else continue; //if current key/value is not defined, skip it.
250 //replace because it can't use aliases in WHERE clause.
251 $fil = str_replace($aliasmap['search'], $aliasmap['replace'], $fil);
254 preg_match('/^([a-zA-Z0-9(),._-]+?)(<>|>=|<=|!=|=~|!~|[=<>])(.+?)$/', $fil, $match);
256 if (isset($match[1]) and isset($match[2]) and isset($match[3])) {
257 if ($match[2] == '=~') $match[2] = ' LIKE ';
258 if ($match[2] == '!~') $match[2] = ' NOT LIKE ';
260 if (strpos($match[3], '|')) { //multiple values
261 $values = split('\|', $match[3]);
263 foreach ($values as $v) {
264 $f[] = $match[1] . $match[2] .'"'. mysql_real_escape_string($v) .'"';
266 if ($match[2] == '<>' or $match[2] == '!=' or $match[2] == '!~') $cond = ' AND '; //'NOT' condition
267 else $cond = ' OR '; //normal condition
268 $fil = '(' . join($cond, $f) . ')';
271 else { //single value
272 $fil = $match[1] . $match[2] .'"'. mysql_real_escape_string($match[3]) .'"';
277 //wrong filter. skip it.
280 return join(' AND ', $filters);
286 * base class of sub plugins
288 * The class extended from this must implement main() method.
293 class NP_ListOfSubPlugin
301 * main method (*MUST* implement it)
309 echo 'echo of sub plugin.';
313 * get default template (implement it if needed)
319 function _getDefaultTemplate()
325 * initicialize a instance
327 * Hold a reference of the caller object (NP_List).
330 * @param &$oCaller caller object
332 * @see NP_List::getInstance()
334 function init(&$oCaller)
337 $this->caller =& $oCaller;
340 $this->params =& $this->caller->params;
342 //set default params, flags and template
347 * reset flags and template
352 * @see NP_List::getInstance()
357 $this->_setDefaultParams();
360 $this->flg = $this->_getFlag($this->params['flag']);
363 $this->_setTemplate();
367 * set template data to property $this->templates
369 * If use standard template, get it from $manager.
370 * If use container, get it with param 'type' and 'tplprefix' (if it is set).
371 * First, get default data. Second, get custom parts and merge them.
374 * @param $forced 'true' forces to reset template
377 function _setTemplate($forced = false)
379 $default = $this->_getDefaultTemplate(); // sub plugin's original default template
381 if ($this->params['template']) { //standard Nucleus template
382 $name = $this->params['template'];
384 else { //custom template (container)
385 $name = $this->params['tplprefix'] . strtoupper($this->params['type']);
388 if ($forced or $this->templates[$name] == null) {
389 if ($this->params['template']) {
391 $custom =& $manager->getTemplate($name);
394 $custom = $this->caller->parts[$name]; //container parts
398 $this->templates[$name] = array_merge($default, $custom);
401 $this->templates[$name] = $default;
407 * get template data from property $this->templates
413 function &_getTemplate()
415 if ($this->params['template']) { //standard Nucleus template
416 $name = $this->params['template'];
419 $name = $this->params['tplprefix'] . strtoupper($this->params['type']);
421 if (! $this->templates[$name]) {
422 $this->_setTemplate();
425 return $this->templates[$name];
429 * get parsed filter string (wrapper)
432 * @param $filter filter string
433 * @param $aliasmap key 'search' has an array of alias name
434 * key 'replace' has an array of column name
435 * @param $current an array of current values
437 * @see NP_List::getFilter()
439 function _getFilter($filter, $aliasmap, $current='')
441 return $this->caller->getFilter($filter, $aliasmap, $current);
451 function _setDefaultParams()
453 if (!isset($this->params['amount'])) $this->params['amount'] = 5;
454 if (!isset($this->params['length'])) $this->params['length'] = 25;
455 if (!isset($this->params['trimmarker'])) $this->params['trimmarker'] = '..';
462 * @param $str flag string
465 function _getFlag($str)
467 $keys = split(' ', $str);
469 foreach ($keys as $key) {
470 if (empty($key)) continue;
478 * scan a templatevar in the string
482 * @param $var templatevar name
485 function _scan($str, $var)
487 return (strpos($str, $var) !== false);
491 * fill the template with variables (wrapper)
494 * @param $str template string
495 * @param $vars array of vars
498 function _fill($str, $vars)
500 return TEMPLATE::fill($str, $vars);
504 * make class property
507 * @param $class array (classname => condition)
510 function _makeClassProperty($class)
513 if (!count($class)) return $str;
515 foreach ($class as $name => $bool) {
516 if ($bool) $str .= ' '.$name;
518 if ($str) $str = ' class="'. ltrim($str) .'"';