iEntityModel = $iEntityModel; if(!$this->isDefaultLanguage() && $iEntityLanguageModel instanceof iEntityLanguageModel) { $this->iEntityLanguageModel = $iEntityLanguageModel; // only controller allow to control the language for the model $this->iEntityLanguageModel->setLanguage($this->view_language); } } public function getLanguage() { return $this->view_language; } public function isDefaultLanguage() { return IS_DEFAULT_LANGUAGE; } public function getFilterConditions() : array { return array_merge( $this->baseFilterConditions(), $this->extendFilterConditions() ); } // this is supposed to be overwritten by the extending class if required protected function extendFilterConditions() : array { return []; } // just here to show the reserved keys. That's all protected function baseFilterConditions() { $base_filter = [ 'q' => getRequest("q", ''), // keyword search 'q_options' => [ 'field_filters' => [], 'fulltext_fields' => [], 'limit_result' => 2000 ], // q_options as in iSearch->find($keyword, array $field_filters = [], array $fulltext_fields = ["keywords"], $limit_result = 2000) 'featured' => getRequestInt("featured", 0), // 1|-1 'status' => getRequestInt("status", 0), // 1|-1 'excluded_ids' => null, // [id1, id2, ...] 'included_ids' => null,// [id1, id2, ...] // to special filters for language 'translated' => getRequestInt("translated", 0), // 1|-1 // for sorting 'sort_by' => getRequest('sort', ''), // for pagination, not exactly for filter but put here to reserve the keys 'numPerPage' => getRequestInt("show", 20), 'page' => getPageId(), ]; if(getRequest("excluded_ids", '') != '') { $base_filter['excluded_ids'] = explode("-", getRequest("excluded_ids", '')); } if(getRequest("included_ids", '') != '') { $base_filter['included_ids'] = explode("-", getRequest("included_ids", '')); } return $base_filter; } protected function formatItemInList(array $item_info) { return $item_info; } protected function formatItemInfo(array $item_info) { return $item_info; } public function getListByIds(array $list_id, array $condition = array()) : array { $item_list = array_map(function ($item){ return $this->formatItemInList($item); }, $this->iEntityModel->getListByIds($list_id, $condition)); if($this->iEntityLanguageModel) { $item_list_language_info = $this->iEntityLanguageModel->getListByIds($list_id); $final_list = []; foreach ($item_list as $item) { $item_language_info = $item_list_language_info[$item['id']] ?? ["not_translated" => true]; $final_list[] = array_merge($item, $item_language_info); } return $final_list; } return $item_list; } // for extending controller class to validate and clean data in the $raw_filter_condition (ie. from URL) // before sending to model for data querying // extending controller must overwrite this protected function validateAndCleanFilterCondition(array $raw_filter_condition) : array { $clean_values = []; foreach ($raw_filter_condition as $key => $value) { // default if(is_array($value)) { $clean_values[$key] = DataClean::makeListOfInputSafe($value, DataType::ID); }else{ $clean_values[$key] = DataClean::makeInputSafe($value, DataType::ID); } } return $clean_values; } /** * @description utility to inspect the actual filters which will be used in getList * make sure to edit the ::_buildQueryConditionExtend method on the Model so the Model will parse the filters provided by controller here * @param array $raw_filter_condition * @return string[] */ public function getActualFilterCondition(array $raw_filter_condition) : array { return $this->buildFilterQuery($raw_filter_condition); } /** * @description utility to inspect the actual filters which will be used in getList by Model * @param array $raw_filter_condition * @return string[] */ public function getModelFilterCondition(array $raw_filter_condition) : array { return $this->iEntityModel->getQueryCondition($this->buildFilterQuery($raw_filter_condition)); } public function getList(array $raw_filter_condition) : array { $filter_condition = $this->buildFilterQuery($raw_filter_condition); //debug_var($filter_condition); $item_list = array_map(function ($item){ return $this->formatItemInList($item); }, $this->iEntityModel->getList($filter_condition)); if($this->iEntityLanguageModel) { $item_list_ids = array_map(function ($item){ return $item['id']; }, $item_list); $item_list_language_info = $this->iEntityLanguageModel->getListByIds($item_list_ids); $final_list = []; foreach ($item_list as $item) { $item_language_info = $item_list_language_info[$item['id']] ?? ["not_translated" => true]; $final_list[] = array_merge($item, $item_language_info); } return $final_list; } return $item_list; } public function getTotal(array $raw_filter_condition) : int { $filter_condition = $this->buildFilterQuery($raw_filter_condition); return $this->iEntityModel->getTotal($filter_condition); } protected function buildFilterQuery(array $raw_filter_condition) : array { $filter_condition = $this->validateAndCleanFilterCondition($raw_filter_condition); // special case to filter out which ids have not been translated if(isset($filter_condition['translated']) && $filter_condition['translated'] && $this->iEntityLanguageModel) { if($filter_condition['translated'] == 1) { $filter_condition['included_ids'] = $this->iEntityLanguageModel->getTranslatedIds(); }else{ $filter_condition['excluded_ids'] = $this->iEntityLanguageModel->getTranslatedIds(); } } return $filter_condition; } public function getInfo($id): ?array { if(!$id) return null; return self::getCache("getInfo-".$id."-".$this->view_language, function () use ($id){ $info = $this->iEntityModel->getInfo($id); if($this->iEntityLanguageModel && $info) { $item_language_info = $this->iEntityLanguageModel->getInfo($id); //debug_var($item_language_info); if($item_language_info) { return $this->formatItemInfo(array_merge($info, $item_language_info)); }else{ $info["not_translated"] = true; return $this->formatItemInfo($info); } } return ($info) ? $this->formatItemInfo($info) : null; }); } }