diff --git a/e107_admin/links.php b/e107_admin/links.php index bbcb1a885..5f4afff32 100644 --- a/e107_admin/links.php +++ b/e107_admin/links.php @@ -75,7 +75,7 @@ class links_admin_ui extends e_admin_ui 'link_button' => array('title'=> LAN_ICON, 'type'=>'icon', 'width'=>'5%', 'thclass'=>'center', 'class'=>'center', 'readParms'=>array('legacy'=>'{e_IMAGE}icons/'), 'writeParms'=>'glyphs=1'), 'link_id' => array('title'=> LAN_ID, 'type'=>'method', 'readParms'=>'', 'noedit'=>TRUE), 'link_name' => array('title'=> LAN_NAME, 'type'=>'text', 'inline'=>true, 'required'=>false, 'validate'=>false, 'width'=>'auto', 'writeParms'=>array('size'=>'xlarge')), // not required as only an icon may be used. - 'link_category' => array('title'=> LAN_TEMPLATE, 'type'=>'dropdown', 'inline'=>true, 'batch'=>true, 'filter'=>true, 'width'=>'auto', 'writeParms'=>array('size'=>'xlarge')), + 'link_category' => array('title'=> LAN_TEMPLATE, 'type'=>'dropdown', 'data'=>'str', 'inline'=>true, 'batch'=>true, 'filter'=>true, 'width'=>'auto', 'writeParms'=>array('size'=>'xlarge')), 'link_parent' => array('title'=> LAN_PARENT, 'type' => 'method', 'data'=>'int', 'width'=>'auto', 'batch'=>true, 'filter'=>true, 'thclass'=>'left first', 'writeParms'=>array('size'=>'xlarge')), 'link_url' => array('title'=> LAN_URL, 'width'=>'auto', 'type'=>'method', 'inline'=>true, 'required'=>true,'validate' => true, 'writeParms'=>'size=xxlarge'), diff --git a/e107_handlers/admin_ui.php b/e107_handlers/admin_ui.php index adceec6f3..04201ff2c 100755 --- a/e107_handlers/admin_ui.php +++ b/e107_handlers/admin_ui.php @@ -3400,6 +3400,11 @@ class e_admin_controller_ui extends e_admin_controller return (isset($this->tableJoin[$table][$att_name]) ? $this->tableJoin[$table][$att_name] : $default_att); } + public function setListOrder($order) + { + $this->listOrder = $order; + } + /** * @param $table * @param $data @@ -3997,19 +4002,11 @@ class e_admin_controller_ui extends e_admin_controller //something like handleListUrlTypeFilter(); for custom handling of 'url_type' field name filters $method = 'handle'.$this->getRequest()->getActionName().$this->getRequest()->camelize($filter[0]).'Filter'; $args = array_slice($filter, 1); - // fwrite(STDOUT, __LINE__ . " Searching custom method: " . $method . "\n"); + e107::getMessage()->addDebug('Searching for custom filter method: ' .$method. '(' .implode(', ', $args). ')'); - if (method_exists($this, $method)) // method handling + if (property_exists($this, $method)) // dynamic property handling { - e107::getMessage()->addDebug('Executing filter callback ' . get_class($this) . '::' . $method . '(' . implode(', ', $args) . ')'); - - return call_user_func_array([$this, $method], $args); - } - elseif (property_exists($this, $method)) // dynamic property handling - { - - // Debug information showing that the property was found e107::getMessage()->addDebug('Accessing filter property ' . get_class($this) . '::$' . $method . ''); if (is_callable($this->$method)) @@ -4024,7 +4021,12 @@ class e_admin_controller_ui extends e_admin_controller return $this->$method; } + elseif (method_exists($this, $method)) // method handling + { + e107::getMessage()->addDebug('Executing filter callback ' . get_class($this) . '::' . $method . '(' . implode(', ', $args) . ')'); + return call_user_func_array([$this, $method], $args); + } $res = array($filter[0], $filter[1]); $this->_log('listQry Filtered by ' .$filter[0]. ' (' .$filter[1]. ')'); @@ -4884,45 +4886,29 @@ class e_admin_controller_ui extends e_admin_controller } /** - * @param $listQry - * @param $searchTerm - * @param $filterOptions - * @param string $tablePath - * @param $isfilter - * @param string $tableFrom - * @param string $primaryName - * @param $raw - * @param $orderField - * @param $qryAsc - * @param $forceFrom - * @param int $qryFrom - * @param $forceTo - * @param int $perPage - * @param $qryField - * @return array|Custom|false|string|string[] + * Modifies a list query with search parameters and filters. + * + * @param string $listQry The base list query string to be modified. + * @param string $searchTerm The search term to filter records. + * @param string $filterOptions The filter options for customizing the query. + * @param string $tablePath The table path for the query. + * @param string $tableFrom The primary table being queried. + * @param string $primaryName The primary key name of the table. + * @param mixed $raw Raw data that can influence query behavior. + * @param mixed $orderField The field by which to order results. + * @param mixed $qryAsc Sort order for the query (ascending or descending). + * @param mixed $forceFrom Forced starting position in the query. + * @param int $qryFrom Starting offset for the query. + * @param mixed $forceTo Forced ending position in the query. + * @param int $perPage The number of results per page. + * @param mixed $qryField Specific query field(s) to filter. + * @param mixed $isfilter Determines if a specific filter is applied. + * @param mixed $handleAction Custom action handler for the search process. + * @return void */ - public function _modifyListQrySearch($listQry, $searchTerm, $filterOptions, string $tablePath, string $tableFrom, string $primaryName, $raw, $orderField, $qryAsc, $forceFrom, int $qryFrom, $forceTo, int $perPage, $qryField, $isfilter, $handleAction) + public function _modifyListQrySearch(string|null $listQry, string $searchTerm, string $filterOptions, string $tablePath, string $tableFrom, string $primaryName, $raw, $orderField, $qryAsc, $forceFrom, int $qryFrom, $forceTo, int $perPage, $qryField, $isfilter, $handleAction) { - -/* - e107::getMessage()->addDebug('listQry: ' . $listQry); - e107::getMessage()->addDebug('searchTerm: ' . $searchTerm); - e107::getMessage()->addDebug('filterOptions: ' . $filterOptions); - e107::getMessage()->addDebug('tablePath: ' . $tablePath); - e107::getMessage()->addDebug('handleAction: ' . $handleAction); - e107::getMessage()->addDebug('tableFrom: ' . $tableFrom); - e107::getMessage()->addDebug('primaryName: ' . $primaryName); - e107::getMessage()->addDebug('raw: ' . $raw); - e107::getMessage()->addDebug('orderField: ' . $orderField); - e107::getMessage()->addDebug('qryAsc: ' . $qryAsc); - e107::getMessage()->addDebug('forceFrom: ' . $forceFrom); - e107::getMessage()->addDebug('qryFrom: ' . $qryFrom); - e107::getMessage()->addDebug('forceTo: ' . $forceTo); - e107::getMessage()->addDebug('perPage: ' . $perPage); - e107::getMessage()->addDebug('qryField: ' . $qryField); - e107::getMessage()->addDebug('isfilter: ' . ($isfilter ? 'true' : 'false'));*/ - - + $generateTest = false; $tp = e107::getParser(); $fields = $this->getFields(); $joinData = $this->getJoinData(); @@ -4939,9 +4925,46 @@ class e_admin_controller_ui extends e_admin_controller $searchQuery = $this->fixSearchWildcards($searchTerm); $searchFilter = $this->_parseFilterRequest($filterOptions); - $listQry = $this->listQry; // check for modification during parseFilterRequest(); + $debugData = [ + 'uri' => e_REQUEST_URI, + 'methodInvocation' => [ + 'listQry' => (string) $listQry, + 'searchTerm' => $searchTerm, + 'filterOptions'=> $filterOptions, + 'tablePath' => $tablePath, + 'tableFrom' => $tableFrom, + 'primaryName' => $primaryName, + 'raw' => (bool) $raw, + 'orderField' => $orderField, + 'qryAsc' => $qryAsc, + 'forceFrom' => $forceFrom, + 'qryFrom' => $qryFrom, + 'forceTo' => $forceTo, + 'perPage' => $perPage, + 'qryField' => $qryField, + 'isfilter' => $isfilter, + 'handleAction' => $handleAction + ], + 'preProcessedData' => [ + 'fields' => $fields, + 'joinData' => $joinData, + 'listOrder' => $this->listOrder, + ], + 'intermediateStates' => [ + 'searchTerm' => $searchTerm, + 'searchQuery' => $searchQuery, + 'searchFilter'=> $searchFilter, + 'listQry' => $this->listQry + ] + ]; + + + + + + if(E107_DEBUG_LEVEL == E107_DBG_SQLQUERIES) { e107::getMessage()->addDebug('searchQuery: ' . $searchQuery . ''); @@ -4954,7 +4977,16 @@ class e_admin_controller_ui extends e_admin_controller if($filterField && $filterValue !== '' && isset($fields[$filterField])) { - $_dataType = $fields[$filterField]['data']; + if(!empty($fields[$filterField]['data'])) + { + $_dataType = $fields[$filterField]['data']; + } + else + { + $_dataType = 'str'; + e107::getMessage()->addInfo('Field ' . $filterField . ' has no data type. Using default str.'); + } + $_fieldType = $fields[$filterField]['type']; if($_fieldType === 'comma' || $_fieldType === 'checkboxes' || $_fieldType === 'userclasses' || ($_fieldType === 'dropdown' && !empty($fields[$filterField]['writeParms']['multiple']))) @@ -5390,6 +5422,27 @@ class e_admin_controller_ui extends e_admin_controller $this->_log('listQry: ' . str_replace('#', MPREFIX, $qry)); + // JSON encode the debug data + $debugData['intermediateStates']['listQryBeforeFinal'] = $listQry; + + $debugData['expected'] = $qry; + $jsonDebugInfo = json_encode($debugData, JSON_PRETTY_PRINT); + + // Optionally log the JSON data to a file for inspection + if($generateTest && !e107::isCli()) + { + $path = e_BASE."e107_tests/tests/_data/e_admin_ui/_modifyListQrySearch/".sha1($jsonDebugInfo).".json"; + if(file_put_contents($path, $jsonDebugInfo . PHP_EOL, FILE_APPEND)) + { + e107::getMessage()->addDebug('Saved test info to ' . $path); + } + } + + + // Print to the debug interface (optional, can overload logs) + e107::getMessage()->addDebug('
' . $jsonDebugInfo . '
'); + + return $qry; } diff --git a/e107_tests/tests/_data/e_admin_ui/_modifyListQrySearch/d75574c0326e90c5a9eb6c187ba7c75f45a0cf70.json b/e107_tests/tests/_data/e_admin_ui/_modifyListQrySearch/d75574c0326e90c5a9eb6c187ba7c75f45a0cf70.json new file mode 100644 index 000000000..5218864fb --- /dev/null +++ b/e107_tests/tests/_data/e_admin_ui/_modifyListQrySearch/d75574c0326e90c5a9eb6c187ba7c75f45a0cf70.json @@ -0,0 +1,676 @@ +{ + "uri": "\/e107v2\/e107_admin\/newspost.php?searchquery=e107&filter_options=searchfield__news_title&mode=main&action=list&etrigger_filter=etrigger_filter", + "methodInvocation": { + "listQry": "SELECT n.*, nc.category_name, nc.category_sef, u.user_id,u.user_name FROM `#news` AS n \n LEFT JOIN `#news_category` AS nc ON n.news_category = nc.category_id \n LEFT JOIN `#user` AS u ON n.news_author = u.user_id ", + "searchTerm": "e107", + "filterOptions": "searchfield__news_title", + "tablePath": "`#news`.", + "tableFrom": "`#news`", + "primaryName": "news_id", + "raw": false, + "orderField": null, + "qryAsc": null, + "forceFrom": false, + "qryFrom": 0, + "forceTo": false, + "perPage": 10, + "qryField": null, + "isfilter": false, + "handleAction": "List" + }, + "preProcessedData": { + "fields": { + "checkboxes": { + "title": "", + "type": null, + "width": "3%", + "thclass": "center first", + "class": "center", + "nosort": true, + "toggle": "news_selected", + "forced": true, + "table": "news", + "alias": "", + "field": "checkboxes", + "__tableField": "`#news`.checkboxes", + "__tableFrom": "`#news`.checkboxes" + }, + "news_id": { + "title": "ID", + "type": "text", + "width": "5%", + "thclass": "center", + "class": "center", + "nosort": false, + "readParms": "link=sef&target=blank", + "table": "news", + "alias": "n.news_id", + "field": "news_id", + "__tableField": "n.news_id", + "__tableFrom": "`#news`.news_id AS n.news_id" + }, + "news_thumbnail": { + "title": "Image\/Video", + "type": "method", + "data": "str", + "width": "110px", + "thclass": "center", + "class": "center", + "nosort": false, + "readParms": "thumb=60&thumb_urlraw=0&thumb_aw=60", + "readonly": false, + "table": "news", + "alias": "n.news_thumbnail", + "field": "news_thumbnail", + "__tableField": "n.news_thumbnail", + "__tableFrom": "`#news`.news_thumbnail AS n.news_thumbnail" + }, + "news_title": { + "title": "Title", + "type": "text", + "data": "safestr", + "filter": true, + "tab": 0, + "writeParms": { + "required": 1, + "size": "block-level" + }, + "inline": true, + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "table": "news", + "alias": "n.news_title", + "field": "news_title", + "__tableField": "n.news_title", + "__tableFrom": "`#news`.news_title AS n.news_title" + }, + "news_summary": { + "title": "Summary", + "type": "text", + "data": "safestr", + "filter": true, + "tab": 0, + "inline": true, + "writeParms": "size=block-level", + "width": "auto", + "thclass": "left", + "class": "left", + "nosort": false, + "table": "news", + "alias": "n.news_summary", + "field": "news_summary", + "__tableField": "n.news_summary", + "__tableFrom": "`#news`.news_summary AS n.news_summary" + }, + "news_body": { + "title": "", + "type": "method", + "data": "str", + "tab": 0, + "nolist": true, + "writeParms": "nolabel=1", + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "table": "news", + "alias": "n.news_body", + "field": "news_body", + "__tableField": "n.news_body", + "__tableFrom": "`#news`.news_body AS n.news_body" + }, + "news_extended": { + "title": "", + "type": null, + "data": "str", + "tab": 0, + "nolist": true, + "noedit": true, + "writeParms": "nolabel=1", + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "table": "news", + "alias": "n.news_extended", + "field": "news_extended", + "__tableField": "n.news_extended", + "__tableFrom": "`#news`.news_extended AS n.news_extended" + }, + "news_meta_title": { + "title": "Meta Title", + "type": "text", + "data": "safestr", + "filter": true, + "tab": 1, + "inline": true, + "width": "auto", + "help": "", + "writeParms": { + "size": "xxlarge", + "placeholder": "", + "counter": 0, + "maxlength": 255 + }, + "nosort": false, + "table": "news", + "alias": "n.news_meta_title", + "field": "news_meta_title", + "__tableField": "n.news_meta_title", + "__tableFrom": "`#news`.news_meta_title AS n.news_meta_title" + }, + "news_meta_keywords": { + "title": "Keywords", + "type": "tags", + "data": "safestr", + "filter": true, + "tab": 1, + "inline": true, + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "readParms": { + "maxlength": 255, + "maxItems": 30 + }, + "writeParms": { + "maxItems": 30, + "maxlength": 255 + }, + "table": "news", + "alias": "n.news_meta_keywords", + "field": "news_meta_keywords", + "__tableField": "n.news_meta_keywords", + "__tableFrom": "`#news`.news_meta_keywords AS n.news_meta_keywords" + }, + "news_meta_description": { + "title": "Meta Description", + "type": "textarea", + "data": "safestr", + "filter": true, + "tab": 1, + "width": "auto", + "thclass": "", + "help": "", + "class": null, + "nosort": false, + "writeParms": { + "size": "xxlarge", + "counter": 0, + "maxlength": 255, + "rows": 2 + }, + "table": "news", + "alias": "n.news_meta_description", + "field": "news_meta_description", + "__tableField": "n.news_meta_description", + "__tableFrom": "`#news`.news_meta_description AS n.news_meta_description" + }, + "news_meta_robots": { + "title": "Robots", + "type": "dropdown", + "data": "safestr", + "tab": 1, + "inline": true, + "readParms": { + "type": "checkboxes" + }, + "writeParms": { + "multiple": 1, + "optArray": { + "noindex": "NoIndex", + "nofollow": "NoFollow", + "noarchive": "NoArchive", + "noimageindex": "NoImageIndex" + }, + "title": { + "noindex": "Prevent search engines from indexing this item.", + "nofollow": "Prevent search engines from following links in this item.", + "noarchive": "Prevent cached copies of this item from appearing in search results.", + "noimageindex": "Prevent search engines from indexing images of this item." + } + }, + "width": "auto", + "thclass": "left", + "class": "left", + "nosort": false, + "batch": true, + "filter": true, + "table": "news", + "alias": "n.news_meta_robots", + "field": "news_meta_robots", + "__tableField": "n.news_meta_robots", + "__tableFrom": "`#news`.news_meta_robots AS n.news_meta_robots" + }, + "news_sef": { + "title": "SEF URL", + "type": "text", + "batch": 1, + "data": "str", + "tab": 1, + "inline": true, + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "writeParms": { + "size": "xxlarge", + "show": 1, + "sef": "news_title" + }, + "table": "news", + "alias": "n.news_sef", + "field": "news_sef", + "__tableField": "n.news_sef", + "__tableFrom": "`#news`.news_sef AS n.news_sef" + }, + "news_author": { + "title": "Author", + "type": "method", + "tab": 2, + "readParms": "idField=user_id&nameField=user_name", + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "table": "news", + "alias": "n.news_author", + "__tableField": "n.news_author", + "__tableFrom": "`#news`.news_author AS n.news_author", + "field": "news_author" + }, + "news_datestamp": { + "title": "Date stamp", + "type": "datestamp", + "data": "int", + "tab": 2, + "writeParms": "type=datetime", + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "filter": true, + "batch": true, + "table": "news", + "alias": "n.news_datestamp", + "field": "news_datestamp", + "__tableField": "n.news_datestamp", + "__tableFrom": "`#news`.news_datestamp AS n.news_datestamp" + }, + "news_category": { + "title": "Category", + "type": "dropdown", + "data": "int", + "tab": 0, + "inline": true, + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "batch": true, + "filter": true, + "table": "news", + "alias": "n.news_category", + "__tableField": "n.news_category", + "__tableFrom": "`#news`.news_category AS n.news_category", + "field": "news_category", + "writeParms": { + "optArray": { + "2": "Category 1", + "3": "Category 2", + "1": "Misc" + }, + "size": "xlarge" + } + }, + "news_start": { + "title": "Start", + "type": "datestamp", + "data": "int", + "tab": 2, + "writeParms": "type=datetime", + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "table": "news", + "alias": "n.news_start", + "field": "news_start", + "__tableField": "n.news_start", + "__tableFrom": "`#news`.news_start AS n.news_start" + }, + "news_end": { + "title": "End", + "type": "datestamp", + "data": "int", + "tab": 2, + "writeParms": "type=datetime", + "width": "auto", + "thclass": "", + "class": null, + "nosort": false, + "table": "news", + "alias": "n.news_end", + "field": "news_end", + "__tableField": "n.news_end", + "__tableFrom": "`#news`.news_end AS n.news_end" + }, + "news_class": { + "title": "Visibility", + "type": "userclass", + "tab": 2, + "inline": true, + "width": "auto", + "thclass": "", + "class": null, + "batch": true, + "filter": true, + "table": "news", + "alias": "n.news_class", + "field": "news_class", + "__tableField": "n.news_class", + "__tableFrom": "`#news`.news_class AS n.news_class" + }, + "news_template": { + "title": "Template", + "type": "method", + "data": "safestr", + "tab": 2, + "inline": true, + "writeParms": { + "plugin": "news", + "id": "news_view", + "area": "front", + "merge": false + }, + "width": "auto", + "thclass": "left", + "class": "left", + "nosort": false, + "batch": true, + "filter": true, + "table": "news", + "alias": "n.news_template", + "field": "news_template", + "__tableField": "n.news_template", + "__tableFrom": "`#news`.news_template AS n.news_template" + }, + "news_render_type": { + "title": "Location", + "type": "dropdown", + "data": "safestr", + "tab": 2, + "inline": true, + "readParms": { + "type": "checkboxes" + }, + "width": "auto", + "thclass": "left", + "class": "left", + "nosort": false, + "batch": true, + "filter": true, + "table": "news", + "alias": "n.news_render_type", + "field": "news_render_type", + "__tableField": "n.news_render_type", + "__tableFrom": "`#news`.news_render_type AS n.news_render_type", + "writeParms": { + "optArray": { + "0": "Default Area", + "1": "Default Area - Title", + "4": "Default Area - Title\/Summary", + "2": "Sidebar - Othernews", + "3": "Sidebar - Othernews 2", + "5": "Carousel", + "6": "News Grid Menu" + }, + "multiple": 1, + "empty": "0" + } + }, + "news_sticky": { + "title": "Sticky", + "type": "boolean", + "data": "int", + "tab": 2, + "width": "auto", + "thclass": "center", + "inline": true, + "class": "center", + "nosort": false, + "batch": true, + "filter": true, + "table": "news", + "alias": "n.news_sticky", + "field": "news_sticky", + "__tableField": "n.news_sticky", + "__tableFrom": "`#news`.news_sticky AS n.news_sticky" + }, + "news_modified": { + "title": "Last Updated", + "type": "datestamp", + "readonly": true, + "noedit": true, + "data": "int", + "tab": 2, + "width": "auto", + "thclass": "center", + "inline": false, + "class": "center", + "nosort": false, + "batch": false, + "filter": true, + "table": "news", + "alias": "n.news_modified", + "field": "news_modified", + "__tableField": "n.news_modified", + "__tableFrom": "`#news`.news_modified AS n.news_modified" + }, + "news_allow_comments": { + "title": "Comments", + "type": "boolean", + "data": "int", + "tab": 2, + "writeParms": "inverse=1", + "width": "auto", + "thclass": "center", + "class": "center", + "nosort": false, + "batch": true, + "filter": true, + "readParms": "reverse=1", + "table": "news", + "alias": "n.news_allow_comments", + "field": "news_allow_comments", + "__tableField": "n.news_allow_comments", + "__tableFrom": "`#news`.news_allow_comments AS n.news_allow_comments" + }, + "news_comment_total": { + "title": "Comment Total", + "type": "number", + "data": "int", + "tab": 2, + "noedit": true, + "width": "10%", + "thclass": "", + "class": null, + "nosort": false, + "table": "news", + "alias": "n.news_comment_total", + "field": "news_comment_total", + "__tableField": "n.news_comment_total", + "__tableFrom": "`#news`.news_comment_total AS n.news_comment_total" + }, + "news_email_notify": { + "title": "Email notification", + "type": "checkbox", + "tab": 2, + "data": false, + "writeParms": { + "show": 1, + "tdClassRight": "form-inline", + "post": "Configure<\/a><\/span>" + }, + "help": "Trigger an email notification when you submit this form.", + "table": "news", + "alias": "n.news_email_notify", + "field": "news_email_notify", + "__tableField": "n.news_email_notify", + "__tableFrom": "`#news`.news_email_notify AS n.news_email_notify" + }, + "submitted_id": { + "title": "Submitted Item", + "type": "hidden", + "tab": 2, + "data": false, + "writeParms": "show=0", + "table": "news", + "alias": "n.submitted_id", + "field": "submitted_id", + "__tableField": "n.submitted_id", + "__tableFrom": "`#news`.submitted_id AS n.submitted_id" + }, + "x__blank_url": { + "title": "Blank URL", + "type": "url", + "tab": 1, + "writeParms": { + "size": "xxlarge", + "placeholder": "", + "default": "https:\/\/" + }, + "width": "auto", + "help": "", + "readParms": "", + "class": "left", + "thclass": "left", + "data": false + }, + "x__blank_custom": { + "title": "Blank Custom", + "type": "method", + "tab": 1, + "writeParms": { + "size": "xxlarge", + "placeholder": "", + "default": "https:\/\/" + }, + "width": "auto", + "help": "", + "readParms": "", + "class": "left", + "thclass": "left", + "data": false, + "method": "_blank_admin_form::x__blank_custom" + }, + "x_ahrefs_traffic": { + "title": "Organic Traffic", + "type": "method", + "tab": 1, + "writeParms": { + "size": "xxlarge", + "placeholder": "", + "default": "https:\/\/" + }, + "width": "auto", + "help": "", + "readParms": "", + "class": "left", + "thclass": "left", + "data": false, + "method": "ahrefs_admin_form::x_ahrefs_traffic" + }, + "x_canonical_url": { + "title": "Canonical URL", + "type": "url", + "tab": 1, + "writeParms": { + "size": "xxlarge", + "placeholder": "", + "default": "" + }, + "width": "auto", + "help": "", + "readParms": "", + "class": "left", + "thclass": "left", + "data": false + }, + "x_figure_captions": { + "title": "Image\/Video Captions", + "type": "method", + "tab": 0, + "writeParms": { + "default": null + }, + "width": "auto", + "help": "", + "readParms": [], + "class": "left", + "thclass": "left", + "data": false, + "method": "figure_admin_form::x_figure_captions" + }, + "x_linkwords_stats": { + "title": "Linkwords", + "type": "method", + "tab": 1, + "noedit": true, + "writeParms": [], + "width": "auto", + "help": "", + "readParms": "", + "class": "left", + "thclass": "left", + "data": false, + "method": "linkwords_admin_form::x_linkwords_stats" + }, + "x_reference_url": { + "title": "Reference", + "type": "method", + "tab": "ref", + "writeParms": { + "nolabel": true, + "size": "xxlarge", + "placeholder": "", + "default": "" + }, + "width": "auto", + "help": "", + "readParms": "", + "class": "left", + "thclass": "left", + "data": false, + "method": "reference_admin_form::x_reference_url" + }, + "options": { + "title": "Options", + "type": null, + "width": "10%", + "thclass": "center last", + "class": "center", + "nosort": true, + "forced": true, + "table": "news", + "alias": "", + "field": "options", + "__tableField": "`#news`.options", + "__tableFrom": "`#news`.options" + } + }, + "joinData": [], + "listOrder": "news_id desc" + }, + "intermediateStates": { + "searchTerm": "e107", + "searchQuery": "e107", + "searchFilter": "news_title LIKE '%e107%' ", + "listQry": "SELECT n.*, nc.category_name, nc.category_sef, u.user_id,u.user_name FROM `#news` AS n \n LEFT JOIN `#news_category` AS nc ON n.news_category = nc.category_id \n LEFT JOIN `#user` AS u ON n.news_author = u.user_id ", + "listQryBeforeFinal": "SELECT n.*, nc.category_name, nc.category_sef, u.user_id,u.user_name FROM `#news` AS n \n LEFT JOIN `#news_category` AS nc ON n.news_category = nc.category_id \n LEFT JOIN `#user` AS u ON n.news_author = u.user_id " + }, + "expected": "SELECT n.*, nc.category_name, nc.category_sef, u.user_id,u.user_name FROM `#news` AS n \n LEFT JOIN `#news_category` AS nc ON n.news_category = nc.category_id \n LEFT JOIN `#user` AS u ON n.news_author = u.user_id WHERE news_title LIKE '%e107%' ORDER BY news_id desc LIMIT 0, 10" +} diff --git a/e107_tests/tests/unit/e_admin_controller_uiTest.php b/e107_tests/tests/unit/e_admin_controller_uiTest.php index 866297826..e95900cb3 100644 --- a/e107_tests/tests/unit/e_admin_controller_uiTest.php +++ b/e107_tests/tests/unit/e_admin_controller_uiTest.php @@ -21,8 +21,9 @@ { try { - $this->ui = $this->make(e_admin_controller_ui::class); + $this->ui = $this->make(e_admin_ui::class); $this->req = $this->make(e_admin_request::class); + $this->ui->setRequest($this->req); } catch (Exception $e) { @@ -155,6 +156,36 @@ $this::assertSame($expected, $result); + + + } + + public function test_ModifyListQrySearchField() + { + $listQry = 'SELECT u.* FROM `#user` WHERE 1 '; + $filterOptions = ''; + $tablePath = '`#user`.'; + $tableFrom = '`#user`'; + $primaryName = 'user_id'; + $raw = false; + $orderField = null; + $qryAsc = null; + $forceFrom = false; + $qryFrom = 0; + $forceTo = false; + $perPage = 10; + $qryField = null; + $isfilter = false; + $handleAction = 'List'; + + $this->ui->setFields([ + 'user_id' => array('title'=>'User ID', '__tableField' => 'u.user_id', 'type'=>'int', 'data'=>'int'), + 'user_name' => array('title' => 'Name', '__tableField' => 'u.user_name', 'type' => 'text', 'data'=>'safestr'), // Display name + 'user_login' => array('title' => 'Login','__tableField' => 'u.user_login', 'type' => 'text', 'data'=>'safestr'), // Real name (no real vetting) + 'user_phone' => array('title' => 'Phone','__tableField' => 'u.user_phone', 'search'=>true, 'type' => 'text', 'data'=>'safestr'), // Real name (no real vetting) + + + ]); // Search Specific Field Test $this->req->setAction('List'); @@ -176,7 +207,108 @@ $expected = "SELECT u.* FROM `#user` WHERE 1 AND u.user_phone LIKE '%custom_phone_5551234%' LIMIT 0, 10"; $this::assertSame($expected, $result); + } + + public function test_ModifyListQrySearch_FromJsonFiles() + { + // The directory where the JSON files are stored + $directory = e_BASE . "e107_tests/tests/_data/e_admin_ui/_modifyListQrySearch/"; + if (!is_dir($directory)) + { + $this::fail("Directory does not exist: " . $directory); + } + + // Scan the directory for JSON files + $files = glob($directory . '*.json'); + + $this::assertNotEmpty($files, "No JSON files found in the specified directory!"); + + foreach ($files as $fl) + { + // Ensure the JSON file exists + $file = realpath(codecept_data_dir().str_replace('/', DIRECTORY_SEPARATOR, '/e_admin_ui/_modifyListQrySearch/') . basename($fl)); + if (!file_exists($file)) + { + $this::fail("File doesn't exist: " . $file); + } + + // Load JSON content + $jsonContent = file_get_contents($file); + if (empty($jsonContent)) + { + $this::fail("Failed to read JSON file: " . $file); + } + + // Decode JSON + $data = json_decode($jsonContent, true); + if ($data === null) + { + $error = json_last_error_msg(); // Get a readable explanation of the problem + $this::fail("JSON decoding failed for file: $file. Error: " . $error); + } + + // Ensure JSON data is valid + $this::assertNotEmpty($data, "Failed to decode JSON file: " . $file); + + // Extract input parameters from JSON structure + $methodInvocation = $data['methodInvocation']; + $preProcessedData = $data['preProcessedData']; + $expected = $data['expected']; + + // Verify fields are present in the JSON + if (empty($preProcessedData['fields'])) + { + $this::fail("Fields are not defined in the JSON file: " . $file); + } + + if(!empty($preProcessedData['listOrder'])) + { + $this->ui->setListOrder($preProcessedData['listOrder']); + } + + $this->ui->setFields($preProcessedData['fields']); + + $queryValue = $this->ui->getQuery('searchquery'); + + if(!empty($methodInvocation['searchTerm'])) + { + $this->ui->setQuery('searchquery', $methodInvocation['searchTerm']); + } + + if(!empty($methodInvocation['handleAction'])) + { + $this->req->setAction($methodInvocation['handleAction']); + } + + $query = $this->ui->_modifyListQrySearch( + $methodInvocation['listQry'], + $methodInvocation['searchTerm'], + $methodInvocation['filterOptions'], + $methodInvocation['tablePath'], + $methodInvocation['tableFrom'], + $methodInvocation['primaryName'], + $methodInvocation['raw'], + $methodInvocation['orderField'], + $methodInvocation['qryAsc'], + $methodInvocation['forceFrom'], + $methodInvocation['qryFrom'], + $methodInvocation['forceTo'], + $methodInvocation['perPage'], + $methodInvocation['qryField'], + $methodInvocation['isfilter'], + $methodInvocation['handleAction'] + ); + + $this::assertEquals($expected, $query, "Test failed for JSON file: " . $file); + } + } + + + + + + /* public function testGetSortParent() {