plugin.class.php
上传用户:stephen_wu
上传日期:2008-07-05
资源大小:1757k
文件大小:91k
源码类别:

网络

开发平台:

Unix_Linux

  1. <?php
  2. /**
  3. * Joomla/Mambo Community Builder : Plugin Handler
  4. * @version $Id: plugin.class.php 610 2006-12-13 17:33:44Z beat $
  5. * @package Community Builder
  6. * @subpackage plugin.class.php
  7. * @author various, JoomlaJoe and Beat
  8. * @copyright (C) JoomlaJoe and Beat, www.joomlapolis.com and various
  9. * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU/GPL version 2
  10. */
  11. // ensure this file is being included by a parent file
  12. if ( ! ( defined( '_VALID_CB' ) || defined( '_JEXEC' ) || defined( '_VALID_MOS' ) ) ) { die( 'Direct Access to this location is not allowed.' ); }
  13. /**
  14.  * CB framework
  15.  * @global CBframework $_CB_framework
  16.  */
  17. global $_CB_framework;
  18. global $mainframe;
  19. if ( defined( 'JPATH_ADMINISTRATOR' ) ) {
  20. $foundation = JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.foundation.php';
  21. } else {
  22. $foundation = $mainframe->getCfg( 'absolute_path' ) . '/administrator/components/com_comprofiler/plugin.foundation.php';
  23. }
  24. include_once( $foundation );
  25. cbimport( 'cb.database' );
  26. /** utility: adds all vars of object $src to object $obj except the variable named in array exclude Array */
  27. function addVarsToClass( &$obj, $src, $excludeArray ) {
  28. foreach( get_object_vars( $src ) as $key => $val ) {
  29. if ( ! in_array( $key, $excludeArray ) ) {
  30. $obj->$key = $val;
  31. }
  32. }
  33. }
  34. class cbPluginHandler {
  35. /** @var array An array of functions in event groups */
  36. var $_events = null;
  37. /** @var array An array of classes and pluginids for field-types */
  38. var $_fieldTypes = array();
  39. /** @var array An array of classes for additional field-parameters */
  40. var $_fieldParams = array();
  41. /** @var array An array of menu and status items (array) */
  42. var $_menus = null;
  43. /** @var array An array of lists */
  44. var $_lists = null;
  45. /** @var array An array of loaded plugins objects, index=pluginId */
  46. var $_plugins = array();
  47. /** @var array An array indexed by the group-name of arrays of plugin ids of the plugins already loaded containing stdClass objects of the plugin table entry */
  48. var $_pluginGroups = array();
  49. /** @var int Index of the plugin being loaded */
  50. var $_loading = null;
  51. /** @var array collection of debug data */
  52. var $debugMSG = array();
  53. /** @var string Error Message*/
  54. var $errorMSG = array();
  55. var $_iserror = false;
  56. var $params = null;
  57. /**
  58. * Constructor
  59. */
  60. function cbPluginHandler() {
  61. $this->_events = array();
  62. }
  63. /**
  64. * Loads all the bot files for a particular group (if group not already loaded)
  65. * @param string The group name, relates to the sub-directory in the plugins directory
  66. * @param mixed array of int : ids of plugins to load. OR: string : name of class 
  67. * @param int if 1 (DEFAULT): load only published plugins, if 0: load all plugins including unpublished ones
  68. * @return boolean TRUE: load done, FALSE: no plugin loaded
  69. */
  70. function loadPluginGroup( $group, $ids = null, $publishedStatus = 1 ) {
  71. global $_CB_framework, $_CB_database;
  72. static $dbCache = null;
  73. $this->_iserror = false;
  74. $group = trim( $group );
  75. if ( ( $group && ! isset( $this->_pluginGroups[$group] ) ) || ( ! $this->all_in_array_key( $ids, $this->_plugins ) ) ) {
  76. $cmsAccess = $_CB_framework->myCmsGid();
  77. if ( ! isset( $dbCache[$publishedStatus][$cmsAccess][$group] ) ) {
  78. $where = array();
  79. if ( $publishedStatus == 1 ) {
  80. $where[] = 'published = 1';
  81. } else {
  82. $where[] = 'published >= ' . (int) $publishedStatus;
  83. }
  84. $where[] = 'access <= '. (int) $cmsAccess;
  85. if ( $group ) {
  86. $where[] = 'type = ' . $_CB_database->Quote( trim ( $group ) );
  87. }
  88. /*
  89. if ( ( $ids !== null ) && ( count( $ids ) > 0 ) ) {
  90. cbArrayToInts( $ids );
  91. if ( count( $ids ) == 1 ) {
  92. $where[] = 'id = ' . implode( '', $ids );
  93. } else {
  94. $where[] = 'id IN (' . implode( ',', $ids ) . ')';
  95. }
  96. }
  97. */
  98. $_CB_database->setQuery( "SELECT id, folder, element, published, type, params, CONCAT_WS('/',folder,element) AS lookup, name"
  99. . "n FROM #__comprofiler_plugin"
  100. . "n WHERE " . implode( ' AND ', $where )
  101. . "n ORDER BY ordering"
  102. );
  103. $dbCache[$publishedStatus][$cmsAccess][$group] = $_CB_database->loadObjectList();
  104. if ( $dbCache[$publishedStatus][$cmsAccess][$group] === null ) {
  105. return false;
  106. }
  107. }
  108. if ( count( $ids ) == 0 ) {
  109. $ids = null;
  110. }
  111. foreach ( $dbCache[$publishedStatus][$cmsAccess][$group] AS $plugin ) {
  112. if ( ( $ids === null ) || in_array( $plugin->id, $ids ) ) {
  113. if ( ( ! isset( $this->_plugins[$plugin->id] ) ) && $this->_loadPluginFile( $plugin ) ) {
  114. $this->_plugins[$plugin->id] = $plugin;
  115. if ( ! isset( $this->_pluginGroups[$plugin->type][$plugin->id] ) ) {
  116. $this->_pluginGroups[$plugin->type][$plugin->id] =& $this->_plugins[$plugin->id];
  117. }
  118. }
  119. }
  120. }
  121. }
  122. return true;
  123. }
  124. /**
  125.  * Returns array of plugins which got loaded through loadPluginGroup method for that $group
  126.  * Returns empty array() if none is loaded.
  127.  *
  128.  * @param  string  $group
  129.  * @return array           keyed array ( pluginid => plugin row ( + lookup = path to plugin files
  130.  */
  131. function & getLoadedPluginGroup( $group ) {
  132. if ( isset( $this->_pluginGroups[$group] ) ) {
  133. return $this->_pluginGroups[$group];
  134. } else {
  135. $array = array();
  136. return $array;
  137. }
  138. }
  139. /** utility: checks if all elements of array needles are in array haystack */
  140. function all_in_array($needles,$haystack) {
  141. if (is_array($needles)) {
  142. foreach ($needles as $needle) {
  143. if (!in_array($needle,$haystack)) return false;
  144. }
  145. } else {
  146. if (!in_array($needles,$haystack)) return false;
  147. }
  148. return true;
  149. }
  150. /** utility: checks if all elements of array needles are in array haystack */
  151. function all_in_array_key($needles,$haystack) {
  152. if (is_array($needles)) {
  153. foreach ($needles as $needle) {
  154. if (!array_key_exists($needle,$haystack)) return false;
  155. }
  156. } else {
  157. if (!array_key_exists($needles,$haystack)) return false;
  158. }
  159. return true;
  160. }
  161. function _setLoading( $plugin, $loading = true ) {
  162. $savePreviousPluginId = $this->_loading;
  163. if ( $loading === true ) {
  164. $this->_loading = $plugin->id;
  165. } elseif ( $loading === false) {
  166. $this->_loading = null;
  167. } else {
  168. $this->_loading = $loading;
  169. }
  170. return $savePreviousPluginId;
  171. }
  172. function _loadPluginFile($plugin) {
  173. global $_CB_framework, $_PLUGINS;
  174. $path = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $plugin->type . '/'. $plugin->folder . '/' . $plugin->element . '.php';
  175. if ( file_exists( $path ) && is_readable( $path ) ) {
  176. $savePreviousPluginId = $this->_setLoading( $plugin, true );
  177. require_once( $path );
  178. $this->_setLoading( $plugin, $savePreviousPluginId );
  179. return true;
  180. } else {
  181. return false;
  182. }
  183. }
  184. function getPluginId( ) {
  185. global $_PLUGINS;
  186. return $_PLUGINS->_loading;
  187. }
  188. function & getPluginObject( $pluginId = null ) {
  189. global $_PLUGINS;
  190. if ( $pluginId === null ) {
  191. $pluginId = $_PLUGINS->_loading;
  192. }
  193. return $_PLUGINS->_plugins[$pluginId];
  194. }
  195. function & getInstanceOfPluginClass( $class, $pluginId = null ) {
  196. global $_PLUGINS;
  197. if ( $pluginId === null ) {
  198. $pluginId = $_PLUGINS->_loading;
  199. }
  200. if ( ! isset( $this->_plugins[$pluginId]->classInstance[$class] ) ) {
  201. if ( ! isset( $this->_plugins[$pluginId]->classInstance ) ) {
  202. $this->_plugins[$pluginId]->classInstance = array();
  203. }
  204. $this->_plugins[$pluginId]->classInstance[$class] = new $class();
  205. $this->_plugins[$pluginId]->classInstance[$class]->_cbpluginid = $pluginId;
  206. }
  207. return $this->_plugins[$pluginId]->classInstance[$class];
  208. }
  209. /**
  210. * Gets a variable from the plugin class
  211. * @param int id of plugin
  212. * @param string name of plugin class
  213. * @param string name of class variable
  214. * @return mixed : variable's content
  215. */
  216. function getVar($pluginId, $class, $variable) {
  217. if ($class!=null && class_exists($class) && isset( $this->_plugins[$pluginId] ) ) {
  218. if ($this->_plugins[$pluginId]->published) {
  219. if (isset( $this->_plugins[$pluginId]->classInstance[$class]->$variable )) {
  220. return $this->_plugins[$pluginId]->classInstance[$class]->$variable;
  221. }
  222. }
  223. return false;
  224. }
  225. function getPluginPath() {
  226. global $_CB_framework, $_PLUGINS;
  227. // $plugin = $_PLUGINS->_pluginGroups[$this->type][$this->_cbpluginid]; //TBD: check for multiple classes per plugin ??? + getPluginCLass/vs. getTabCLass
  228. $plugin =& $_PLUGINS->_plugins[$this->_cbpluginid]; //TBD: remove those vars from here and make this function available to API
  229. $path = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $plugin->type . '/'. $plugin->folder;
  230. return $path;
  231. }
  232. function getPluginLIvePath() {
  233. global $_CB_framework, $_PLUGINS;
  234. // $plugin = $_PLUGINS->_pluginGroups[$this->type][$this->_cbpluginid]; //TBD: check for multiple classes per plugin ??? + getPluginCLass/vs. getTabCLass
  235. $plugin =& $_PLUGINS->_plugins[$this->_cbpluginid]; //TBD: remove those vars from here and make this function available to API
  236. $path = $_CB_framework->getCfg('live_site') . '/components/com_comprofiler/plugin/' . $plugin->type . '/'. $plugin->folder;
  237. return $path;
  238. }
  239. function _loadParams($pluginId, $extraParams=null) {
  240. global $_PLUGINS;
  241. $this->params = new cbParamsBase($_PLUGINS->_plugins[$pluginId]->params . "n" . $extraParams);
  242. }
  243. function & getParams() {
  244. return $this->params;
  245. }
  246. function getXml( $type = null, $typeValue = null ) {
  247. return null; // override if needed
  248. }
  249. /**
  250.  * FIELDS PLUGINS MANAGEMENT: through $_PLUGINS only:
  251.  */
  252. /**
  253. * Registers a field type which can be used by users
  254. *
  255. * @param array $typesArray  array of string of the names of types of fields
  256. * @param int   $pluginId    for CB internal plugin installer use ONLY: id of plugin to associate with field type
  257. */
  258. function registerUserFieldTypes( $typesArray, $pluginId = null ) {
  259. if ( $pluginId === null ) {
  260. $pluginId = $this->_loading;
  261. }
  262. foreach ( $typesArray as $type => $class ) {
  263. $this->_fieldTypes[$type] = array( $class, $pluginId );
  264. }
  265. }
  266. /**
  267.  * Returns array of field types
  268.  *
  269.  * @return array of string  Names of types registered
  270.  */
  271. function getUserFieldTypes( ) {
  272. return array_keys( $this->_fieldTypes );
  273. }
  274. /**
  275.  * Returns array of field types
  276.  *
  277.  * @param  string $fieldType  Type of field
  278.  * @return array of string    Names of types registered
  279.  */
  280. function getUserFieldPluginId( $fieldType ) {
  281. if (isset( $this->_fieldTypes[$fieldType] ) ) {
  282. return $this->_fieldTypes[$fieldType][1];
  283. }
  284. return null;
  285. }
  286. /**
  287. * Calls a function of a field type
  288. *
  289. * @param  string $fieldType  Type of field
  290. * @param  string $method     Method to call
  291. * @param  array  $args       An array of arguments
  292. * @return mixed  result of function call or NULL if non-existant
  293. */
  294. function callField( $fieldType, $method, $args = null, &$field ) {
  295. $result = null;
  296. if ($args === null) {
  297. $args = array();
  298. }
  299. if ( isset( $this->_fieldTypes[$fieldType] ) ) {
  300. $result = $this->call( $this->_fieldTypes[$fieldType][1], $method, $this->_fieldTypes[$fieldType][0], $args );
  301. }
  302. return $result;
  303. }
  304. /**
  305. * Registers field params for fields
  306. * @param  $class  name of class if overriding core class cbFieldParamsHandler which then needs to be extended.
  307. */
  308. function registerUserFieldParams( $class = null ) {
  309. $pluginId = $this->_loading;
  310. if ( $class === null ) {
  311. $class = 'cbFieldParamsHandler';
  312. }
  313. $this->_fieldParams[$pluginId] = $class;
  314. }
  315. /**
  316.  * Returns array of field types
  317.  *
  318.  * @return array of string  pluginid => Names of class
  319.  */
  320. function getUserFieldParamsPluginIds( ) {
  321. return $this->_fieldParams;
  322. }
  323. /**
  324.  * MENU MANAGEMENT:
  325.  */
  326. /**
  327.  * Adds a menu
  328.  * @access private
  329.  * 
  330.  * @param unknown_type $menuItem
  331.  */
  332. function _internalPLUGINSaddMenu( $menuItem ) {
  333. $this->_menus[] = $menuItem;
  334. }
  335. /**
  336. * Registers a menu or status item to a particular menu position
  337. * @param array a menu item like:
  338. // Test example:
  339. $mi = array(); $mi["_UE_MENU_CONNECTIONS"]["duplique"]=null;
  340. $this->addMenu( array( "position" => "menuBar" , // "menuBar", "menuList"
  341. "arrayPos" => $mi ,
  342. "caption" => _UE_MENU_MANAGEMYCONNECTIONS ,
  343. "url" => cbSef($ue_manageConnection_url) , // can also be "<a ....>" or "javascript:void(0)" or ""
  344. "target" => "" , // e.g. "_blank"
  345. "img" => null , // e.g. "<img src='plugins/user/myplugin/images/icon.gif' width='16' height='16' alt='' />"
  346. "alt" => null , // e.g. "text"
  347. "tooltip" => _UE_MENU_MANAGEMYCONNECTIONS_DESC ,
  348. "keystroke" => null ) ); // e.g. "P"
  349. // Test example: Member Since:
  350. $mi = array(); $mi["_UE_MENU_STATUS"]["_UE_MEMBERSINCE"]["dupl"]=null;
  351. $dat = cbFormatDate($user->registerDate);
  352. if (!$dat) $dat="?";
  353. $this->addMenu( array( "position" => "menuList" , // "menuBar", "menuList"
  354. "arrayPos" => $mi ,
  355. "caption" => $dat ,
  356. "url" => "" , // can also be "<a ....>" or "javascript:void(0)" or ""
  357. "target" => "" , // e.g. "_blank"
  358. "img" => null , // e.g. "<img src='plugins/user/myplugin/images/icon.gif' width='16' height='16' alt='' />"
  359. "alt" => null , // e.g. "text"
  360. "tooltip" => _UE_MEMBERSINCE_DESC ,
  361. "keystroke" => null ) ); // e.g. "P"
  362. */
  363. function addMenu( $menuItem ) {
  364. global $_PLUGINS;
  365. $_PLUGINS->_internalPLUGINSaddMenu($menuItem);
  366. }
  367. /**
  368. * Returns all menu items registered with addMenu
  369. * @param string The event name
  370. * @param string The function name
  371. */
  372. function getMenus() {
  373. return $this->_menus;
  374. }
  375. /**
  376.  * EVENTS AND TRIGGERS METHODS:
  377.  */
  378. /**
  379. * Registers a function to a particular event group
  380. * @param string The event name
  381. * @param string The function name
  382. */
  383. function registerFunction( $event, $method, $class=null ) {
  384. $this->_events[$event][] = array( $class,$method, $this->_loading );
  385. }
  386. /**
  387. * Calls all functions associated with an event group
  388. * @param string The event name
  389. * @param array An array of arguments
  390. * @return array An array of results from each function call
  391. */
  392. function trigger( $event, $args=null ) {
  393. $result = array();
  394. if ($args === null) {
  395. $args = array();
  396. }
  397. if (isset( $this->_events[$event] ) ) {
  398. foreach ($this->_events[$event] as $func) {
  399. $result[] = $this->call($func[2],$func[1],$func[0],$args);
  400. }
  401. }
  402. return $result;
  403. }
  404. function is_errors() {
  405. return $this->_iserror;
  406. }
  407. /**
  408. * Execute the plugin class/method pair
  409. * @param int id of plugin
  410. * @param string name of plugin variable
  411. * @param mixed value to assign (if any)
  412. * @return mixed : previous value
  413. */
  414. function plugVarValue($pluginid, $var, $value=null) {
  415. $preValue = $this->_plugins[$pluginid]->$var;
  416. if ( $value !== null ) {
  417. $this->_plugins[$pluginid]->$var = $value;
  418. }
  419. return $preValue;
  420. }
  421. /**
  422. * Execute the plugin class/method pair
  423. * @param $pluginid int id of plugin
  424. * @param $method string name of plugin method
  425. * @param $class string name of plugin class
  426. * @param $args array set of variables to path to class/method
  427. * @param $extraParams string additional parameters external to plugin params (e.g. tab params)
  428. * @return mixed : either string HTML for tab content, or false if ErrorMSG generated
  429. */
  430. function call( $pluginid, $method, $class, &$args, $extraParams = null, $ignorePublishedStatus = false ) {
  431. if ( $class != null && class_exists( $class ) ) {
  432. if ( $this->_plugins[$pluginid]->published || $ignorePublishedStatus ) {
  433. $pluginClassInstance =& $this->getInstanceOfPluginClass( $class, $pluginid );
  434. if (method_exists( $pluginClassInstance, $method )) {
  435. $pluginClassInstance->_loadParams( $pluginid, $extraParams );
  436. //BB1.2b7: really needed to have plugin row in tab and field classes called ??? element below should be enough: addVarsToClass($pluginClassInstance, $this->_plugins[$pluginid], array( 'params', 'classinstance' ));
  437. $pluginClassInstance->element = $this->_plugins[$pluginid]->element; // needed for _getPrefix for _getReqParam & co
  438. $savePreviousPluginId = $this->_loading;
  439. $this->_loading = $pluginid;
  440. $ret = call_user_func_array( array( &$pluginClassInstance, $method ), $args );
  441. $this->_loading = $savePreviousPluginId;
  442. return $ret;
  443. }
  444. }
  445. } elseif (function_exists( $method )) {
  446. if ( $this->_plugins[$pluginid]->published || $ignorePublishedStatus ) {
  447. $this->_loadParams($pluginid, $extraParams);
  448. $savePreviousPluginId = $this->_loading;
  449. $this->_loading = $pluginid;
  450. $ret = call_user_func_array( $method, $args );
  451. $this->_loading = $savePreviousPluginId;
  452. return $ret;
  453. }
  454. return false;
  455. }
  456. /**
  457. * PRIVATE method: sets the text of the last error
  458. * @access private
  459. *
  460. * @param  string   $msg   error message
  461. * @return boolean         true
  462. */
  463. function _setErrorMSG( $msg ) {
  464. $this->errorMSG[] = $msg;
  465. return true;
  466. }
  467. /**
  468. * Gets the text of the last error:
  469. * $separator == FALSE:  always returns array
  470. * $separator is string: returns null or string of errors
  471. *
  472. * @param  string|boolean  $separator   FALSE: return array, STRING: Separator between the errors which are imploded from array
  473. * @return string|array                 Text for error message or array of texts of error messages.
  474. */
  475. function getErrorMSG( $separator = "n" ) {
  476. if ( $separator === false ) {
  477. return $this->errorMSG;
  478. } else {
  479. $error = null;
  480. if ( count( $this->errorMSG ) > 0 ) {
  481. $error = implode( $separator, $this->errorMSG );
  482. }
  483. return $error;
  484. }
  485. }
  486. /**
  487. * PRIVATE method: sets the error condition and priority (for now 0)
  488. * @param error priority
  489. * @return boolean true
  490. */
  491. function raiseError($priority) {
  492. $this->_iserror=true;
  493. return true;
  494. }
  495. /**
  496. * Gets the debug text
  497. * @returns string text for debug
  498. */
  499. function getDebugMSG() {
  500. return $this->debugMSG;
  501. }
  502. /**
  503. * PRIVATE method: sets the text of the last error
  504. * @returns void
  505. */
  506. function _setDebugMSG($method,$msg) {
  507. $debugARRAY=array();
  508. $debugARRAY['class']=get_class($this);
  509. $debugARRAY['method']=$method;
  510. $debugARRAY['msg']=$msg;
  511. $this->debugMSG[]=$debugARRAY;
  512. return true;
  513. }
  514. /**
  515.  * XML LOAD AND ACCESS METHOD:
  516.  */
  517. /**
  518.  * xml file for plugin
  519.  *
  520.  * @param  string             $actionType
  521.  * @param  string             $action
  522.  * @param  int                $pluginId
  523.  * @return CBSimpleXMLElement
  524.  */
  525. function & loadPluginXML( $actionType, $action, $pluginId = null ) {
  526. global $_CB_framework;
  527. static $cache = array();
  528. cbimport('cb.xml.simplexml');
  529. $row =& $this->getPluginObject( $pluginId );
  530. $xmlString = null;
  531. if ( $row ) {
  532. // security sanitization to disable use of `/`, `\` and `:` in $action variable
  533. $unsecureChars = array( '/', '\', ':', ';', '{', '}', '(', ')', """, "'", '.', ',', "", ' ', "t", "n", "r", "x0B" );
  534. $classname = 'CBplug_' . strtolower( substr( str_replace( $unsecureChars, '', $row->element ), 0, 32 ) );
  535. $action_cleaned = strtolower( substr( str_replace( $unsecureChars, '', $action ),   0, 32 ) );
  536. if ( isset( $cache[$classname][$actionType][$action_cleaned] ) ) {
  537. return $cache[$classname][$actionType][$action_cleaned];
  538. }
  539. if ( class_exists( $classname ) ) {
  540. // class CBplug_pluginname exists:
  541. if ( ( $_CB_framework->getUi() == 2 ) && is_callable( array( $classname, 'loadAdmin' ) ) ) {
  542. // function loadAdmin exists:
  543. $array = array();
  544. $this->call( $row->id, 'loadAdmin', $classname, $array, null, true );
  545. }
  546. // $xmlString = $pluginClass->getXml( 'action', $action_cleaned );
  547. $array = array( $actionType, $action_cleaned );
  548. $xmlString = $this->call( $row->id, 'getXml', $classname, $array, null, true );
  549. if ( $xmlString ) {
  550. $cache[$classname][$actionType][$action_cleaned] =& new CBSimpleXMLElement( $xmlString );
  551. return $cache[$classname][$actionType][$action_cleaned];
  552. }
  553. }
  554. if ( $action_cleaned ) {
  555. // try action-specific file: xml/edit.actiontype.xml :
  556. $xmlfile = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' .$row->type . '/'.$row->folder . '/xml/edit.' . $actionType . '.' . $action_cleaned .'.xml';
  557. if ( file_exists( $xmlfile ) ) {
  558. $cache[$classname][$actionType][$action_cleaned] =& new CBSimpleXMLElement( trim( file_get_contents( $xmlfile ) ) );
  559. return $cache[$classname][$actionType][$action_cleaned];
  560. }
  561. }
  562. // try specific file for after installations: xml/edit.plugin.xml :
  563. $xmlfile = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $row->type . '/' . $row->folder . '/xml/edit.plugin.xml';
  564. if ( file_exists( $xmlfile ) ) {
  565. $cache[$classname][$actionType][$action_cleaned] =& new CBSimpleXMLElement( trim( file_get_contents( $xmlfile ) ) );
  566. return $cache[$classname][$actionType][$action_cleaned];
  567. }
  568. // try plugin installation file:
  569. $xmlfile = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $row->type . '/' . $row->folder . '/' . $row->element . '.xml';
  570. if ( isset( $cache[$xmlfile] ) ) {
  571. return $cache[$xmlfile];
  572. } else {
  573. if ( file_exists( $xmlfile ) ) {
  574. $cache[$xmlfile] =& new CBSimpleXMLElement( trim( file_get_contents( $xmlfile ) ) );
  575. return $cache[$xmlfile];
  576. }
  577. }
  578. $row->description = '<b><font style="color:red;">Plugin not installed</font></b>';
  579. }
  580. $element = null;
  581. return $element;
  582. }
  583. } // end class cbPluginHandler
  584. /**
  585. * Event Class for handling the CB event api
  586. * @package Community Builder
  587. * @author JoomlaJoe
  588. */
  589. class cbEventHandler extends cbPluginHandler  {
  590. /**
  591. * Constructor
  592. */
  593. function cbEventHandler() {
  594. $this->cbPluginHandler();
  595. }
  596. }
  597. /**
  598. * Field Class for handling the CB field api
  599. * @package Community Builder
  600. * @author Beat
  601. */
  602. class cbFieldHandler extends cbPluginHandler  {
  603. /** Plugin of this field
  604.  * @var moscomprofilerPlugin */
  605. var $_plugin = null;
  606. /** XML of the Plugin of this field
  607.  * @var CBSimpleXMLElement */
  608. var $_xml = null;
  609. /** XML of this field
  610.  * @var CBSimpleXMLElement */
  611. var $_fieldXml = null;
  612. /**
  613. * Constructor
  614. */
  615. function cbFieldHandler() {
  616. $this->cbPluginHandler();
  617. }
  618. /**
  619.  * Overridable methods:
  620.  */
  621. /**
  622.  * Initializer:
  623.  * Puts the default value of $field into $user (for registration or new user in backend)
  624.  *
  625.  * @param  moscomprofilerFields  $field
  626.  * @param  moscomprofilerUser    $user
  627.  * @param  string                $reason      'profile' for user profile view and edit, 'register' for registration
  628.  */
  629. function initFieldToDefault( &$field, &$user, $reason ) {
  630. foreach ( $field->getTableColumns() as $col ) {
  631. $user->$col = $field->default;
  632. }
  633. }
  634. /**
  635.  * Formatter:
  636.  * Returns a field in specified format
  637.  *
  638.  * @param  moscomprofilerFields  $field
  639.  * @param  moscomprofilerUser    $user
  640.  * @param  string                $output      'html', 'xml', 'json', 'php', 'csvheader', 'csv', 'rss', 'fieldslist', 'htmledit'
  641.  * @param  string                $formatting  'tr', 'td', 'div', 'span', 'none',   'table'??
  642.  * @param  string                $reason      'profile' for user profile view and edit, 'register' for registration, 'search' for searches
  643.  * @return mixed                
  644.  */
  645. function getFieldRow( &$field, &$user, $output, $formatting, $reason ) {
  646. global $ueConfig, $_CB_OneTwoRowsStyleToggle;
  647. $results = null;
  648. $oValue = $this->getField( $field, $user, $output, $reason );
  649. if ( ( ! ( $oValue != null || trim($oValue) != '' ) )
  650. && ( $output == 'html' )
  651. && isset( $ueConfig['showEmptyFields'] ) && ( $ueConfig['showEmptyFields'] == 1 )
  652. && ( $reason != 'search' )
  653. && ( $field->displaytitle == 1 )
  654. )
  655. {
  656. $oValue = cbReplaceVars( $ueConfig['emptyFieldsText'], $user );
  657. }
  658. if ( $oValue != null || trim($oValue) != '' ) {
  659. if ( cbStartOfStringMatch( $output, 'html' ) ) {
  660. switch ( $formatting ) {
  661. case 'table':
  662. // ?
  663. break;
  664. case 'tr':
  665. $class  = 'sectiontableentry' . $_CB_OneTwoRowsStyleToggle;
  666. $_CB_OneTwoRowsStyleToggle = ( $_CB_OneTwoRowsStyleToggle == 1 ? 2 : 1 );
  667. $results .= "ntttt<tr class="" . $class. '" id="cbfr_' . $field->fieldid . '">';
  668. $colspan = ( ( $field->profile == 2 ) ? ' colspan="2"' : '' );
  669. if ( ( $field->displaytitle === null ) || ( $field->displaytitle == 1 ) || ( $output == 'htmledit' ) ) {
  670. $translatedTitle = $this->getFieldTitle( $field, $user, $output, $reason );
  671. if ( trim( $translatedTitle ) == '' ) {
  672. $colspan = ' colspan="2"'; // CB 1.0-1.1 backwards compatibility
  673. }
  674. } else {
  675. $translatedTitle = '';
  676. }
  677. if( trim( $translatedTitle ) != '' ) {
  678. $results .= "nttttt<td class="titleCell"" . $colspan .'>'
  679. . ( ( $field->displaytitle != -1 ) ? '<label for="' . ( $output == 'htmledit' ? htmlspecialchars( $field->name ) : 'cbfl_' . $field->fieldid ) . '">' : '' )
  680. . $translatedTitle
  681. . ':'
  682. . ( ( $field->displaytitle != -1 ) ? '</label>' : '' )
  683. . '</td>';
  684. if ( $field->profile == 2 ) {
  685. $results .= "ntttt</tr>"
  686. . "ntttt<tr class="" . $class . '">';
  687. }
  688. }
  689. $results .= "nttttt<td" . $colspan . ' class="fieldCell" id="cbfv_' . $field->fieldid . '">' . $oValue . '</td>';
  690. $results .= "ntttt</tr>";
  691. break;
  692. case 'td':
  693. $results .= "nttttt" . '<td class="fieldCell" id="cbfv_' . $field->fieldid . '">' . $oValue . '</td>';
  694. break;
  695. case 'div':
  696. $class  = 'sectiontableentry' . $_CB_OneTwoRowsStyleToggle;
  697. $_CB_OneTwoRowsStyleToggle = ( $_CB_OneTwoRowsStyleToggle == 1 ? 2 : 1 );
  698. $translatedTitle = $this->getFieldTitle( $field, $user, $output, $reason );
  699. $results .= "ntttt"
  700. . '<div class="' . $class . ' cb_form_line cbclearboth" id="cbfr_' . $field->fieldid . '">';
  701. if ( trim( $translatedTitle ) != '' ) {
  702. $results .= ( ( $field->displaytitle != -1 ) ? '<label for="' . ( $output == 'htmledit' ? htmlspecialchars( $field->name ) : 'cbfv_' . $field->fieldid ) . '">' : '' )
  703. . $translatedTitle
  704. . ':'
  705. . ( ( $field->displaytitle != -1 ) ? '</label>' : '' )
  706. ;
  707. }
  708. $results .= '<div class="cb_field"><div id="cbfv_' . $field->fieldid . '">'
  709. . $oValue
  710. . '</div>'
  711. // <div class="cb_result_container"><div id="checkemail__Response">&nbsp;</div></div> // space for AJAX reply
  712. . '</div></div>'
  713. ;
  714. break;
  715. case 'span':
  716. $results .= '<span class="cb_field"><span id="cbfv_' . $field->fieldid . '">'
  717. . $oValue
  718. . '</span></span>';
  719. break;
  720. case 'none':
  721. $results = $oValue;
  722. break;
  723. default:
  724. $results = '*' . $oValue . '*';
  725. break;
  726. }
  727. } else {
  728. $results = $oValue;
  729. }
  730. }
  731. return $results;
  732. }
  733. /**
  734.  * Accessor:
  735.  * Returns a field in specified format
  736.  *
  737.  * @param  moscomprofilerFields  $field
  738.  * @param  moscomprofilerUser    $user
  739.  * @param  string                $output  'html', 'xml', 'json', 'php', 'csvheader', 'csv', 'rss', 'fieldslist', 'htmledit'
  740.  * @param  string                $reason  'profile' for user profile view and edit, 'register' for registration, 'list' for user-lists
  741.  * @return mixed
  742.  */
  743. function getField( &$field, &$user, $output, $reason ) {
  744. $valuesArray = array();
  745. foreach ( $field->getTableColumns() as $col ) {
  746. $valuesArray[] = $user->get( $col );
  747. }
  748. $value = implode( ', ', $valuesArray );
  749. switch ( $output ) {
  750. case 'html':
  751. case 'rss':
  752. return $this->_formatFieldOutput( $field->name, $value, $output, true );
  753. case 'htmledit':
  754. if ( $reason == 'search' ) {
  755. return $this->_fieldSearchModeHtml( $field, $user, $this->_fieldEditToHtml( $field, $user, $reason, 'input', $field->type, $value, '' ), 'text' );
  756. } else {
  757. return $this->_fieldEditToHtml( $field, $user, $reason, 'input', $field->type, $value, '' );
  758. }
  759. break;
  760. default:
  761. return $this->_formatFieldOutput( $field->name, $value, $output, false );
  762. break;
  763. }
  764. }
  765. /**
  766.  * Labeller for title:
  767.  * Returns a field title
  768.  *
  769.  * @param  moscomprofilerFields  $field
  770.  * @param  moscomprofilerUser    $user
  771.  * @param  string                $output  'text' or: 'html', 'htmledit', (later 'xml', 'json', 'php', 'csvheader', 'csv', 'rss', 'fieldslist')
  772.  * @param  string                $reason  'profile' for user profile view and edit, 'register' for registration, 'list' for user-lists
  773.  * @return string
  774.  */
  775. function getFieldTitle( &$field, &$user, $output, $reason ) {
  776. if ( $output === 'text' ) {
  777. return strip_tags( cbReplaceVars( $field->title, $user ) );
  778. } else {
  779. return cbReplaceVars( $field->title, $user );
  780. }
  781. }
  782. /**
  783.  * Labeller for description:
  784.  * Returns a field title
  785.  *
  786.  * @param  moscomprofilerFields  $field
  787.  * @param  moscomprofilerUser    $user
  788.  * @param  string                $output  'text' or: 'html', 'xml', 'json', 'php', 'csvheader', 'csv', 'rss', 'fieldslist', 'htmledit'
  789.  * @param  string                $reason  'profile' for user profile view and edit, 'register' for registration, 'list' for user-lists
  790.  * @return string
  791.  */
  792. function getFieldDescription( &$field, &$user, $output, $reason ) {
  793. if ( $output === 'text' ) {
  794. return strip_tags( cbReplaceVars( $field->description, $user ) );
  795. } elseif ( $output === 'htmledit' ) {
  796. return cbReplaceVars( $field->description, $user );
  797. } else {
  798. return null;
  799. }
  800. }
  801. /**
  802.  * Mutator:
  803.  * Prepares field data for saving to database (safe transfer from $postdata to $user)
  804.  * Override
  805.  *
  806.  * @param  moscomprofilerFields  $field
  807.  * @param  moscomprofilerUser    $user      RETURNED populated: touch only variables related to saving this field (also when not validating for showing re-edit)
  808.  * @param  array                 $postdata  Typically $_POST (but not necessarily), filtering required.
  809.  * @param  string                $reason    'profile' for save user edit, 'register' for save registration
  810.  * @return boolean                          True: All fields have validated, False: Some fields didn't validate
  811.  */
  812. function prepareFieldDataSave( &$field, &$user, &$postdata, $reason ) {
  813. $this->_prepareFieldMetaSave( $field, $user, $postdata, $reason );
  814. foreach ( $field->getTableColumns() as $col ) {
  815. $value = cbGetParam( $postdata, $col );
  816. if ( ( $value !== null ) && ! is_array( $value ) ) {
  817. $value = stripslashes( $value );
  818. $this->validate( $field, $user, $col, $value, $postdata, $reason );
  819. $user->$col = $value;
  820. }
  821. }
  822. return true; //TBD: validation
  823. }
  824. /**
  825.  * Validator:
  826.  * Validates $value for $field->required and other rules
  827.  * Override
  828.  *
  829.  * @param  moscomprofilerFields  $field
  830.  * @param  moscomprofilerUser    $user        RETURNED populated: touch only variables related to saving this field (also when not validating for showing re-edit)
  831.  * @param  string                $columnName  Column to validate
  832.  * @param  string                $value       (RETURNED:) Value to validate, Returned Modified if needed !
  833.  * @param  array                 $postdata    Typically $_POST (but not necessarily), filtering required.
  834.  * @param  string                $reason      'profile' for save user edit, 'register' for save registration
  835.  * @return boolean                            True if validate, $this->_setErrorMSG if False
  836.  */
  837. function validate( &$field, &$user, $columnName, &$value, &$postdata, $reason ) {
  838. global $_CB_framework, $ueConfig;
  839. if ( ( $_CB_framework->getUi() == 1 ) || ( ( $_CB_framework->getUi() == 2 ) && ( $ueConfig['adminrequiredfields'] == 1 ) ) ) {
  840. // Required field:
  841. if ( ( $field->required == 1 ) && ( $value == '' ) ) {
  842. $this->_setValidationError( $field, $user, $reason, unHtmlspecialchars(_UE_REQUIRED_ERROR) );
  843. return false;
  844. }
  845. $len = strlen( $value );
  846. // Minimum field length:
  847. if ( $field->name == 'password' ) {
  848. $defaultMin = 6;
  849. } elseif ( $field->name == 'username' ) {
  850. $defaultMin = 3;
  851. } else {
  852. $defaultMin = 0;
  853. }
  854. $fieldMinLength = $field->params->get( 'fieldMinLength', $defaultMin );
  855. if ( ( $len > 0 ) && ( $len < $fieldMinLength ) ) {
  856. $this->_setValidationError( $field, $user, $reason, sprintf( _UE_VALID_MIN_LENGTH, $this->getFieldTitle( $field, $user, 'text', $reason ), $fieldMinLength, $len ) );
  857. return false;
  858. }
  859. // Maximum field length:
  860. $fieldMaxLength = $field->maxlength;
  861. if ( $fieldMaxLength && ( $len > $fieldMaxLength ) ) {
  862. $this->_setValidationError( $field, $user, $reason, sprintf( _UE_VALID_MAX_LENGTH, $this->getFieldTitle( $field, $user, 'text', $reason ), $fieldMaxLength, $len ) );
  863. return false;
  864. }
  865. // Bad words:
  866. if ( ( $reason == 'register' ) && ( in_array( $field->type, array( 'emailaddress', 'primaryemailaddress', 'textarea', 'text', 'webaddress', 'predefined' ) ) ) ) {
  867. $defaultForbidden = 'http:,https:,mailto:,//.[url],<a,</a>,&#';
  868. } else {
  869. $defaultForbidden = '';
  870. }
  871. $forbiddenContent = $field->params->get( 'fieldValidateForbiddenList_' . $reason, $defaultForbidden );
  872. if ( $forbiddenContent != '' ) {
  873. $forbiddenContent = explode( ',', $forbiddenContent );
  874. $replaced = str_replace( $forbiddenContent, '', $value );
  875. if ( $replaced != $value ) {
  876. $this->_setValidationError( $field, $user, $reason, _UE_INPUT_VALUE_NOT_ALLOWED );
  877. return false;
  878. }
  879. }
  880. }
  881. return true;
  882. }
  883. /**
  884.  * Finder:
  885.  * Prepares field data for saving to database (safe transfer from $postdata to $user)
  886.  * Override
  887.  *
  888.  * @param  moscomprofilerFields  $field
  889.  * @param  moscomprofilerUser    $searchVals  RETURNED populated: touch only variables related to saving this field (also when not validating for showing re-edit)
  890.  * @param  array                 $postdata    Typically $_POST (but not necessarily), filtering required.
  891.  * @param  string                $reason      'profile' for save user edit, 'register' for save registration
  892.  * @return boolean                            True: All fields have validated, False: Some fields didn't validate
  893.  */
  894. function bindSearchCriteria( &$field, &$searchVals, &$postdata, $reason ) {
  895. $query = array();
  896. $searchMode = $this->_bindSearchMode( $field, $searchVals, $postdata );
  897. if ( $searchMode ) {
  898. foreach ( $field->getTableColumns() as $col ) {
  899. $value = cbGetParam( $postdata, $col );
  900. if ( ( $value !== null ) && ( $value !== '' ) && ! is_array( $value ) ) {
  901. $value = stripslashes( $value );
  902. $searchVals->$col = $value;
  903. // $this->validate( $field, $user, $col, $value, $postdata, $reason );
  904. $sql = new cbSqlQueryPart();
  905. $sql->tag = 'column';
  906. $sql->name = $col;
  907. $sql->table = $field->table;
  908. $sql->type = 'sql:field';
  909. $sql->operator = '=';
  910. $sql->value = $value;
  911. $sql->valuetype = 'const:string';
  912. $sql->searchmode = $searchMode;
  913. $query[] = $sql;
  914. }
  915. }
  916. }
  917. return $query;
  918. }
  919. /**
  920.  * Returns a field in specified format
  921.  *
  922.  * @param  moscomprofilerField  $field
  923.  * @param  moscomprofilerUser   $user
  924.  * @param  string               $output  NO 'htmledit' BUT: 'html', 'xml', 'json', 'php', 'csvheader', 'csv', 'rss', 'fieldslist', 'htmledit'
  925.  * @param  boolean              $htmlspecialchars  TRUE: escape for display, FALSE: not escaped will display raw.
  926.  * @return mixed                
  927.  */
  928. function _formatFieldOutput( $name, $value, $output, $htmlspecialchars = true ) {
  929. switch ( $output ) {
  930. case 'html':
  931. case 'rss':
  932. case 'htmledit':
  933. if ( $htmlspecialchars ) {
  934. return htmlspecialchars( $value );
  935. } else {
  936. return $value;
  937. }
  938. break;
  939. case 'xml':
  940. if ( $htmlspecialchars ) {
  941. return '<' . $name . '>' . htmlspecialchars( htmlspecialchars( $value ) ) . '</' . $name . '>';
  942. } else {
  943. return '<' . $name . '>' . htmlspecialchars( $value ) . '</' . $name . '>';
  944. }
  945. break;
  946. case 'json':
  947. return "'" . $name . "' : '" . addslashes( $value ) . "'";
  948. break;
  949. case 'php':
  950. return array( $name => $value );
  951. break;
  952. case 'csvheader':
  953. case 'fieldslist':
  954. return $name;
  955. break;
  956. case 'csv':
  957. return '"' . addslashes( $value ) . '"';
  958. break;
  959. default:
  960. trigger_error( '_formatFieldOutput called with ' . htmlspecialchars( $output ), E_USER_WARNING );
  961. return $value;
  962. break;
  963. }
  964. }
  965. /**
  966.  * Returns a field in specified format
  967.  *
  968.  * @param  moscomprofilerField  $field
  969.  * @param  moscomprofilerUser   $user
  970.  * @param  string               $output  NO 'htmledit' BUT: 'html', 'xml', 'json', 'php', 'csvheader', 'csv', 'rss', 'fieldslist', 'htmledit'
  971.  * @return mixed                
  972.  */
  973. function _formatFieldOutputIntBoolFloat( $name, $value, $output ) {
  974. switch ( $output ) {
  975. case 'html':
  976. case 'rss':
  977. return $value; 
  978. break;
  979. case 'htmledit':
  980. trigger_error( '_formatFieldOutput called with htmledit', E_USER_WARNING );
  981. return null;
  982. break;
  983. case 'xml':
  984. return '<' . $name . '>' . $value . '</' . $name . '>';
  985. break;
  986. case 'json':
  987. return "'" . $name . "' : " . $value;
  988. break;
  989. case 'php':
  990. return array( $name => $value );
  991. break;
  992. case 'csvheader':
  993. case 'fieldslist':
  994. return $name;
  995. break;
  996. case 'csv':
  997. return $value;
  998. default:
  999. trigger_error( '_formatFieldOutput called with ' . htmlspecialchars( $output ), E_USER_WARNING );
  1000. return $value;
  1001. break;
  1002. }
  1003. }
  1004. /**
  1005.  * Reformats a PHP array into $output format
  1006.  *
  1007.  * @param  array   $retArray  Named array
  1008.  * @param  string  $output  'html', 'xml', 'json', 'php', 'csvheader', 'csv', 'rss', 'fieldslist', 'htmledit'
  1009.  * @return mixed
  1010.  */
  1011. function _arrayToFormat( &$retArray, $output ) {
  1012. switch ( $output ) {
  1013. case 'html':
  1014. case 'rss':
  1015. $imploded = null;
  1016. foreach ( $retArray as $res ) {
  1017. if ( isset( $res['url' ] ) ) {
  1018. $imploded .= '<a href="' . cbSef( $res["url"] ) . '" title="' . getLangDefinition( $res["tooltip"] ) . '">' . $res['title'] . '</a> ';
  1019. }
  1020. }
  1021. return $imploded;
  1022. break;
  1023. case 'htmledit':
  1024. break;
  1025. case 'xml':
  1026. break;
  1027. case 'json':
  1028. break;
  1029. case 'php':
  1030. break;
  1031. case 'csvheader':
  1032. case 'fieldslist':
  1033. break;
  1034. case 'csv':
  1035. default:
  1036. break;
  1037. }
  1038. trigger_error( '_arrayToFormat called with non-implemented output type: ' . htmlspecialchars( $output ), E_USER_WARNING );
  1039. }
  1040. /**
  1041.  * Private methods for front-end:
  1042.  */
  1043. /**
  1044.  * converts to HTML
  1045.  *
  1046.  * @param  moscomprofilerFields  $field
  1047.  * @param  moscomprofilerUser    $user
  1048.  * @param  string                $reason      'profile' for user profile view and edit, 'register' for registration
  1049.  * @param  string                $tag         <tag
  1050.  * @param  string                $type        type="$type"
  1051.  * @param  string                $value       value="$value"
  1052.  * @param  string                $additional  'xxxx="xxx" yy="y"'
  1053.  * @param  string                $allValues   
  1054.  * @param  boolean               $displayFieldIcons
  1055.  * @return string                            HTML: <tag type="$type" value="$value" xxxx="xxx" yy="y" />
  1056.  */
  1057. function _fieldEditToHtml( &$field, &$user, $reason, $tag, $type, $value, $additional, $allValues = null, $displayFieldIcons = true ) {
  1058. global $_CB_framework, $ueConfig;
  1059. $readOnly = $this->_isReadOnly( $field, $user, $reason );
  1060. $oReq = $this->_isRequired( $field, $user, $reason );
  1061. if ( $readOnly ) { 
  1062. $additional .= ' disabled="disabled"';
  1063. $oReq = 0;
  1064. }
  1065. if ( $oReq ) {
  1066. $additional .= ' mosReq="1"' //TBD: replace by class
  1067. . ' mosLabel="' . htmlspecialchars( $this->getFieldTitle( $field, $user, 'text', $reason ) ) . '"';
  1068. }
  1069. if ( $field->size > 0 ) {
  1070. $additional .= " size='" . $field->size . "' ";
  1071. }
  1072. $inputName = $field->name;
  1073. switch ( $type ) {
  1074. case 'radio':
  1075. return moscomprofilerHTML::radioListTable( $allValues, $inputName, $additional, 'value', 'text', $value, $field->cols, $field->rows, $field->size, $oReq )
  1076. . $this->_fieldIconsHtml( $field, $user, 'htmledit', $reason, $tag, $type, $value, $additional, $allValues, $displayFieldIcons, $oReq );
  1077. break;
  1078. case 'multiselect':
  1079. $additional .= ' multiple="multiple"';
  1080. $inputName .= '[]';
  1081. // no break on purpose for fall-through:
  1082. case 'select':
  1083. $additional .= ' class="inputbox"';
  1084. return moscomprofilerHTML::selectList( $allValues, $inputName, $additional, 'value', 'text', $this->_explodeCBvalues( $value ), $oReq )
  1085. . $this->_fieldIconsHtml( $field, $user, 'htmledit', $reason, $tag, $type, $value, $additional, $allValues, $displayFieldIcons, $oReq );
  1086. break;
  1087. case 'multicheckbox':
  1088. $additional .= ' size="' . $field->size . '"';
  1089. return moscomprofilerHTML::checkboxListTable( $allValues, $inputName . '[]', $additional, 'value', 'text', $this->_explodeCBvalues( $value ), $field->cols, $field->rows, $field->size, $oReq )
  1090. . $this->_fieldIconsHtml( $field, $user, 'htmledit', $reason, $tag, $type, $value, $additional, $allValues, $displayFieldIcons, $oReq );
  1091. break;
  1092. case 'text':
  1093. case 'primaryemailaddress':
  1094. case 'emailaddress':
  1095. case 'webaddress':
  1096. case 'predefined':
  1097. case 'password':
  1098. if ( $field->size = 0 ) {
  1099. $additional .= " size='25' ";
  1100. }
  1101. if ( $field->maxlength > 0 ) {
  1102. $additional .= ' maxlength="' . $field->maxlength . '"';
  1103. }
  1104. $additional .= ' class="inputbox"';
  1105. break;
  1106. case 'textarea':
  1107. $tag = 'textarea';
  1108. $type = null;
  1109. $additional .= ' class="inputbox"';
  1110. if ( $field->cols > 0 ) {
  1111. $additional .= ' cols="' . $field->cols . '"';
  1112. }
  1113. if ( $field->rows > 0 ) {
  1114. $additional .= ' rows="' . $field->rows . '"';
  1115. }
  1116. break;
  1117. case 'html':
  1118. return $value;
  1119. break;
  1120. default:
  1121. break;
  1122. }
  1123. $htmlDescription = $this->getFieldDescription( $field, $user, 'htmledit', $reason );
  1124. return '<' . $tag
  1125. . ( $type ? ' type="' . $type . '"' : '' )
  1126. . ' name="' . $inputName . '" id="' . $inputName . '"'
  1127. . ( $tag == 'textarea' ? '' : ' value="' . htmlspecialchars( $value ) . '"' )
  1128. . ( $additional ? ' ' . $additional : '' )
  1129. . ( trim( strip_tags( $htmlDescription ) ) ? ' title="' . htmlspecialchars( $this->getFieldTitle( $field, $user, 'html', $reason ) ) . ':' . htmlspecialchars( $htmlDescription ) . '"' : '' )
  1130. . ( $tag == 'textarea' ? '>' .  htmlspecialchars( $value ) . '</textarea>' : ' />' )
  1131. . $this->_fieldIconsHtml( $field, $user, 'htmledit', $reason, $tag, $type, $value, $additional, $allValues, $displayFieldIcons, $oReq )
  1132. ;
  1133. }
  1134. function _fieldIconsHtml( &$field, &$user, $output, $reason, $tag, $type, $value, $additional, $allValues, $displayFieldIcons, $required ) {
  1135. global $_CB_framework, $_PLUGINS;
  1136. $results = $_PLUGINS->trigger( 'onFieldIcons', array( &$field, &$user, $reason, $tag, $type, $value, $additional, $allValues, $displayFieldIcons, $required ) );
  1137. if ( count( $results ) > 0 ) {
  1138. return implode( '', $results );
  1139. } else {
  1140. if ( $displayFieldIcons && ( $reason != 'search' ) ) {
  1141. return getFieldIcons( $_CB_framework->getUi(), ( $required && ( $reason != 'search' ) ), ( $reason != 'search' ? $field->profile : null ), $this->getFieldDescription( $field, $user, $output, $reason ), $this->getFieldTitle( $field, $user, $output, $reason ) );
  1142. } else {
  1143. return null;
  1144. }
  1145. }
  1146. }
  1147. function _isRequired( &$field, &$user, $reason ) {
  1148. global $_CB_framework, $ueConfig;
  1149. $adminReq = $field->required;
  1150. if ( ( $_CB_framework->getUi() == 2 )
  1151. && ( $ueConfig['adminrequiredfields']==0 )
  1152. && ! in_array( $field->name, array( 'username', 'email', 'name', 'firstname', 'lastname' ) ) )
  1153. {
  1154. $adminReq = 0;
  1155. }
  1156. return $adminReq;
  1157. }
  1158. function _isReadOnly( &$field, &$user, $reason ) {
  1159. global $_CB_framework;
  1160. $readOnly = $field->readonly;
  1161. if ( ( $_CB_framework->getUi() == 2 ) || ( in_array( $reason, array( 'register', 'search' ) ) ) ) {
  1162. $readOnly = 0;
  1163. }
  1164. return $readOnly;
  1165. }
  1166. function _valueDoesntMatter( &$field, $reason, $noneValue = false ) {
  1167. $value = new stdClass();
  1168. $value->id = 'cbf0_' . $field->fieldid;
  1169. $value->value = '';
  1170. $value->text = ( $reason == 'search' ? ( $noneValue ? _UE_NONE : _UE_NO_PREFERENCE ) : _UE_NO_INDICATION );
  1171. return $value;
  1172. }
  1173. function _explodeCBvalues( $value ) {
  1174. if ( ! is_array( $value ) ) {
  1175. $value = explode( '|*|', $value );
  1176. }
  1177. $objArr = array();
  1178. foreach( $value as $k => $kv ) {
  1179. $objArr[$k]->value = $kv;
  1180. $objArr[$k]->text = $kv;
  1181. }
  1182. return $objArr;
  1183. }
  1184. /**
  1185.  * Outputs search format including $html being html with input fields
  1186.  *
  1187.  * @param  moscomprofilerFields  $field
  1188.  * @param  moscomprofilerUser    $user
  1189.  * @param  string                $html
  1190.  * @param  string                $type   'text', 'choice', 'isisnot', 'none'
  1191.  * @param  string                $class  Extra-class (e.g. for jQuery)
  1192.  * @return string
  1193.  */
  1194. function _fieldSearchModeHtml( &$field, &$user, $html, $type, $class = '' ) {
  1195. $col = $field->name . '__srmch';
  1196. $selected = $user->get( $col );
  1197. switch ( $type ) {
  1198. case 'text':
  1199. $choices = array( 'is' => _UE_MATCH_IS_EXACTLY,
  1200. 'phrase' => _UE_MATCH_PHRASE,
  1201. 'all' => _UE_MATCH_ALL,
  1202. 'any' => _UE_MATCH_ANY,
  1203. '-' => _UE_MATCH_EXCLUSIONS . ':',
  1204. 'isnot' => _UE_MATCH_IS_EXACTLY_NOT,
  1205. 'phrasenot' => _UE_MATCH_PHRASE_NOT,
  1206. 'allnot' => _UE_MATCH_ALL_NOT,
  1207. 'anynot' => _UE_MATCH_ANY_NOT
  1208. );
  1209. break;
  1210. case 'singlechoice':
  1211. $choices = array( 'is' => _UE_MATCH_IS,
  1212. // 'is' => _UE_MATCH_IS_EXACTLY,
  1213. // 'phrase' => _UE_MATCH_PHRASE,
  1214. // 'all' => _UE_MATCH_ALL,
  1215. 'anyis' => _UE_MATCH_IS_ONE_OF, // _UE_MATCH_ANY,
  1216. '-' => _UE_MATCH_EXCLUSIONS . ':',
  1217. 'isnot' => _UE_MATCH_IS_NOT,
  1218. // 'phrasenot' => _UE_MATCH_PHRASE_NOT,
  1219. // 'allnot' => _UE_MATCH_ALL_NOT,
  1220. 'anyisnot' => _UE_MATCH_IS_NOT_ONE_OF // _UE_MATCH_ANY_NOT
  1221. );
  1222. break;
  1223. case 'multiplechoice':
  1224. $choices = array( 'is' => _UE_MATCH_ARE_EXACTLY,
  1225. // 'phrase' => _UE_MATCH_PHRASE,
  1226. 'all' => _UE_MATCH_INCLUDE_ALL_OF,
  1227. 'any' => _UE_MATCH_INCLUDE_ANY_OF,
  1228. '-' => _UE_MATCH_EXCLUSIONS . ':',
  1229. 'isnot' => _UE_MATCH_ARE_EXACTLY_NOT,
  1230. // 'phrasenot' => _UE_MATCH_PHRASE_NOT,
  1231. 'allnot' => _UE_MATCH_INCLUDE_ALL_OF_NOT,
  1232. 'anynot' => _UE_MATCH_INCLUDE_ANY_OF_NOT
  1233. );
  1234. break;
  1235. case 'isisnot':
  1236. $choices = array( 'is' => _UE_MATCH_IS,
  1237. '-' => _UE_MATCH_EXCLUSIONS . ':',
  1238. 'isnot' => _UE_MATCH_IS_NOT
  1239. );
  1240. break;
  1241. case 'none':
  1242. default:
  1243. $choices = null;
  1244. break;
  1245. }
  1246. if ( $choices !== null ) {
  1247. $drop = array();
  1248. $drop[] = moscomprofilerHTML::makeOption( '', _UE_NO_PREFERENCE );
  1249. $group = false;
  1250. foreach ( $choices as $k => $v ) {
  1251. if ( $k == '-' ) {
  1252. $drop[] = moscomprofilerHTML::makeOptGroup( $v );
  1253. $group = true;
  1254. } else {
  1255. $drop[] = moscomprofilerHTML::makeOption( $k, $v );
  1256. }
  1257. }
  1258. if ( $group ) {
  1259. $drop[] = moscomprofilerHTML::makeOptGroup( null );
  1260. }
  1261. $list = moscomprofilerHTML::selectList( $drop, $field->name . '__srmch', '', 'value', 'text', $selected, 1 );
  1262. } else {
  1263. $list = null;
  1264. }
  1265. return '<div class="cbSearchContainer">'
  1266. . ( $list ? '<div class="cbSearchKind">' . $list . '</div>' : '' )
  1267. . '<div class="cbSearchCriteria' . ( $class ? ' ' . $class : '' ) . '">' . $html . '</div>'
  1268. . '</div>'
  1269. ;
  1270. }
  1271. function _bindSearchMode( &$field, &$searchVals, &$postdata ) {
  1272. $fieldNam = $field->name . '__srmch';
  1273. $value = cbGetParam( $postdata, $fieldNam );
  1274. if ( $value !== null ) {
  1275. $searchVals->$fieldNam = stripslashes( $value );
  1276. }
  1277. return $value;
  1278. }
  1279. /**
  1280.  * Prepares field meta-data for saving to database (safe transfer from $postdata to $user)
  1281.  * Override but call parent
  1282.  *
  1283.  * @param  moscomprofilerFields  $field
  1284.  * @param  moscomprofilerUser    $user      RETURNED populated: touch only variables related to saving this field (also when not validating for showing re-edit)
  1285.  * @param  array                 $postdata  Typically $_POST (but not necessarily), filtering required.
  1286.  * @param  string                $reason    'profile' for save user edit, 'register' for save registration, 'list' for lists
  1287.  */
  1288. function _prepareFieldMetaSave( &$field, &$user, &$postdata, $reason ) {
  1289. // this is not used here anymore:
  1290. // if ( $reason == 'search' ) {
  1291. // $this->_bindSearchMode( $field, $user, $postdata );
  1292. // }
  1293. }
  1294. function ajaxCheckField( &$field, &$user, $reason ) {
  1295. global $_CB_framework;
  1296. global $_CB_fieldajax_outputed;
  1297. if ( $_CB_fieldajax_outputed !== true ) {
  1298. $cbSpoofField = cbSpoofField();
  1299. $cbSpoofString = cbSpoofString( null, 'fieldclass' );
  1300. $regAntiSpamFieldName = cbGetRegAntiSpamFieldName();
  1301. $regAntiSpamValues = cbGetRegAntiSpams();
  1302. $userid = (int) $user->id;
  1303. $checking  = _UE_CHECKING; // . '&start_debug=1',
  1304. $live_site = $_CB_framework->getCfg( 'live_site' );
  1305. $regAntiSpZ = $regAntiSpamValues[0];
  1306. if ( $_CB_framework->getUi() == 2 ) {
  1307. $ajaxUrl = $live_site . '/administrator/index3.php';
  1308. } else {
  1309. $ajaxUrl = $live_site . '/index2.php';
  1310. }
  1311. $_CB_framework->outputCbJQuery( <<<EOT
  1312. $.fn.cb_field_ajaxCheck = function() {
  1313. if ( ( $(this).val() != '' ) && ( $(this).val() != $(this).data('cblastvalsent') ) ) {
  1314. var inputid = $(this).attr('id');
  1315. if ( ! $('#'+inputid+'__Response').size() ) {
  1316. var respField = '<div class="cb_result_container"><div id="' + inputid + '__Response">&nbsp;</div></div>';
  1317. $(this).parent().each( function() {
  1318. if (this.tagName.toLowerCase() == 'td') {
  1319. $(this).append(respField);
  1320. } else {
  1321. $(this).after(respField);
  1322. }
  1323. $(inputid+'__Response').hide();
  1324. } );
  1325. }
  1326. if (  $('#'+inputid+'__Response').length > 0 ) {
  1327. $('#'+inputid+'__Response').html('<img alt="" src="$live_site/components/com_comprofiler/images/wait.gif" /> $checking').fadeIn('fast');
  1328. var cbInputField = this;
  1329. var lastVal = $(this).val();
  1330. $(this).data('cblastvalsent', lastVal );
  1331. $.ajax( { type: 'POST',
  1332. url:  '$ajaxUrl?option=com_comprofiler&task=fieldclass&field='+encodeURI(inputid)+'&function=checkvalue&user=$userid&no_html=1&format=raw',
  1333. data: 'value=' + encodeURI( lastVal ) + '&$cbSpoofField=' + encodeURI('$cbSpoofString') + '&$regAntiSpamFieldName=' + encodeURI('$regAntiSpZ'),
  1334. success: function(response) {
  1335. var respField = $('#'+$(cbInputField).attr('id')+'__Response');
  1336. respField.fadeOut('fast', function() {
  1337. respField.html(response).fadeIn('fast');
  1338. } );
  1339. $(cbInputField).data( 'cblastvalchecked', lastVal );
  1340. },
  1341. dataType: 'html'
  1342. });
  1343. }
  1344. }
  1345. };
  1346. $.fn.cb_field_ajaxClear = function() {
  1347. var respField = $('#'+$(this).attr('id')+'__Response');
  1348. if ( respField.html() != '&nbsp;' ) {
  1349. if ( $(this).val() != $(this).data( 'cblastvalchecked' ) ) {
  1350. respField.fadeOut('medium' );
  1351. } else {
  1352. respField.fadeIn('medium' );
  1353. }
  1354. }
  1355. };
  1356. EOT
  1357. );
  1358. $_CB_fieldajax_outputed = true;
  1359. }
  1360. $_CB_framework->outputCbJQuery(
  1361. // change is broken in FF 2.0.13 when a auto-filled value is chosen
  1362. "$('#" . $field->name . "').data( 'cblastvalsent', $('#" . $field->name . "').val() ).blur( $.fn.cb_field_ajaxCheck ).keyup( $.fn.cb_field_ajaxClear );"
  1363. );
  1364. }
  1365. /**
  1366.  * Direct access to field for custom operations, like for Ajax
  1367.  *
  1368.  * WARNING: direct unchecked access, except if $user is set, then check
  1369.  * that the logged-in user has rights to edit that $user.
  1370.  *
  1371.  * @param  moscomprofilerFields  $field
  1372.  * @param  moscomprofilerUser    $user
  1373.  * @param  array                 $postdata
  1374.  * @param  string                $reason     'profile' (as nothing can really be trusted in here.
  1375.  * @return string                            Expected output.
  1376.  */
  1377. function fieldClass( &$field, &$user, &$postdata, $reason ) {
  1378. global $_CB_framework;
  1379. // simple spoof check security
  1380. if ( ( ! cbSpoofCheck( 'fieldclass', 'POST', 2 ) ) || ( ( $reason == 'register' ) && ( $_CB_framework->getUi() == 1 ) && ! cbRegAntiSpamCheck( 2 ) ) ) {
  1381. echo '<span class="cb_result_error">' . _UE_SESSION_EXPIRED . "</span>";
  1382. exit;
  1383. }
  1384. return false;
  1385. }
  1386. /**
  1387.  * Private methods: BACKEND ONLY:
  1388.  */
  1389. /**
  1390.  * Loads XML file (backend use only!)
  1391.  *
  1392.  * @param moscomprofilerField $field
  1393.  * @return boolean  TRUE if success, FALSE if failed
  1394.  */
  1395. function _loadXML( &$field ) {
  1396. global $_CB_database, $_PLUGINS;
  1397. if ( ! $field->pluginid ) {
  1398. // this field pluginid is not up-to-date, try to find the plugin by the php registration method as last resort: load all user plugins for that:
  1399. if ( ! $_PLUGINS->loadPluginGroup( 'user', null, 0 ) ) {
  1400. return false;
  1401. }
  1402. $field->pluginid = $_PLUGINS->getUserFieldPluginId( $field->type );
  1403. }
  1404. if ( $this->_xml === null ) {
  1405. if ( ! $_PLUGINS->loadPluginGroup( null, array( $field->pluginid ), 0 ) ) {
  1406. return false;
  1407. }
  1408. $this->_xml =& $_PLUGINS->loadPluginXML( 'editField', $field->type, $field->pluginid );
  1409. if ( $this->_xml === null ) {
  1410. return false;
  1411. }
  1412. }
  1413. return true;
  1414. }
  1415. /**
  1416.  * Loads field XML (backend use only!)
  1417.  *
  1418.  * @param  moscomprofilerField $field
  1419.  * @return CBSimpleXMLElement if success, NULL if failed
  1420.  */
  1421. function & _loadFieldXML( &$field ) {
  1422. if ( $this->_fieldXml === null ) {
  1423. if ( $this->_loadXML( $field ) ) {
  1424. $fieldTypesXML =& $this->_xml->getElementByPath( 'fieldtypes' );
  1425. if ( $fieldTypesXML ) {
  1426. $this->_fieldXml =& $fieldTypesXML->getChildByNameAttr( 'field', 'type', $field->type );
  1427. }
  1428. }
  1429. }
  1430. return $this->_fieldXml;
  1431. }
  1432. /**
  1433.  * Loads parameters editor (backend use only!)
  1434.  *
  1435.  * @param moscomprofilerField $field
  1436.  * @return cbParamsEditorController or null if not existant
  1437.  */
  1438. function & _loadParamsEditor( &$field ) {
  1439. global $_PLUGINS;
  1440. if ( $this->_loadXML( $field ) ) {
  1441. $plugin  = $_PLUGINS->getPluginObject( $field->pluginid );
  1442. $params =& new cbParamsEditorController( $field->params, $this->_xml, $this->_xml, $plugin );
  1443. $pluginParams = new cbParamsBase( $plugin->params );
  1444. $params->setPluginParams( $pluginParams );
  1445. } else {
  1446. $params = null;
  1447. }
  1448. return $params;
  1449. }
  1450. /**
  1451.  * Methods for CB backend only (do not override):
  1452.  */
  1453. /**
  1454.  * Draws parameters editor of the field paramaters (backend use only!)
  1455.  *
  1456.  * @param  moscomprofilerField  $field
  1457.  * @param  array                $options
  1458.  * @return string  HTML if editor available, or NULL
  1459.  */
  1460. function drawParamsEditor( &$field, &$options ) {
  1461. $params =& $this->_loadParamsEditor( $field );
  1462. if ( $params ) {
  1463. $params->setOptions( $options );
  1464. return $params->draw( 'params', 'fieldtypes', 'field', 'type', $field->type );
  1465. } else {
  1466. return null;
  1467. }
  1468. }
  1469. /**
  1470.  * Converts returned parameters into raw format of parameters (backend use only!)
  1471.  *
  1472.  * @param  moscomprofilerField  $field
  1473.  * @param  array                $post_Params
  1474.  * @return string               for the param column of the field
  1475.  */
  1476. function getRawParams( &$field, &$post_Params ) {
  1477. return cbParamsEditorController::getRawParams( $_POST['params'] );
  1478. }
  1479. /**
  1480.  * Returns full label of the type of the field (backend use only!)
  1481.  *
  1482.  * @param  moscomprofilerField $field
  1483.  * @return boolean  TRUE if success, FALSE if failed
  1484.  */
  1485. function getFieldTypeLabel( &$field, $checkNotSys = true ) {
  1486. $fieldXML =& $this->_loadFieldXML( $field );
  1487. if ( $fieldXML ) {
  1488. if ( $checkNotSys && ( $fieldXML->attributes( 'unique' ) == 'true' ) ) {
  1489. return null;
  1490. }
  1491. return $fieldXML->attributes( 'label' );
  1492. }
  1493. return null;
  1494. }
  1495. /**
  1496.  * Returns main table name of $field
  1497.  *
  1498.  * @param  moscomprofilerFields  $field
  1499.  * @return string
  1500.  */
  1501. function getMainTable( &$field ) {
  1502. $fieldXML =& $this->_loadFieldXML( $field );
  1503. if ( $fieldXML ) {
  1504. $db =& $fieldXML->getElementByPath( 'database' );
  1505. if ( $db !== false ) {
  1506. cbimport( 'cb.sql.upgrader' );
  1507. $sqlUpgrader = new CBSQLupgrader( $_CB_database );
  1508. return $sqlUpgrader->getMainTableName( $db, $field->name, '#__comprofiler' );
  1509. }
  1510. }
  1511. return '#__comprofiler';
  1512. }
  1513. /**
  1514.  * Returns array of main table columns names of $field
  1515.  *
  1516.  * @param  moscomprofilerFields  $field
  1517.  * @return array
  1518.  */
  1519. function getMainTableColumns( &$field ) {
  1520. $fieldXML =& $this->_loadFieldXML( $field );
  1521. if ( $fieldXML ) {
  1522. $db =& $fieldXML->getElementByPath( 'database' );
  1523. if ( $db !== false ) {
  1524. cbimport( 'cb.sql.upgrader' );
  1525. $sqlUpgrader = new CBSQLupgrader( $_CB_database );
  1526. $columnsNames = $sqlUpgrader->getMainTableColumnsNames( $db, $field->name );
  1527. if ( $columnsNames !== false ) {
  1528. return $columnsNames;
  1529. }
  1530. }
  1531. }
  1532. return array( $field->name );
  1533. }
  1534. /**
  1535.  * Handles SQL XML for the type of the field (backend use only!)
  1536.  *  <database version="1">
  1537.  * <table name="#__comprofiler" class="moscomprofiler">
  1538.  * <columns>
  1539.  * <column name="_rate" nametype="namesuffix" type="sql:decimal(16,8)" unsigned="true" null="true" default="NULL" auto_increment="100" />
  1540.  *
  1541.  * @param  moscomprofilerField $field
  1542.  * @return array of array of array
  1543.  */
  1544. function adaptSQL( &$field, $add = true ) {
  1545. global $_CB_database;
  1546. $tableTypeNames = array();
  1547. cbimport( 'cb.sql.upgrader' );
  1548. $sqlUpgrader = new CBSQLupgrader( $_CB_database );
  1549. // $sqlUpgrader->setDryRun( true );
  1550. $change = ( $add ? true : 'drop' );
  1551. $fieldXML =& $this->_loadFieldXML( $field );
  1552. if ( $fieldXML ) {
  1553. $db =& $fieldXML->getElementByPath( 'database' );
  1554. if ( $db !== false ) {
  1555. // <database><table><columns>.... structure:
  1556. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $field->name, $change, null );
  1557. } else {
  1558. $data =& $fieldXML->getElementByPath( 'data' );
  1559. if ( $data !== false ) {
  1560. // <data ....> structure:
  1561. $xmlText = '<?xml version="1.0" encoding="UTF-8"?>
  1562. <database version="1">
  1563.     <table name="' . $field->table . '" maintable="true" strict="false" drop="never" shared="true">
  1564.         <columns>
  1565.         </columns>
  1566.     </table>
  1567. </database>';
  1568. $dbXml =& new CBSimpleXMLElement( $xmlText );
  1569. $columns =& $dbXml->getElementByPath( 'table/columns' );
  1570. $columns->addChildWithAttr( 'column', '', null, $data->attributes() );
  1571. $success = $sqlUpgrader->checkXmlDatabaseDescription( $dbXml, $field->name, $change, null );
  1572. } else {
  1573. $success = true;
  1574. }
  1575. }
  1576. } else {
  1577. cbimport('cb.xml.simplexml');
  1578. // no <fieldtype> xml at all, must be an old plugin:
  1579. $xmlText = '<?xml version="1.0" encoding="UTF-8"?>
  1580. <database version="1">
  1581.     <table name="#__comprofiler" class="moscomprofiler" maintable="true" strict="false" drop="never" shared="true">
  1582.         <columns>
  1583.             <column name="" nametype="namesuffix" type="sql:varchar(255)" null="true" default="NULL" />
  1584.         </columns>
  1585.     </table>
  1586. </database>';
  1587. $dbXml =& new CBSimpleXMLElement( $xmlText );
  1588. $success = $sqlUpgrader->checkXmlDatabaseDescription( $dbXml, $field->name, $change, null );
  1589. }
  1590. if ( ! $success ) {
  1591. $field->_error .= $sqlUpgrader->getErrors();
  1592. }
  1593. /*
  1594. var_dump( $success );
  1595. echo "<br>nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />nn", "<br />n" );
  1596. echo "<br>nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />nn", "<br />n" );
  1597. //exit;
  1598. */
  1599. return $success;
  1600. }
  1601. /**
  1602.  * Sets an error message $errorText for $field of $user
  1603.  *
  1604.  * @param  moscomprofilerFields  $field
  1605.  * @param  moscomprofilerUser    $user
  1606.  * @param  string                $reason    'profile' for save user edit, 'register' for save registration, 'list' for lists
  1607.  * @param  string                $errorText
  1608.  */
  1609. function _setValidationError( &$field, &$user, $reason, $errorText ) {
  1610. $this->_setErrorMSG( $this->getFieldTitle( $field, $user, 'text', $reason ) . ' : ' .  $errorText );
  1611. }
  1612. /**
  1613. * PRIVATE method: sets the text of the last error
  1614. * @access private
  1615. *
  1616. * @param  string   $msg   error message
  1617. * @return boolean         true
  1618. */
  1619. function _setErrorMSG( $msg ) {
  1620. global $_PLUGINS;
  1621. $_PLUGINS->errorMSG[] = $msg;
  1622. return true;
  1623. }
  1624. }
  1625. // cbimport( 'cb.xml.simplexml' );
  1626. class cbSqlQueryPart /* extends CBSimpleXMLElement */ {
  1627. var $tag;
  1628. var $name;
  1629. var $table;
  1630. var $type;
  1631. var $operator;
  1632. var $value;
  1633. var $valuetype;
  1634. var $searchmode;
  1635. var $_children = array();
  1636. function addChildren( $children ) {
  1637. $this->_children = array_merge( $this->_children, $children );
  1638. }
  1639. function reduceSqlFormula( &$tableReferences, $wildcards = null ) {
  1640. global $_CB_database;
  1641. static $replaceWildcards = false;
  1642. if ( $wildcards !== null ) {
  1643. $replaceWildcards = $wildcards;
  1644. }
  1645. $condition = null;
  1646. $subFormulas = array();
  1647. foreach ( $this->children() as $child ) {
  1648. $subFormulas[] = $child->reduceSqlFormula( $tableReferences );
  1649. }
  1650. if ( $this->attributes( 'type' ) == 'sql:operator' ) {
  1651. if ( count( $subFormulas ) > 0 ) {
  1652. $condition = '(' . implode( ') ' . $this->attributes( 'operator' ) . ' (', $subFormulas ) . ')';
  1653. }
  1654. } elseif ( $this->attributes( 'type' ) == 'sql:field' ) {
  1655. if ( $this->name() == 'column' ) {
  1656. if ( isset( $tableReferences[$this->attributes( 'table' )] ) ) {
  1657. $operator = $this->attributes( 'operator' );
  1658. $value = $this->attributes( 'value' );
  1659. $valuetype = $this->attributes( 'valuetype' );
  1660. $searchmode = $this->attributes( 'searchmode' );
  1661. if ( in_array( $operator, array( '=', '<>', '!=' ) ) && ( $valuetype == 'const:string' ) ) {
  1662. switch ( $searchmode ) {
  1663. case 'all':
  1664. case 'any':
  1665. case 'anyis':
  1666. case 'phrase':
  1667. case 'allnot':
  1668. case 'anynot':
  1669. case 'anyisnot':
  1670. case 'phrasenot':
  1671. $precise = in_array( $searchmode, array( 'anyis', 'anyisnot' ) );
  1672. if ( $replaceWildcards && ! $precise ) {
  1673. $wildsReplaced = $this->_replaceWildCards( $operator, $value ); // changes $operator and $value !
  1674. }
  1675. if ( is_array( $value ) ) {
  1676. $eachValues = $value;
  1677. } else {
  1678. if ( cbStartOfStringMatch( $searchmode, 'phrase' ) ) {
  1679. $eachValues = array( $value );
  1680. } else {
  1681. $eachValues = preg_split( '/W+/', $value );
  1682. }
  1683. }
  1684. $conditions = array();
  1685. foreach ( $eachValues as $v ) {
  1686. if ( $v != '' ) {
  1687. if ( ! ( $precise || in_array( $operator, array( 'LIKE', 'NOT LIKE' ) ) ) ) {
  1688. $operator = $this->_operatorToLike( $operator );
  1689. }
  1690. $conditions[] = $this->_buildop( $operator, ( $precise ? $v : $this->_prepostfixPercent( $v ) ), $valuetype, $tableReferences );
  1691. }
  1692. }
  1693. if ( count( $conditions ) > 1 ) {
  1694. $op = ( in_array( $searchmode, array( 'all', 'allnot' ) ) ? ') AND (' : ') OR (' );
  1695. $condition = '(' . implode( $op, $conditions ) . ')';
  1696. } elseif ( count( $conditions ) == 1 ) {
  1697. $condition = implode( '', $conditions );
  1698. } else {
  1699. $condition = null;
  1700. }
  1701. if ( in_array( $searchmode, array( 'allnot', 'anynot', 'anyisnot', 'phrasenot' ) ) && $condition ) {
  1702. $condition = 'NOT(' . $condition . ')';
  1703. }
  1704. break;
  1705. case 'isnot':
  1706. $operator = ( $operator == '=' ? '<>' : '=' );
  1707. $condition = $this->_buildop( $operator, $value, $valuetype, $tableReferences );
  1708. break;
  1709. case 'is':
  1710. default:
  1711. $condition = $this->_buildop( $operator, $value, $valuetype, $tableReferences );
  1712. break;
  1713. }
  1714. } else {
  1715. $condition = $this->_buildop( $operator, $value, $valuetype, $tableReferences );
  1716. }
  1717. }
  1718. }
  1719. }
  1720. return $condition;
  1721. }
  1722. function _replaceWildCards( &$operator, &$value ) {
  1723. $changes = false;
  1724. if ( is_array( $value ) ) {
  1725. foreach ( array_keys( $value ) as $k ) {
  1726. $changes = $this->_replaceWildCards( $operator, $value[$k] ) || $changes;
  1727. }
  1728. } else {
  1729. $escSearch = str_replace( '|*|', '|`|', $value );
  1730. if ( strpos( $escSearch, '*' ) !== false ) {
  1731. $escSearch = cbEscapeSQLsearch( $escSearch );
  1732. $escSearch = str_replace( '*', '%', $escSearch );
  1733. $value = str_replace( '|`|', '|*|', $escSearch );
  1734. $operator = $this->_operatorToLike( $operator );
  1735. $changes = true;
  1736. }
  1737. }
  1738. return $changes;
  1739. }
  1740. function _prepostfixPercent( $sqlSearchEscaped ) {
  1741. if ( $sqlSearchEscaped[0] != '%' ) {
  1742. $sqlSearchEscaped = '%' . $sqlSearchEscaped;
  1743. }
  1744. if ( $sqlSearchEscaped[strlen($sqlSearchEscaped) - 1] != '%' ) {
  1745. $sqlSearchEscaped .= '%';
  1746. }
  1747. return $sqlSearchEscaped;
  1748. }
  1749. function _operatorToLike( $operator ) {
  1750. switch ( $operator ) {
  1751. case '<>':
  1752. case '!=':
  1753. $operator = 'NOT LIKE';
  1754. break;
  1755. case '=':
  1756. default:
  1757. $operator = 'LIKE';
  1758. break;
  1759. }
  1760. return $operator;
  1761. }
  1762. function _buildop( $operator, $value, $valuetype, &$tableReferences ) {
  1763. global $_CB_database;
  1764. return $tableReferences[$this->attributes( 'table' )] . '.' . $_CB_database->NameQuote( $this->attributes( 'name' ) )
  1765. . ' ' . $operator . ' '
  1766. . $this->_sqlCleanQuote( $value, $valuetype )
  1767. ;
  1768. }
  1769. /**
  1770.  * Cleans and makes a value SQL safe depending on the type that is enforced.
  1771.  * @access private
  1772.  *
  1773.  * @param  mixed   $fieldValue
  1774.  * @param  string  $type
  1775.  * @return string
  1776.  */
  1777. function _sqlCleanQuote( $fieldValue, $type ) {
  1778. global $_CB_database;
  1779. $typeArray = explode( ':', $type, 3 );
  1780. if ( count( $typeArray ) < 2 ) {
  1781. $typeArray = array( 'const' , $type );
  1782. }
  1783. switch ( $typeArray[1] ) {
  1784. case 'int':
  1785. $value = (int) $fieldValue;
  1786. break;
  1787. case 'float':
  1788. $value = (float) $fieldValue;
  1789. break;
  1790. case 'formula':
  1791. $value = $fieldValue;
  1792. break;
  1793. case 'field': // this is temporarly handled here
  1794. $value = $_CB_database->NameQuote( $fieldValue );
  1795. break;
  1796. case 'datetime':
  1797. if ( preg_match( '/[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9](:[0-5][0-9]){2}/', $fieldValue ) ) {
  1798. $value = $_CB_database->Quote( $fieldValue );
  1799. } else {
  1800. $value = "''";
  1801. }
  1802. break;
  1803. case 'date':
  1804. if ( preg_match( '/[0-9]{4}-[01][0-9]-[0-3][0-9]/', $fieldValue ) ) {
  1805. $value = $_CB_database->Quote( $fieldValue );
  1806. } else {
  1807. $value = "''";
  1808. }
  1809. break;
  1810. case 'string':
  1811. $value = $_CB_database->Quote( $fieldValue );
  1812. break;
  1813. case 'null':
  1814. if ( $fieldValue != 'NULL' ) {
  1815. trigger_error( sprintf( 'cbSqlQueryPart::_sqlCleanQuote: ERROR: field type sql:null has not NULL value' ) );
  1816. }
  1817. $value = 'NULL';
  1818. break;
  1819. default:
  1820. trigger_error( 'cbSqlQueryPart::_sqlQuoteValueType: ERROR_UNKNOWN_TYPE: ' . htmlspecialchars( $type ), E_USER_NOTICE );
  1821. $value = $_CB_database->Quote( $fieldValue ); // false;
  1822. break;
  1823. }
  1824. return (string) $value;
  1825. }
  1826. function name() {
  1827. return $this->tag;
  1828. }
  1829. function attributes( $name = null ) {
  1830. if ( isset( $this->$name ) ) {
  1831. return $this->$name;
  1832. } else {
  1833. return null;
  1834. }
  1835. }
  1836. function children( ) {
  1837. return $this->_children;
  1838. }
  1839. }
  1840. /**
  1841. * Field Class for handling the CB field api
  1842. * @package Community Builder
  1843. * @author Beat
  1844. */
  1845. class cbFieldParamsHandler {
  1846. /** Plugin id
  1847.  * @var int */
  1848. var $_pluginid = null;
  1849. /** field object
  1850.  * @var moscomprofilerField */
  1851. var $_field = null;
  1852. /** Plugin of this field
  1853.  * @var moscomprofilerPlugin */
  1854. var $_plugin = null;
  1855. /** XML of the Plugin of this field
  1856.  * @var CBSimpleXMLElement */
  1857. var $_xml = null;
  1858. /** XML element for the params for this field
  1859.  * @var CBSimpleXMLElement */
  1860. var $_fieldXml = null;
  1861. /** params are specific to one particular field type
  1862.  * @var boolean */
  1863. var $_specific = false;
  1864. /**
  1865. * Constructor
  1866. *
  1867. * @param  int                  $pluginid   id of plugin with params for other fields
  1868. * @param  moscomprofilerField  $field
  1869. */
  1870. function cbFieldParamsHandler( $pluginid, &$field ) {
  1871. $this->_pluginid = $pluginid;
  1872. $this->_field =& $field;
  1873. }
  1874. /**
  1875.  * Private methods:
  1876.  */
  1877. /**
  1878.  * Loads XML file (backend use only!)
  1879.  *
  1880.  * @return boolean  TRUE if success, FALSE if failed
  1881.  */
  1882. function _loadXML( ) {
  1883. global $_CB_database, $_PLUGINS;
  1884. if ( $this->_xml === null ) {
  1885. if ( ! $_PLUGINS->loadPluginGroup( null, array( $this->_pluginid ), 0 ) ) {
  1886. return false;
  1887. }
  1888. $this->_xml =& $_PLUGINS->loadPluginXML( 'editField', 'cbfields_params', $this->_pluginid );
  1889. if ( $this->_xml === null ) {
  1890. return false;
  1891. }
  1892. }
  1893. return true;
  1894. }
  1895. /**
  1896.  * Loads fields-params XML (backend use only!)
  1897.  * also sets $this->_fieldXML and $this->_specific
  1898.  *
  1899.  * @return boolean              TRUE if success, FALSE if not existant
  1900.  */
  1901. function _loadFieldParamsXML( ) {
  1902. if ( $this->_fieldXml === null ) {
  1903. if ( $this->_loadXML() ) {
  1904. $fieldsParamsXML =& $this->_xml->getElementByPath( 'fieldsparams' );
  1905. if ( $fieldsParamsXML ) {
  1906. $fieldTypeSpecific =& $fieldsParamsXML->getChildByNameAttr( 'field', 'type', $this->_field->type );
  1907. if ( $fieldTypeSpecific ) {
  1908. // <fieldsparams><field type="date"><params><param ....
  1909. $this->_fieldXml =& $fieldTypeSpecific;
  1910. $this->_specific = true;
  1911. } else {
  1912. // <fieldsparams><field type="other_types"><params><param ....
  1913. $nonSpecific =& $fieldsParamsXML->getChildByNameAttr( 'field', 'type', 'other_types' );
  1914. if ( $nonSpecific ) {
  1915. $this->_fieldXml =& $nonSpecific;
  1916. $this->_specific = false;
  1917. }
  1918. }
  1919. }
  1920. }
  1921. }
  1922. return ( $this->_fieldXml !== null );
  1923. }
  1924. /**
  1925.  * Loads parameters editor (backend use only!)
  1926.  *
  1927.  * @return cbParamsEditorController or null if not existant
  1928.  */
  1929. function & _loadParamsEditor() {
  1930. global $_PLUGINS;
  1931. if ( $this->_loadFieldParamsXML() ) {
  1932. $plugin  = $_PLUGINS->getPluginObject( $this->_pluginid );
  1933. $params =& new cbParamsEditorController( $this->_field->params, $this->_xml, $this->_xml, $plugin );
  1934. $pluginParams = new cbParamsBase( $plugin->params );
  1935. $params->setPluginParams( $pluginParams );
  1936. } else {
  1937. $params = null;
  1938. }
  1939. return $params;
  1940. }
  1941. /**
  1942.  * Methods for CB backend only (do not override):
  1943.  */
  1944. /**
  1945.  * Draws parameters editor of the field paramaters (backend use only!)
  1946.  *
  1947.  * @param  array                $options
  1948.  * @return string  HTML if editor available, or NULL
  1949.  */
  1950. function drawParamsEditor( &$options ) {
  1951. $params =& $this->_loadParamsEditor();
  1952. if ( $params ) {
  1953. $params->setOptions( $options );
  1954. if ( $this->_specific ) {
  1955. return $params->draw( 'params', 'fieldsparams', 'field', 'type', $this->_field->type );
  1956. } else {
  1957. return $params->draw( 'params', 'fieldsparams', 'field', 'type', 'other_types' );
  1958. }
  1959. } else {
  1960. return null;
  1961. }
  1962. }
  1963. /**
  1964.  * Converts returned parameters into raw format of parameters:
  1965.  *
  1966.  * @param  array                $post_Params
  1967.  * @return string               for the param column of the field
  1968.  */
  1969. function getRawParams( &$post_Params ) {
  1970. return cbParamsEditorController::getRawParams( $_POST['params'] );
  1971. }
  1972. /**
  1973.  * Returns full label of the type of the field (backend use only!)
  1974.  *
  1975.  * @param  moscomprofilerField $field
  1976.  * @return boolean  TRUE if success, FALSE if failed
  1977.  */
  1978. function getFieldsParamsLabel() {
  1979. global $_PLUGINS;
  1980. $plugin  = $_PLUGINS->getPluginObject( $this->_pluginid );
  1981. if ( $this->_fieldXml ) {
  1982. return $plugin->name . ': ' . $this->_fieldXml->attributes( 'label' );
  1983. }
  1984. return $plugin->name . ': ' . "specific field-parameters";
  1985. }
  1986. }
  1987. /**
  1988. * Tab Class for handling the CB tab api
  1989. * @package Community Builder
  1990. * @author JoomlaJoe and Beat
  1991. */
  1992. class cbTabHandler extends cbPluginHandler  {
  1993. var $fieldJS="";
  1994. /**
  1995. * Constructor
  1996. */
  1997. function cbTabHandler() {
  1998. $this->cbPluginHandler();
  1999. }
  2000. /**
  2001. * Generates the menu and user status to display on the user profile by calling back $this->addMenu
  2002. * @param  moscomprofilerTab   $tab       the tab database entry
  2003. * @param  moscomprofilerUser  $user      the user being displayed
  2004. * @param  int                 $ui        1 for front-end, 2 for back-end
  2005. * @return boolean                        either true, or false if ErrorMSG generated
  2006. */
  2007. function getMenuAndStatus( $tab, $user, $ui) {
  2008. }
  2009. /**
  2010. * Generates the HTML to display the user profile tab
  2011. * @param  moscomprofilerTab   $tab       the tab database entry
  2012. * @param  moscomprofilerUser  $user      the user being displayed
  2013. * @param  int                 $ui        1 for front-end, 2 for back-end
  2014. * @return mixed                          either string HTML for tab content, or false if ErrorMSG generated
  2015. */
  2016. function getDisplayTab( $tab, $user, $ui ) {
  2017. }
  2018. /**
  2019. * Generates the HTML to display the user edit tab
  2020. * @param  moscomprofilerTab   $tab       the tab database entry
  2021. * @param  moscomprofilerUser  $user      the user being displayed
  2022. * @param  int                 $ui        1 for front-end, 2 for back-end
  2023. * @return mixed                          either string HTML for tab content, or false if ErrorMSG generated
  2024. */
  2025. function getEditTab( $tab, $user, $ui ) {
  2026. }
  2027. /**
  2028. * Saves the user edit tab postdata into the tab's permanent storage
  2029. * @param  moscomprofilerTab   $tab       the tab database entry
  2030. * @param  moscomprofilerUser  $user      the user being displayed
  2031. * @param  int                 $ui        1 for front-end, 2 for back-end
  2032. * @param  array               $postdata  _POST data for saving edited tab content as generated with getEditTab
  2033. * @return mixed                          either string HTML for tab content, or false if ErrorMSG generated
  2034. */
  2035. function saveEditTab( $tab, &$user, $ui, $postdata ) {
  2036. }
  2037. /**
  2038. * Generates the HTML to display the registration tab/area
  2039. * @param  moscomprofilerTab   $tab       the tab database entry
  2040. * @param  moscomprofilerUser  $user      the user being displayed
  2041. * @param  int                 $ui        1 for front-end, 2 for back-end
  2042. * @param  array               $postdata  _POST data for saving edited tab content as generated with getEditTab
  2043. * @return mixed                          either string HTML for tab content, or false if ErrorMSG generated
  2044. */
  2045. function getDisplayRegistration( $tab, $user, $ui, $postdata ) {
  2046. }
  2047. /**
  2048. * Saves the registration tab/area postdata into the tab's permanent storage
  2049. * @param  moscomprofilerTab   $tab       the tab database entry
  2050. * @param  moscomprofilerUser  $user      the user being displayed
  2051. * @param  int                 $ui        1 for front-end, 2 for back-end
  2052. * @param  array               $postdata  _POST data for saving edited tab content as generated with getEditTab
  2053. * @return mixed                          either string HTML for tab content, or false if ErrorMSG generated
  2054. */
  2055. function saveRegistrationTab( $tab, &$user, $ui, $postdata ) {
  2056. }
  2057. /**
  2058. * WARNING: UNCHECKED ACCESS! On purpose unchecked access for M2M operations
  2059. * Generates the HTML to display for a specific component-like page for the tab. WARNING: unchecked access !
  2060. * @param  moscomprofilerTab   $tab       the tab database entry
  2061. * @param  moscomprofilerUser  $user      the user being displayed
  2062. * @param  int                 $ui        1 for front-end, 2 for back-end
  2063. * @param  array               $postdata  _POST data for saving edited tab content as generated with getEditTab
  2064. * @return mixed                          either string HTML for tab content, or false if ErrorMSG generated
  2065. */
  2066. function getTabComponent( $tab, $user, $ui, $postdata ) {
  2067. return null;
  2068. }
  2069. //
  2070. // private methods for inheriting classes:
  2071. //
  2072. /**
  2073. * adds a validation JS code for the Edit Profile and Registration pages
  2074. * @param string Javascript code ready for HTML output, with a tab t at the begin and a newline n at the end.
  2075. */
  2076. function _addValidationJS($js)
  2077. {
  2078. $this->fieldJS .= $js;
  2079. }
  2080. /**
  2081. * internal utility method
  2082. * @param string postfix for identifying multiple pagings/search/sorts (optional)
  2083. * @return string value of the tab forms&urls prefix
  2084. */
  2085. function _getPrefix($postfix="")
  2086. {
  2087. return str_replace(".","_",((strncmp($this->element, "cb.", 3)==0)? substr($this->element,3) : $this->element).$postfix);
  2088. }
  2089. /**
  2090. * gets an ESCAPED and urldecoded request parameter for the plugin
  2091. * you need to call stripslashes to remove escapes, and htmlspecialchars before displaying.
  2092. *
  2093. * @param  string  $name     name of parameter in REQUEST URL
  2094. * @param  string  $def      default value of parameter in REQUEST URL if none found
  2095. * @param  string  $postfix  postfix for identifying multiple pagings/search/sorts (optional)
  2096. * @return string            value of the parameter (urldecode processed for international and special chars) and ESCAPED! and ALLOW HTML!
  2097. */
  2098. function _getReqParam( $name, $def=null, $postfix="" ) {
  2099. global $_GET, $_POST;
  2100. $prefix = $this->_getPrefix($postfix);
  2101. $value = cbGetParam( $_POST, $prefix.$name, false );
  2102. if ( $value !== false ) {
  2103. $value = cbGetParam( $_POST, $prefix.$name, $def );
  2104. } else {
  2105. $value = cbGetParam( $_GET, $prefix.$name, $def );
  2106. if ( $value && is_string( $value ) ) {
  2107. $value = utf8ToISO( urldecode( $value ) );
  2108. }
  2109. }
  2110. return $value;
  2111. }
  2112. /**
  2113. * Gets the name input parameter for search and other functions
  2114. *
  2115. * @param  string  $name     name of parameter of plugin
  2116. * @param  string  $postfix  postfix for identifying multiple pagings/search/sorts (optional)
  2117. * @return string            value of the name input parameter
  2118. */
  2119. function _getPagingParamName( $name="search", $postfix="" )
  2120. {
  2121. $prefix = $this->_getPrefix($postfix);
  2122. return $prefix.$name;
  2123. }
  2124. /**
  2125. * Gives the URL of a link with plugin parameters.
  2126. *
  2127. * @param  array    $paramArray        array of string with key name of parameters
  2128. * @param  string   $task              cb task to link to (default: userProfile)
  2129. * @param  boolean  $sefed             TRUE to call cbSef (default), FALSE to leave URL unsefed
  2130. * @param  array    $excludeParamList  of string with keys of parameters to not include
  2131. * @return string                      value of the parameter
  2132. */
  2133. function _getAbsURLwithParam( $paramArray, $task = 'userProfile', $sefed = true, $excludeParamList = array() )
  2134. {
  2135. global $_CB_database, $_POST, $_GET;
  2136. $prefix = $this->_getPrefix();
  2137. if ( $task == 'userProfile' ) {
  2138. $Itemid = (int) getCBprofileItemid( 0 );
  2139. unset( $paramArray['Itemid'] );
  2140. } elseif ( isset( $paramArray['Itemid'] ) ) {
  2141. $Itemid = (int) $paramArray['Itemid'];
  2142. unset( $paramArray['Itemid'] );
  2143. } elseif ( isset( $_POST['Itemid'] ) ) {
  2144. $Itemid = (int) cbGetParam( $_POST, 'Itemid', 0 );
  2145. } elseif ( isset( $_GET['Itemid'])) {
  2146. $Itemid = (int) cbGetParam( $_GET, 'Itemid', 0 );
  2147. } else {
  2148. $Itemid = (int) getCBprofileItemid( 0 );
  2149. }
  2150. if ( ( $task == 'userProfile' ) && ! isset( $paramArray['user'] ) ) {
  2151. if ( isset( $_POST['user'] ) ) {
  2152. $paramArray['user'] = urldecode(cbGetParam($_POST,'user',null));
  2153. } else {
  2154. $paramArray['user'] = urldecode(cbGetParam($_GET,'user',null));
  2155. }
  2156. }
  2157. if ( $task == 'pluginclass' ) {
  2158. $plugin = $this->getPluginObject();
  2159. $unsecureChars = array( '/', '\', ':', ';', '{', '}', '(', ')', """, "'", '.', ',', "", ' ', "t", "n", "r", "x0B" );
  2160. $paramArray['plugin'] = substr( str_replace( $unsecureChars, '', $plugin->element ), 0, 32 );
  2161. $paramArray['tab'] = null;
  2162. } else {
  2163. $paramArray['plugin'] = null;
  2164. if ( ! isset( $paramArray['tab'] ) ) {
  2165. $paramArray['tab'] = strtolower( get_class( $this ) );
  2166. }
  2167. }
  2168. $uri = 'index.php?option=com_comprofiler&amp;task=' . $task
  2169. . ( ( isset( $paramArray['user'] ) && $paramArray['user'] ) ? '&amp;user=' . htmlspecialchars( stripslashes( $paramArray['user'] ) ) : '' )
  2170. . ( $Itemid ? '&amp;Itemid=' . $Itemid : '' )
  2171. . ( $paramArray['tab'] ? '&amp;tab=' . htmlspecialchars( stripslashes( $paramArray['tab'] ) ) : '' )
  2172. . ($paramArray['plugin'] ? '&amp;plugin=' . htmlspecialchars( stripslashes( $paramArray['plugin'] ) ) : '' );
  2173. reset( $paramArray );
  2174. while ( list( $key, $val ) = each( $paramArray ) ) {
  2175. if ( ! in_array( $key, array( 'Itemid', 'user', 'tab', 'plugin' ) ) && ! in_array( $key, $excludeParamList ) ) {
  2176. if ( $val ) {
  2177. $uri .= '&amp;' . htmlspecialchars( $prefix . $key ) . '=' . htmlspecialchars( stripslashes( $val ) );
  2178. }
  2179. }
  2180. }
  2181. if ( $sefed ) {
  2182. return cbSef( $uri );
  2183. } else {
  2184. return $uri;
  2185. }
  2186. }
  2187. /**
  2188.  * Returns the tab description with all replacements of variables and of language strings made.
  2189.  *
  2190.  * @param  cbTabHandler        $tab
  2191.  * @param  moscomprofilerUser  $user
  2192.  * @param  string              $htmlId  div id tag for the description html div
  2193.  * @return string
  2194.  */
  2195. function _writeTabDescription( $tab, $user, $htmlId = null ) {
  2196. if ( $tab->description != null ) {
  2197. $return = "tt<div class="tab_Description""
  2198. . ( $htmlId ? " id="" . $htmlId . """ : "" )
  2199. . ">"
  2200. . cbReplaceVars( unHtmlspecialchars( $tab->description ), $user ) //TBD later: remove unHtmlSpecialchars, as from CB 1.2 on the row is stored fine.
  2201. ."</div>n";
  2202. } else {
  2203. $return = null;
  2204. }
  2205. return $return;
  2206. }
  2207. /**
  2208. * Writes the html search box as <form><div><input ....
  2209. * @param array: paging parameters. ['limitstart'] is the record number to start dislpaying from will be ignored
  2210. * @param string postfix for identifying multiple pagings/search/sorts (optional)
  2211. * @param string the class/style for the div
  2212. * @param string the class/style for the input
  2213. * @param string cb task to link to (default: userProfile)
  2214. * @return string html text displaying a nice search box
  2215. */
  2216. function _writeSearchBox($pagingParams,$postfix="",$divClass="style="float:right;"",$inputClass="class="inputbox"",$task="userProfile")
  2217. {
  2218. $base_url = $this->_getAbsURLwithParam($pagingParams, $task, true, array($postfix."search",$postfix."limitstart"));
  2219. $searchPagingParams = stripslashes($pagingParams[$postfix."search"]);
  2220. $searchForm = "<form action="".$base_url."" method="post"><div".($divClass?" ".$divClass:"").">";
  2221. /* done in _getAbsURLwithParam:
  2222. foreach ($pagingParams as $k => $pp) {
  2223. if ($pp && !in_array($k,array($postfix."search",$postfix."limitstart"))) {
  2224. $searchForm .= "<input type='hidden' name='".$this->_getPagingParamName($k)."' value="".htmlspecialchars($pp)."" />"; //BB $_CB_framework->outputCharset() charset into htmlspecialchars everywhere ?
  2225. }
  2226. }
  2227. */
  2228. $searchForm .= "<input type="text" name="".$this->_getPagingParamName("search",$postfix)."" ".$inputClass." value=""
  2229. .($searchPagingParams ? htmlspecialchars($searchPagingParams) : _UE_SEARCH_INPUT).""";
  2230. if (!$searchPagingParams) {
  2231. $searchForm .= " onblur="if(this.value=='') { this.value='"._UE_SEARCH_INPUT."'; return false; }""
  2232. ." onfocus="if(this.value=='"._UE_SEARCH_INPUT."') this.value='';"";
  2233. }
  2234. $searchForm .= " onchange="if(this.value!='".($searchPagingParams ? str_replace(array("\","'"),array("\\","\'"),htmlspecialchars($searchPagingParams)) : _UE_SEARCH_INPUT)."')"
  2235. ." { ";
  2236. if (!$searchPagingParams) {
  2237. $searchForm .= "if (this.value=='"._UE_SEARCH_INPUT."') this.value=''; ";
  2238. }
  2239. $searchForm .= "this.form.submit(); }" />"
  2240. . "</div></form>";
  2241. return $searchForm;
  2242. }
  2243. /**
  2244. * Writes the html links for sorting as headers
  2245. * @param array: paging parameters. ['limitstart'] is the record number to start dislpaying from will be ignored
  2246. * @param string postfix for identifying multiple pagings/search/sorts (optional)
  2247. * @param string sorting parameter added as &sortby=... if NOT NULL
  2248. * @param string Name to display as column heading/hyperlink
  2249. * @param boolean true if it is the default sorting field to not output sorting
  2250. * @param string class/style html for the unselected sorting header
  2251. * @param string class/style html for the selected sorting header
  2252. * @param string cb task to link to (default: userProfile)
  2253. * @return string html text displaying paging
  2254. */
  2255. function _writeSortByLink($pagingParams,$postfix,$sortBy,$sortName,$defaultSort=false,$unselectedClass='class="cbSortHead"',$selectedClass='class="cbSortHeadSelected"',$task="userProfile")
  2256. {
  2257. $url = $this->_getAbsURLwithParam($pagingParams, $task, false, array($postfix."sortby",$postfix."limitstart"));
  2258. $prefix = $this->_getPrefix();
  2259. //done in _getAbsURLwithParam: foreach ($pagingParams as $k => $v) if ($v && $k!=$postfix."sortby")  $url .= "&amp;".htmlentities($prefix.$k)."=".htmlentities($v);
  2260. if (!$defaultSort) $url .= "&amp;".htmlentities($prefix.$postfix)."sortby=".htmlentities($sortBy);
  2261. $class = ((!$pagingParams[$postfix."sortby"] && $defaultSort) || ($pagingParams[$postfix."sortby"]==$sortBy))?" ".$selectedClass:" ".$unselectedClass;
  2262. return '<a href="'.cbSef($url).'"'.$class.' title="'.sprintf(_UE_CLICKTOSORTBY,htmlspecialchars($sortName, ENT_QUOTES)).'">'
  2263. .htmlspecialchars($sortName, ENT_QUOTES).'</a>';
  2264. }
  2265. /**
  2266. * Writes the html links for pages inside tabs, eg, previous 1 2 3 ... x next
  2267. * @param array: paging parameters. ['limitstart'] is the record number to start dislpaying from will be ignored
  2268. * @param string postfix for identifying multiple pagings/search/sorts (optional)
  2269. * @param int Number of rows to display per page
  2270. * @param int Total number of rows
  2271. * @param string cb task to link to (default: userProfile)
  2272. * @return string html text displaying paging
  2273. */
  2274. function _writePaging( $pagingParams, $postfix, $limit, $total, $task = 'userProfile' )
  2275. {
  2276. $base_url = $this->_getAbsURLwithParam( $pagingParams, $task, false, array( $postfix . 'limitstart' ) );
  2277. $prefix = $this->_getPrefix( $postfix );
  2278. return writePagesLinks( $pagingParams[$postfix . 'limitstart'], $limit, $total, $base_url, null, $prefix );
  2279. }
  2280. /**
  2281. * gets the paging limitstart, search and sortby parameters, as well as additional parameters
  2282. * @param array of string : keyed additional parameters as "Param-name" => "default-value"
  2283. * @param mixed : array of string OR string : postfix for identifying multiple pagings/search/sorts (optional)
  2284. * @return array("limitstart" => current list-start value (default: null), "search" => search-string (default: null), "sortby" => sorting by, +additional parameters as keyed in $additionalParams)
  2285. */
  2286. function _getPaging($additionalParams=array(), $postfixArray=null)
  2287. {
  2288. $return=array();
  2289. if (!is_array($postfixArray)) {
  2290. if (is_string($postfixArray)) {
  2291. $postfixArray = array($postfixArray);
  2292. } else {
  2293. $postfixArray = array("");
  2294. }
  2295. }
  2296. foreach ($postfixArray as $postfix) {
  2297. $return[$postfix."limitstart"] = (int) $this->_getReqParam("limitstart", null, $postfix);
  2298. $return[$postfix."search"] = $this->_getReqParam("search", null, $postfix);
  2299. $return[$postfix."sortby"] = $this->_getReqParam("sortby", null, $postfix);
  2300. }
  2301. foreach ($additionalParams as $k => $p) {
  2302. $return[$k] = $this->_getReqParam($k, $p);
  2303. }
  2304. return $return;
  2305. }
  2306. /**
  2307. * sets the paging limitstart, search and sortby parameters, as well as additional parameters
  2308. * @param array of string : keyed additional parameters as "Param-name" => "value"
  2309. * @param string search string
  2310. * @param string sorting parameter added as &sortby=... if NOT NULL
  2311. * @param array of string : keyed additional parameters as "Param-name" => "default-value"
  2312. * @param string postfix for identifying multiple pagings/search/sorts (optional)
  2313. * @return array("limitstart" => current list-start value (default: null), "search" => search-string (default: null), "sortby" => sorting by, +additional parameters as keyed in $additionalParams)
  2314. */
  2315. function _setPaging($limitstart="0",$search=null,$sortBy=null,$additionalParams=array(), $postfix="")
  2316. {
  2317. $return=array();
  2318. $return[$postfix."limitstart"] = (int) $limitstart;
  2319. $return[$postfix."search"] = $search;
  2320. $return[$postfix."sortby"] = $sortBy;
  2321. foreach ($additionalParams as $k => $p) {
  2322. $return[$k] = $p;
  2323. }
  2324. return $return;
  2325. }
  2326. } // end class cbTabHandler.
  2327. /**
  2328. * PMS Class for handling the CB PMS api
  2329. * @package Community Builder
  2330. * @author Beat
  2331. */
  2332. class cbPMSHandler extends cbTabHandler  {
  2333. /**
  2334. * Constructor
  2335. */
  2336. function cbPMSHandler() {
  2337. $this->cbTabHandler();
  2338. }
  2339. /**
  2340. * Sends a PMS message
  2341. * @param int userId of receiver
  2342. * @param int userId of sender
  2343. * @param string subject of PMS message
  2344. * @param string body of PMS message
  2345. * @param boolean false: real user-to-user message; true: system-Generated by an action from user $fromid (if non-null)
  2346. * @return mixed : either string HTML for tab content, or false if ErrorMSG generated
  2347. */
  2348. function sendUserPMS( $toid, $fromid, $subject, $message, $systemGenerated = false ) {
  2349. }
  2350. /**
  2351. * returns all the parameters needed for a hyperlink or a menu entry to do a pms action
  2352. * @param int userId of receiver
  2353. * @param int userId of sender
  2354. * @param string subject of PMS message
  2355. * @param string body of PMS message
  2356. * @param int kind of link: 1: link to compose new PMS message for $toid user. 2: link to inbox of $fromid user; 3: outbox, 4: trashbox,
  2357.   5: link to edit pms options
  2358. * @return mixed array of string {"caption" => menu-text ,"url" => NON-cbSef relative url-link, "tooltip" => description} or false and errorMSG
  2359. */
  2360. function getPMSlink($toid, $fromid, $subject, $message, $kind) {
  2361. }
  2362. /**
  2363. * gets PMS system capabilities
  2364. * @return mixed array of string {'subject' => boolean ,'body' => boolean} or false if ErrorMSG generated
  2365. */
  2366. function getPMScapabilites() {
  2367. }
  2368. /**
  2369. * gets PMS unread messages count
  2370. * @param int user id
  2371. * @return mixed number of messages unread by user $userid or false if ErrorMSG generated
  2372. */
  2373. function getPMSunreadCount($userid) {
  2374. }
  2375. }
  2376. // ----- NO MORE CLASSES OR FUNCTIONS PASSED THIS POINT -----
  2377. // Post class declaration initialisations
  2378. // some version of PHP don't allow the instantiation of classes
  2379. // before they are defined
  2380. global $_PLUGINS;
  2381. /** @global cbPluginHandler $_PLUGINS */
  2382. $_PLUGINS = new cbPluginHandler();
  2383. ?>