A QCodo powered CMS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
17 KiB

  1. <?php
  2. /**
  3. * This is the "Meta" DataGrid class for the List functionality
  4. * of the JavaScript class. This code-generated class
  5. * contains a QDataGrid class which can be used by any QForm or QPanel,
  6. * listing a collection of JavaScript objects. It includes
  7. * functionality to perform pagination and sorting on columns.
  8. *
  9. * To take advantage of some (or all) of these control objects, you
  10. * must create an instance of this DataGrid in a QForm or QPanel.
  11. *
  12. * Any and all changes to this file will be overwritten with any subsequent re-
  13. * code generation.
  14. *
  15. * @package Quinta CMS
  16. * @subpackage MetaControls
  17. *
  18. */
  19. class JavaScriptDataGridGen extends QDataGrid {
  20. /**
  21. * Standard DataGrid constructor which also pre-configures the DataBinder
  22. * to its own SimpleDataBinder. Also pre-configures UseAjax to true.
  23. *
  24. * @param mixed $objParentObject either a QPanel or QForm which would be this DataGrid's parent
  25. * @param string $strControlId optional explicitly-defined ControlId for this DataGrid
  26. */
  27. public function __construct($objParentObject, $strControlId = null) {
  28. parent::__construct($objParentObject, $strControlId);
  29. $this->SetDataBinder('MetaDataBinder', $this);
  30. $this->UseAjax = true;
  31. }
  32. /**
  33. * Given the description of the Column's contents, this is a simple, express
  34. * way of adding a column to this JavaScript datagrid. The description of a column's
  35. * content can be either a text string description of a simple field name
  36. * in the JavaScript object, or it can be any QQNode extending from QQN::JavaScript().
  37. *
  38. * MetaAddColumn will automatically pre-configure the column with the name, html
  39. * and sort rules given the content being specified.
  40. *
  41. * Any of these things can be overridden with OverrideParameters.
  42. *
  43. * Finally, $mixContents can also be an array of contents, if displaying and/or
  44. * sorting using two fields from the JavaScript object.
  45. *
  46. * @param mixed $mixContents
  47. * @param string $objOverrideParameters[]
  48. * @return QDataGridColumn
  49. */
  50. public function MetaAddColumn($mixContent, $objOverrideParameters = null)
  51. {
  52. $strColumnName = '';
  53. $strHtml = '';
  54. $aryOrderByClauses = null;
  55. if (is_array($mixContent))
  56. {
  57. $objNodeArray = array();
  58. try {
  59. foreach ($mixContent as $mixItem)
  60. $objNodeArray[] = $this->ResolveContentItem($mixItem);
  61. } catch (QCallerException $objExc) {
  62. $objExc->IncrementOffset();
  63. throw $objExc;
  64. }
  65. if (count($objNodeArray) == 0)
  66. throw new QCallerException('No content specified');
  67. // Create Various Arrays to be used by DGC
  68. $strNameArray = '';
  69. $strHtmlArray = '';
  70. $objSortDescending = array();
  71. foreach ($objNodeArray as $objNode)
  72. {
  73. $strNameArray[] = QApplication::Translate(QConvertNotation::WordsFromCamelCase($objNode->_PropertyName));
  74. $strHtmlArray[] = $objNode->GetDataGridHtml();
  75. $objSort[] = $objNode->GetDataGridOrderByNode();
  76. $objSortDescending[] = $objNode->GetDataGridOrderByNode();
  77. $objSortDescending[] = false;
  78. }
  79. $strColumnName = implode(', ', $strNameArray);
  80. $strHtml = '<?=' . implode(' . ", " . ', $strHtmlArray) . '?>';
  81. $aryOrderByClauses = array(
  82. 'OrderByClause' => new QQOrderBy($objNodeArray),
  83. 'ReverseOrderByClause' => new QQOrderBy($objSortDescending)
  84. );
  85. }
  86. else
  87. {
  88. try {
  89. $objNode = $this->ResolveContentItem($mixContent);
  90. } catch (QCallerException $objExc) {
  91. $objExc->IncrementOffset();
  92. throw $objExc;
  93. }
  94. $strColumnName = QApplication::Translate(QConvertNotation::WordsFromCamelCase($objNode->_PropertyName));
  95. $strHtml = '<?=' . $objNode->GetDataGridHtml() . '?>';
  96. $aryOrderByClauses = array(
  97. 'OrderByClause' => QQ::OrderBy($objNode->GetDataGridOrderByNode()),
  98. 'ReverseOrderByClause' => QQ::OrderBy($objNode->GetDataGridOrderByNode(), false)
  99. );
  100. }
  101. $objNewColumn = new QDataGridColumn( $strColumnName, $strHtml, $aryOrderByClauses );
  102. $objOverrideArray = func_get_args();
  103. if (count($objOverrideArray) > 1)
  104. try {
  105. unset($objOverrideArray[0]);
  106. $objNewColumn->OverrideAttributes($objOverrideArray);
  107. } catch (QCallerException $objExc) {
  108. $objExc->IncrementOffset();
  109. throw $objExc;
  110. }
  111. $this->AddColumn($objNewColumn);
  112. return $objNewColumn;
  113. }
  114. /**
  115. * Similar to MetaAddColumn, except it creates a column for a Type-based Id. You MUST specify
  116. * the name of the Type class that this will attempt to use $NameArray against.
  117. *
  118. * Also, $mixContent cannot be an array. Only a single field can be specified.
  119. *
  120. * @param mixed $mixContent string or QQNode from JavaScript
  121. * @param string $strTypeClassName the name of the TypeClass to use $NameArray against
  122. * @param mixed $objOverrideParameters
  123. */
  124. public function MetaAddTypeColumn($mixContent, $strTypeClassName, $objOverrideParameters = null) {
  125. // Validate TypeClassName
  126. if (!class_exists($strTypeClassName) || !property_exists($strTypeClassName, 'NameArray'))
  127. throw new QCallerException('Invalid TypeClass Name: ' . $strTypeClassName);
  128. // Validate Node
  129. try {
  130. $objNode = $this->ResolveContentItem($mixContent);
  131. } catch (QCallerException $objExc) {
  132. $objExc->IncrementOffset();
  133. throw $objExc;
  134. }
  135. // Create the Column
  136. $strName = QConvertNotation::WordsFromCamelCase($objNode->_PropertyName);
  137. if (strtolower(substr($strName, strlen($strName) - 3)) == ' id')
  138. $strName = substr($strName, 0, strlen($strName) - 3);
  139. $strProperty = $objNode->GetDataGridHtml();
  140. $objNewColumn = new QDataGridColumn(
  141. QApplication::Translate($strName),
  142. sprintf('<?=(%s) ? %s::$NameArray[%s] : null;?>', $strProperty, $strTypeClassName, $strProperty),
  143. array(
  144. 'OrderByClause' => QQ::OrderBy($objNode),
  145. 'ReverseOrderByClause' => QQ::OrderBy($objNode, false)
  146. )
  147. );
  148. // Perform Overrides
  149. $objOverrideArray = func_get_args();
  150. if (count($objOverrideArray) > 2)
  151. try {
  152. unset($objOverrideArray[0]);
  153. unset($objOverrideArray[1]);
  154. $objNewColumn->OverrideAttributes($objOverrideArray);
  155. } catch (QCallerException $objExc) {
  156. $objExc->IncrementOffset();
  157. throw $objExc;
  158. }
  159. $this->AddColumn($objNewColumn);
  160. return $objNewColumn;
  161. }
  162. /**
  163. * Will add an "edit" link-based column, using a standard HREF link to redirect the user to a page
  164. * that must be specified.
  165. *
  166. * @param string $strLinkUrl the URL to redirect the user to
  167. * @param string $strLinkHtml the HTML of the link text
  168. * @param string $strColumnTitle the HTML of the link text
  169. * @param string $intArgumentType the method used to pass information to the edit page (defaults to PathInfo)
  170. */
  171. public function MetaAddEditLinkColumn($strLinkUrl, $strLinkHtml = 'Edit', $strColumnTitle = 'Edit', $intArgumentType = QMetaControlArgumentType::PathInfo) {
  172. switch ($intArgumentType) {
  173. case QMetaControlArgumentType::QueryString:
  174. $strLinkUrl .= '?intId=<?=urlencode($_ITEM->Id)?>';
  175. break;
  176. case QMetaControlArgumentType::PathInfo:
  177. $strLinkUrl .= '/<?=urlencode($_ITEM->Id)?>';
  178. break;
  179. default:
  180. throw new QCallerException('Unable to pass arguments with this intArgumentType: ' . $intArgumentType);
  181. }
  182. $strHtml = '<a href="' . $strLinkUrl . '">' . $strLinkHtml . '</a>';
  183. $colEditColumn = new QDataGridColumn($strColumnTitle, $strHtml, 'HtmlEntities=False');
  184. $this->AddColumn($colEditColumn);
  185. return $colEditColumn;
  186. }
  187. /**
  188. * Will add an "edit" control proxy-based column, calling any actions on a given control proxy
  189. * that must be specified.
  190. *
  191. * @param QControlProxy $pxyControl the control proxy to use
  192. * @param string $strLinkHtml the HTML of the link text
  193. * @param string $strColumnTitle the HTML of the link text
  194. */
  195. public function MetaAddEditProxyColumn(QControlProxy $pxyControl, $strLinkHtml = 'Edit', $strColumnTitle = 'Edit') {
  196. $strHtml = '<a href="#" <?= $_FORM->GetControl("' . $pxyControl->ControlId . '")->RenderAsEvents($_ITEM->Id, false); ?>>' . $strLinkHtml . '</a>';
  197. $colEditColumn = new QDataGridColumn($strColumnTitle, $strHtml, 'HtmlEntities=False');
  198. $this->AddColumn($colEditColumn);
  199. return $colEditColumn;
  200. }
  201. /**
  202. * Given the description of the Column's contents, this is a simple, express
  203. * way of adding a column to this JavaScript datagrid. The description of a column's
  204. * content can be either a text string description of a simple field name
  205. * in the JavaScript object, or it can be any QQNode extending from QQN::JavaScript().
  206. *
  207. * MetaAddColumn will automatically pre-configure the column with the name, html
  208. * and sort rules given the content being specified.
  209. *
  210. * Any of these things can be overridden with OverrideParameters.
  211. *
  212. *
  213. * @param QControlProxy $pxyControl the control proxy to use
  214. * @param mixed $mixContents - a string or QQNode
  215. * @param string $strLinkHtml the HTML of the link text
  216. * @param string $strColumnTitle the HTML of the link text
  217. * @param string $aryOverrideParameters
  218. * @return QDataGridColumn
  219. */
  220. public function MetaAddProxyColumn(QControlProxy $pxyControl,
  221. $mixContent,
  222. $strLinkText = '',
  223. $strColumnTitle = '',
  224. $aryOverrideParameters = null)
  225. {
  226. $strHtml = '';
  227. $aryOverrides = null;
  228. $aryExtraOverrides = null;
  229. $aryParams = func_get_args();
  230. if( sizeof($aryParams > 4) )
  231. $aryExtraOverrides = array_slice($aryParams, 4);
  232. try {
  233. $objNode = $this->ResolveContentItem($mixContent);
  234. } catch (QCallerException $objExc) {
  235. $objExc->IncrementOffset();
  236. throw $objExc;
  237. }
  238. if( empty($strColumnTitle) )
  239. $strColumnTitle = QApplication::Translate(QConvertNotation::WordsFromCamelCase($objNode->_PropertyName));
  240. if( empty($strLinkText) )
  241. $strLinkText = '<?= $_ITEM->' . $objNode->_PropertyName . '?>';
  242. $strHtml = '<a href="#" <?= $_FORM->GetControl("' . $pxyControl->ControlId . '")->RenderAsEvents($_ITEM->Id, false); ?>>' . $strLinkText . '</a>';
  243. $aryOverrides = array(
  244. 'HtmlEntities' => 'False',
  245. 'OrderByClause' => QQ::OrderBy($objNode->GetDataGridOrderByNode()),
  246. 'ReverseOrderByClause' => QQ::OrderBy($objNode->GetDataGridOrderByNode(), false)
  247. );
  248. if ($aryExtraOverrides)
  249. $aryOverrides = array_merge($aryOverrides, $aryExtraOverrides);
  250. $objNewColumn = new QDataGridColumn( $strColumnTitle, $strHtml, $aryOverrides );
  251. $this->AddColumn($objNewColumn);
  252. return $objNewColumn;
  253. }
  254. /**
  255. * Default / simple DataBinder for this Meta DataGrid. This can easily be overridden
  256. * by calling SetDataBinder() on this DataGrid with another DataBinder of your choice.
  257. *
  258. * If a paginator is set on this DataBinder, it will use it. If not, then no pagination will be used.
  259. * It will also perform any sorting (if applicable).
  260. */
  261. public function MetaDataBinder() {
  262. // Remember! We need to first set the TotalItemCount, which will affect the calcuation of LimitClause below
  263. if ($this->Paginator) {
  264. $this->TotalItemCount = JavaScript::CountAll();
  265. }
  266. // Setup the $objClauses Array
  267. $objClauses = array();
  268. // If a column is selected to be sorted, and if that column has a OrderByClause set on it, then let's add
  269. // the OrderByClause to the $objClauses array
  270. if ($objClause = $this->OrderByClause)
  271. array_push($objClauses, $objClause);
  272. // Add the LimitClause information, as well
  273. if ($objClause = $this->LimitClause)
  274. array_push($objClauses, $objClause);
  275. // Set the DataSource to be a Query result from JavaScript, given the clauses above
  276. $this->DataSource = JavaScript::LoadAll($objClauses);
  277. }
  278. /**
  279. * Used internally by the Meta-based Add Column tools.
  280. *
  281. * Given a QQNode or a Text String, this will return a JavaScript-based QQNode.
  282. * It will also verify that it is a proper JavaScript-based QQNode, and will throw an exception otherwise.
  283. *
  284. * @param mixed $mixContent
  285. * @return QQNode
  286. */
  287. protected function ResolveContentItem($mixContent) {
  288. if ($mixContent instanceof QQNode) {
  289. if (!$mixContent->_ParentNode)
  290. throw new QCallerException('Content QQNode cannot be a Top Level Node');
  291. if ($mixContent->_RootTableName == 'java_script') {
  292. if (($mixContent instanceof QQReverseReferenceNode) && !($mixContent->_PropertyName))
  293. throw new QCallerException('Content QQNode cannot go through any "To Many" association nodes.');
  294. $objCurrentNode = $mixContent;
  295. while ($objCurrentNode = $objCurrentNode->_ParentNode) {
  296. if (!($objCurrentNode instanceof QQNode))
  297. throw new QCallerException('Content QQNode cannot go through any "To Many" association nodes.');
  298. if (($objCurrentNode instanceof QQReverseReferenceNode) && !($objCurrentNode->_PropertyName))
  299. throw new QCallerException('Content QQNode cannot go through any "To Many" association nodes.');
  300. }
  301. return $mixContent;
  302. } else
  303. throw new QCallerException('Content QQNode has a root table of "' . $mixContent->_RootTableName . '". Must be a root of "java_script".');
  304. } else if (is_string($mixContent)) switch ($mixContent) {
  305. case 'Id': return QQN::JavaScript()->Id;
  306. case 'Name': return QQN::JavaScript()->Name;
  307. case 'Description': return QQN::JavaScript()->Description;
  308. case 'Filename': return QQN::JavaScript()->Filename;
  309. default: throw new QCallerException('Simple Property not found in JavaScriptDataGrid content: ' . $mixContent);
  310. } else if ($mixContent instanceof QQAssociationNode)
  311. throw new QCallerException('Content QQNode cannot go through any "To Many" association nodes.');
  312. else
  313. throw new QCallerException('Invalid Content type');
  314. }
  315. }
  316. ?>