/**
  * Get item properties
  *
  * @return	array		array of property arrays:
  *					"alert" (boolean) => display as an alert property (usually in red)
  *					"property" (string) => property name
  *					"value" (string) => property value
  */
 public function getProperties()
 {
     global $lng, $ilUser;
     $props = array();
     include_once "./Modules/DataCollection/classes/class.ilObjDataCollectionAccess.php";
     if (!ilObjDataCollectionAccess::_lookupOnline($this->obj_id)) {
         $props[] = array("alert" => true, "property" => $lng->txt("status"), "value" => $lng->txt("offline"));
     }
     return $props;
 }
 /**
  * @param $found
  *
  * @return string
  */
 public function doExtReplace($found)
 {
     $ref_rec_ids = $this->record_obj->getRecordFieldValue($this->currentField->getId());
     if (!is_array($ref_rec_ids)) {
         $ref_rec_ids = array($ref_rec_ids);
     }
     if (!count($ref_rec_ids) || !$ref_rec_ids) {
         return;
     }
     $ref_recs = array();
     foreach ($ref_rec_ids as $ref_rec_id) {
         $ref_recs[] = ilDataCollectionCache::getRecordCache($ref_rec_id);
     }
     $field = $ref_recs[0]->getTable()->getFieldByTitle($found[1]);
     $tpl = new ilTemplate("tpl.reference_list.html", true, true, "Modules/DataCollection");
     $tpl->setCurrentBlock("reference_list");
     if (!$field) {
         if (ilObjDataCollectionAccess::_hasWriteAccess($this->dcl_gui_object->ref_id)) {
             ilUtil::sendInfo("Bad Viewdefinition at [ext tableOf=\"" . $found[1] . "\" ...]", true);
         }
         return;
     }
     foreach ($ref_recs as $ref_record) {
         $tpl->setCurrentBlock("reference");
         $tpl->setVariable("CONTENT", $ref_record->getRecordFieldHTML($field->getId()));
         $tpl->parseCurrentBlock();
     }
     //$ref_rec->getRecordFieldHTML($field->getId())
     if ($field) {
         return $tpl->get();
     }
 }
 /**
  * @param $ref int the reference id of the datacollection object to check.
  *
  * @deprecated
  * @return bool whether or not the current user has add/edit_entry access to the referenced datacollection
  */
 public static function _hasReadAccess($ref)
 {
     return ilObjDataCollectionAccess::hasReadAccess($ref);
 }
 /**
  * @return bool
  */
 public function executeCommand()
 {
     if ($_GET['mode']) {
         $this->ctrl->saveParameter($this, 'mode');
         $this->ctrl->setParameterByClass("ildatacollectionrecordlistgui", "mode", $_GET['mode']);
     }
     $this->ctrl->saveParameter($this, 'redirect');
     if ($this->record_id) {
         $this->record = ilDataCollectionCache::getRecordCache($this->record_id);
         if (!$this->record->hasPermissionToEdit($this->parent_obj->ref_id) or !$this->record->hasPermissionToView($this->parent_obj->ref_id)) {
             $this->accessDenied();
         }
         $this->table = $this->record->getTable();
         $this->table_id = $this->table->getId();
     } else {
         $this->table = ilDataCollectionCache::getTableCache($this->table_id);
         if (!ilObjDataCollectionAccess::hasAddRecordAccess($_GET['ref_id'])) {
             $this->accessDenied();
         }
     }
     $cmd = $this->ctrl->getCmd();
     switch ($cmd) {
         default:
             $this->{$cmd}();
             break;
     }
     return true;
 }
 /**
  * checks wether a user may invoke a command or not
  * (this method is called by ilAccessHandler::checkAccess)
  *
  * @param    string $a_cmd        command (not permission!)
  * @param    string $a_permission permission
  * @param    int    $a_ref_id     reference id
  * @param    int    $a_obj_id     object id
  * @param    int    $a_user_id    user id (if not provided, current user is taken)
  *
  * @return    boolean        true, if everything is ok
  */
 public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "")
 {
     global $ilUser, $lng, $rbacsystem, $ilAccess;
     if ($a_user_id == "") {
         $a_user_id = $ilUser->getId();
     }
     switch ($a_cmd) {
         case "view":
             if (!ilObjDataCollectionAccess::_lookupOnline($a_obj_id) && !$rbacsystem->checkAccessOfUser($a_user_id, 'write', $a_ref_id)) {
                 $ilAccess->addInfoItem(IL_NO_OBJECT_ACCESS, $lng->txt("offline"));
                 return false;
             }
             break;
             // for permission query feature
         // for permission query feature
         case "infoScreen":
             if (!ilObjDataCollectionAccess::_lookupOnline($a_obj_id)) {
                 $ilAccess->addInfoItem(IL_NO_OBJECT_ACCESS, $lng->txt("offline"));
             } else {
                 $ilAccess->addInfoItem(IL_STATUS_MESSAGE, $lng->txt("online"));
             }
             break;
     }
     switch ($a_permission) {
         case "read":
         case "visible":
             if (!ilObjDataCollectionAccess::_lookupOnline($a_obj_id) && !$rbacsystem->checkAccessOfUser($a_user_id, 'write', $a_ref_id)) {
                 $ilAccess->addInfoItem(IL_NO_OBJECT_ACCESS, $lng->txt("offline"));
                 return false;
             }
             break;
     }
     return true;
 }
 /**
  * 
  *
  * @param
  * @return
  */
 function checkAccessMobUsage($usage, $oid)
 {
     /**
      * @var $ilObjDataCache ilObjectDataCache
      */
     global $ilObjDataCache;
     switch ($usage['type']) {
         case 'lm:pg':
             if ($oid > 0) {
                 if ($this->checkAccessLM($oid, 'lm', $usage['id'])) {
                     return true;
                 }
             }
             break;
         case 'news':
             // media objects in news (media casts)
             include_once "./Modules/MediaCast/classes/class.ilObjMediaCastAccess.php";
             include_once "./Services/News/classes/class.ilNewsItem.php";
             if ($this->checkAccessObject($oid, 'mcst')) {
                 return true;
             } elseif (ilObjMediaCastAccess::_lookupPublicFiles($oid) && ilNewsItem::_lookupVisibility($usage["id"]) == NEWS_PUBLIC) {
                 return true;
             }
             break;
         case 'dcl:html':
             include_once "./Modules/DataCollection/classes/class.ilObjDataCollectionAccess.php";
             include_once "./Services/Object/classes/class.ilObject2.php";
             $ref_ids = ilObject2::_getAllReferences($oid);
             foreach ($ref_ids as $ref_id) {
                 if (ilObjDataCollectionAccess::_checkAccess("view", "read", $ref_id, $oid)) {
                     return true;
                 }
             }
             break;
         case 'frm~:html':
             // $oid = userid
             foreach ($this->check_users as $user_id) {
                 if ($ilObjDataCache->lookupType($oid) == 'usr' && $oid == $user_id) {
                     return true;
                 }
             }
             break;
         case 'qpl:pg':
         case 'qpl:html':
             // test questions
             if ($this->checkAccessTestQuestion($oid, $usage['id'])) {
                 return true;
             }
             break;
         case 'gdf:pg':
             // special check for glossary terms
             if ($this->checkAccessGlossaryTerm($oid, $usage['id'])) {
                 return true;
             }
             break;
         case 'sahs:pg':
             // check for scorm pages
             if ($this->checkAccessObject($oid, 'sahs')) {
                 return true;
             }
             break;
         case 'prtf:pg':
             // special check for portfolio pages
             if ($this->checkAccessPortfolioPage($oid, $usage['id'])) {
                 return true;
             }
             break;
         case 'blp:pg':
             // special check for blog pages
             if ($this->checkAccessBlogPage($oid, $usage['id'])) {
                 return true;
             }
             break;
         default:
             // standard object check
             if ($this->checkAccessObject($oid)) {
                 return true;
             }
             break;
     }
     return false;
 }
 /**
  * @param int $ref_id
  * @param     $record ilDataCollectionRecord
  *
  * @return bool
  */
 public function hasPermissionToViewRecord($ref_id, $record)
 {
     global $ilUser, $rbacreview;
     /** @var ilRbacReview $rbacreview */
     // Owner of the DataCollection object and ILIAS Administrators can view each record by default
     if ($this->getCollectionObject()->getOwner() == $ilUser->getId() || $rbacreview->isAssigned($ilUser->getId(), 2)) {
         return true;
     }
     if (ilObjDataCollectionAccess::_hasReadAccess($ref_id)) {
         // Check for view only own entries setting
         if ($this->getViewOwnRecordsPerm() && $ilUser->getId() != $record->getOwner()) {
             return false;
         }
         return true;
     }
     return false;
 }
 /**
  * Return only the needed subset of record objects for the table, according to sorting, paging and filters
  *
  * @param string $sort      Title of a field where the ilTable2GUI is sorted
  * @param string $direction 'desc' or 'asc'
  * @param int    $limit     Limit of records
  * @param int    $offset    Offset from records
  * @param array  $filter    Containing the filter values
  *
  * @return array Array with two keys: 'record' => Contains the record objects, 'total' => Number of total records (without slicing)
  */
 public function getPartialRecords($sort, $direction, $limit, $offset, array $filter = array())
 {
     global $ilDB, $ilUser, $rbacreview;
     $sort_field = $sort ? $this->getFieldByTitle($sort) : $this->getField('id');
     $direction = strtolower($direction);
     $direction = in_array($direction, array('desc', 'asc')) ? $direction : 'asc';
     // Sorting by a status from an ILIAS Ref field. This column is added dynamically to the table, there is no field model
     $sort_by_status = false;
     if (substr($sort, 0, 8) == '_status_') {
         $sort_by_status = true;
         $sort_field = $this->getFieldByTitle(substr($sort, 8));
     }
     if (is_null($sort_field)) {
         $sort_field = $this->getField('id');
     }
     $id = $sort_field->getId();
     $stl = $sort_field->getStorageLocation();
     $select_str = '';
     $join_str = '';
     $where_additions = '';
     $has_nref = false;
     if ($sort_field->isStandardField()) {
         if ($id == 'owner' || $id == 'last_edit_by') {
             $join_str .= "LEFT JOIN usr_data AS sort_usr_data_{$id} ON (sort_usr_data_{$id}.usr_id = record.{$id})";
             $select_str .= " sort_usr_data_{$id}.login AS field_{$id},";
         } elseif ($id != 'comments') {
             $select_str .= " record.{$id} AS field_{$id},";
         }
     } else {
         switch ($sort_field->getDatatypeId()) {
             case ilDataCollectionDatatype::INPUTFORMAT_RATING:
                 $rating_joined = true;
                 // FSX Bugfix 0015735: The average is multiplied with 10000 and added to the amount of votes
                 $join_str .= "LEFT JOIN (SELECT (ROUND(AVG(rating), 1) * 10000 + COUNT(rating)) as rating, obj_id FROM il_rating GROUP BY obj_id) AS average ON average.obj_id = record.id";
                 $select_str .= " average.rating AS field_{$id},";
                 break;
             case ilDataCollectionDatatype::INPUTFORMAT_ILIAS_REF:
                 $join_str .= "LEFT JOIN il_dcl_record_field AS sort_record_field_{$id} ON (sort_record_field_{$id}.record_id = record.id AND sort_record_field_{$id}.field_id = " . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
                 $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS sort_stloc_{$id} ON (sort_stloc_{$id}.record_field_id = sort_record_field_{$id}.id) ";
                 $join_str .= "LEFT JOIN object_reference AS sort_object_reference_{$id} ON (sort_object_reference_{$id}.ref_id = sort_stloc_{$id}.value AND sort_object_reference_{$id}.deleted IS NULL)";
                 $join_str .= "LEFT JOIN object_data AS sort_object_data_{$id} ON (sort_object_data_{$id}.obj_id = sort_object_reference_{$id}.obj_id)";
                 if ($sort_by_status) {
                     global $ilUser;
                     $join_str .= "LEFT JOIN ut_lp_marks AS ut ON (ut.obj_id = sort_object_data_{$id}.obj_id AND ut.usr_id = " . $ilDB->quote($ilUser->getId(), 'integer') . ") ";
                 }
                 $select_str .= !$sort_by_status ? " sort_object_data_{$id}.title AS field_{$id}," : " ut.status AS field_{$id}";
                 break;
             case ilDataCollectionDatatype::INPUTFORMAT_FILE:
             case ilDataCollectionDatatype::INPUTFORMAT_MOB:
                 $join_str .= "LEFT JOIN il_dcl_record_field AS sort_record_field_{$id} ON (sort_record_field_{$id}.record_id = record.id AND sort_record_field_{$id}.field_id = " . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
                 $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS sort_stloc_{$id} ON (sort_stloc_{$id}.record_field_id = sort_record_field_{$id}.id) ";
                 $join_str .= "LEFT JOIN object_data AS sort_object_data_{$id} ON (sort_object_data_{$id}.obj_id = sort_stloc_{$id}.value) ";
                 $select_str .= " sort_object_data_{$id}.title AS field_{$id},";
                 break;
             case ilDataCollectionDatatype::INPUTFORMAT_REFERENCE:
                 $prop = $sort_field->getPropertyvalues();
                 $ref_field = ilDataCollectionCache::getFieldCache($sort_field->getFieldRef());
                 $n_ref = $prop[ilDataCollectionField::PROPERTYID_N_REFERENCE];
                 if ($n_ref) {
                     $has_nref = true;
                 }
                 $select_str .= $n_ref ? " GROUP_CONCAT(stloc_{$id}_joined.value) AS field_{$id}" : "stloc_{$id}_joined.value AS field_{$id},";
                 $join_str .= "LEFT JOIN il_dcl_record_field AS record_field_{$id} ON (record_field_{$id}.record_id = record.id AND record_field_{$id}.field_id = " . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
                 $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS stloc_{$id} ON (stloc_{$id}.record_field_id = record_field_{$id}.id) ";
                 $join_str .= "LEFT JOIN il_dcl_record_field AS record_field_{$id}_joined ON (record_field_{$id}_joined.record_id = stloc_{$id}.value AND record_field_{$id}_joined.field_id = " . $ilDB->quote($ref_field->getId(), 'integer') . ") ";
                 $join_str .= "LEFT JOIN il_dcl_stloc{$ref_field->getStorageLocation()}_value AS stloc_{$id}_joined ON (stloc_{$id}_joined.record_field_id = record_field_{$id}_joined.id) ";
                 break;
             case ilDataCollectionDatatype::INPUTFORMAT_DATETIME:
             case ilDataCollectionDatatype::INPUTFORMAT_TEXT:
             case ilDataCollectionDatatype::INPUTFORMAT_BOOLEAN:
             case ilDataCollectionDatatype::INPUTFORMAT_NUMBER:
                 $select_str .= " sort_stloc_{$id}.value AS field_{$id},";
                 $join_str .= "LEFT JOIN il_dcl_record_field AS sort_record_field_{$id} ON (sort_record_field_{$id}.record_id = record.id AND sort_record_field_{$id}.field_id = " . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
                 $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS sort_stloc_{$id} ON (sort_stloc_{$id}.record_field_id = sort_record_field_{$id}.id) ";
                 break;
         }
     }
     if (count($filter)) {
         foreach ($filter as $key => $filter_value) {
             $filter_field_id = substr($key, 7);
             $filter_field = $this->getField($filter_field_id);
             switch ($filter_field->getDatatypeId()) {
                 case ilDataCollectionDatatype::INPUTFORMAT_RATING:
                     if (!$rating_joined) {
                         $join_str .= "LEFT JOIN (SELECT (ROUND(AVG(rating), 1) * 10000 + COUNT(rating)) as rating, obj_id FROM il_rating GROUP BY obj_id) AS average ON average.obj_id = record.id";
                     }
                     // FSX Bugfix 0015735: The average is multiplied with 10000 and added to the amount of votes
                     $where_additions .= " AND average.rating >= " . $ilDB->quote($filter_value * 10000, 'integer');
                     break;
                 case ilDataCollectionDatatype::INPUTFORMAT_ILIAS_REF:
                     $join_str .= "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                     $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id) ";
                     $join_str .= "INNER JOIN object_reference AS filter_object_reference_{$filter_field_id} ON (filter_object_reference_{$filter_field_id}.ref_id = filter_stloc_{$filter_field_id}.value ) ";
                     $join_str .= "INNER JOIN object_data AS filter_object_data_{$filter_field_id} ON (filter_object_data_{$filter_field_id}.obj_id = filter_object_reference_{$filter_field_id}.obj_id AND filter_object_data_{$filter_field_id}.title LIKE " . $ilDB->quote("%{$filter_value}%", 'text') . ") ";
                     break;
                 case ilDataCollectionDatatype::INPUTFORMAT_MOB:
                 case ilDataCollectionDatatype::INPUTFORMAT_FILE:
                     $join_str .= "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                     $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id) ";
                     $join_str .= "INNER JOIN object_data AS filter_object_data_{$filter_field_id} ON (filter_object_data_{$filter_field_id}.obj_id = filter_stloc_{$filter_field_id}.value AND filter_object_data_{$filter_field_id}.title LIKE " . $ilDB->quote("%{$filter_value}%", 'text') . ") ";
                     break;
                 case ilDataCollectionDatatype::INPUTFORMAT_DATETIME:
                     $date_from = isset($filter_value['from']) && is_object($filter_value['from']) ? $filter_value['from'] : NULL;
                     $date_to = isset($filter_value['to']) && is_object($filter_value['to']) ? $filter_value['to'] : NULL;
                     if ($filter_field->isStandardField()) {
                         if ($date_from) {
                             $where_additions .= " AND (record.{$filter_field_id} >= " . $ilDB->quote($date_from, 'date') . ")";
                         }
                         if ($date_to) {
                             $where_additions .= " AND (record.{$filter_field_id} <= " . $ilDB->quote($date_to, 'date') . ")";
                         }
                     } else {
                         $join_str .= "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                         $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id ";
                         if ($date_from) {
                             $join_str .= "AND filter_stloc_{$filter_field_id}.value >= " . $ilDB->quote($date_from, 'date') . " ";
                         }
                         if ($date_to) {
                             $join_str .= "AND filter_stloc_{$filter_field_id}.value <= " . $ilDB->quote($date_to, 'date') . " ";
                         }
                         $join_str .= ") ";
                     }
                     break;
                 case ilDataCollectionDatatype::INPUTFORMAT_NUMBER:
                     $from = isset($filter_value['from']) ? (int) $filter_value['from'] : NULL;
                     $to = isset($filter_value['to']) ? (int) $filter_value['to'] : NULL;
                     if ($filter_field->isStandardField()) {
                         if (!is_null($from)) {
                             $where_additions .= " AND record.{$filter_field_id} >= " . $ilDB->quote($from, 'integer');
                         }
                         if (!is_null($to)) {
                             $where_additions .= " AND record.{$filter_field_id} <= " . $ilDB->quote($to, 'integer');
                         }
                     } else {
                         $join_str .= "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                         $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id";
                         if (!is_null($from)) {
                             $join_str .= " AND filter_stloc_{$filter_field_id}.value >= " . $ilDB->quote($from, 'integer');
                         }
                         if (!is_null($to)) {
                             $join_str .= " AND filter_stloc_{$filter_field_id}.value <= " . $ilDB->quote($to, 'integer');
                         }
                         $join_str .= ") ";
                     }
                     break;
                 case ilDataCollectionDatatype::INPUTFORMAT_BOOLEAN:
                     if ($filter_value == "checked") {
                         $join_str .= "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                         $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id";
                         $join_str .= " AND filter_stloc_{$filter_field_id}.value = " . $ilDB->quote(1, 'integer');
                     } else {
                         $join_str .= "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                         $join_str .= "LEFT JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id";
                         $where_additions .= " AND (filter_stloc_{$filter_field_id}.value <> " . $ilDB->quote(1, 'integer') . " OR filter_stloc_{$filter_field_id}.value is NULL)";
                     }
                     $join_str .= " ) ";
                     break;
                 case ilDataCollectionDatatype::INPUTFORMAT_TEXT:
                     if ($filter_field->isStandardField()) {
                         $join_str .= "INNER JOIN usr_data AS filter_usr_data_{$filter_field_id} ON (filter_usr_data_{$filter_field_id}.usr_id = record.{$filter_field_id} AND filter_usr_data_{$filter_field_id}.login LIKE " . $ilDB->quote("%{$filter_value}%", 'text') . ") ";
                     } else {
                         $join_str .= " INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                         $join_str .= " INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id AND filter_stloc_{$filter_field_id}.value LIKE " . $ilDB->quote("%{$filter_value}%", 'text') . ") ";
                     }
                     break;
                 case ilDataCollectionDatatype::INPUTFORMAT_REFERENCE:
                     $join_str .= " INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = " . $ilDB->quote($filter_field_id, 'integer') . ") ";
                     $prop = $filter_field->getPropertyvalues();
                     $n_ref = $prop[ilDataCollectionField::PROPERTYID_N_REFERENCE];
                     if ($n_ref) {
                         $join_str .= " INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id AND filter_stloc_{$filter_field_id}.value LIKE " . $ilDB->quote("%{$filter_value}%", 'text') . ") ";
                     } else {
                         $join_str .= " INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id AND filter_stloc_{$filter_field_id}.value = " . $ilDB->quote($filter_value, 'integer') . ") ";
                     }
                     break;
             }
         }
     }
     // Build the query string
     $sql = "SELECT DISTINCT record.id, record.owner";
     if ($select_str) {
         $sql .= ', ';
     }
     $sql .= rtrim($select_str, ',') . " FROM il_dcl_record AS record ";
     $sql .= $join_str;
     $sql .= " WHERE record.table_id = " . $ilDB->quote($this->getId(), 'integer') . $where_additions;
     if ($has_nref) {
         $sql .= " GROUP BY record.id";
     }
     if ($id != 'comments' && $sort_field->getDatatypeId() != ilDataCollectionDatatype::INPUTFORMAT_FORMULA) {
         $sql .= " ORDER BY field_{$id} {$direction}";
     }
     $set = $ilDB->query($sql);
     $total_record_ids = array();
     // Save record-ids in session to enable prev/next links in detail view
     $_SESSION['dcl_record_ids'] = array();
     $is_allowed_to_view = ilObjDataCollectionAccess::hasWriteAccess(array_pop(ilObject::_getAllReferences($this->getObjId())));
     while ($rec = $ilDB->fetchAssoc($set)) {
         // Quick check if the current user is allowed to view the record
         if (!$is_allowed_to_view && ($this->getViewOwnRecordsPerm() && $ilUser->getId() != $rec['owner'])) {
             continue;
         }
         $total_record_ids[] = $rec['id'];
         $_SESSION['dcl_record_ids'][] = $rec['id'];
     }
     // Sort by formula
     if ($sort_field->getDatatypeId() == ilDataCollectionDatatype::INPUTFORMAT_FORMULA) {
         $sort_array = array();
         foreach ($total_record_ids as $id) {
             $formula_field = ilDataCollectionCache::getRecordFieldCache(new ilDataCollectionRecord($id), $sort_field);
             $sort_array[$id] = $formula_field->getValue();
         }
         switch ($direction) {
             case 'asc':
             case 'ASC':
                 asort($sort_array);
                 break;
             case 'desc':
             case 'DESC':
                 arsort($sort_array);
                 break;
         }
         $total_record_ids = array_keys($sort_array);
     }
     // Now slice the array to load only the needed records in memory
     $record_ids = array_slice($total_record_ids, $offset, $limit);
     $records = array();
     foreach ($record_ids as $id) {
         $records[] = ilDataCollectionCache::getRecordCache($id);
     }
     return array('records' => $records, 'total' => count($total_record_ids));
 }
 /**
  * save
  *
  * @param string $a_mode values: create | edit
  */
 public function save($a_mode = "create")
 {
     global $ilTabs;
     if (!ilObjDataCollectionAccess::checkActionForObjId('write', $this->obj_id)) {
         $this->accessDenied();
         return;
     }
     $ilTabs->activateTab("id_fields");
     $this->initForm($a_mode);
     if ($this->checkInput($a_mode)) {
         if ($a_mode != "update") {
             $this->table = ilDataCollectionCache::getTableCache();
         } elseif ($this->table_id) {
             $this->table = ilDataCollectionCache::getTableCache($this->table_id);
         } else {
             $this->ctrl->redirectByClass("ildatacollectionfieldeditgui", "listFields");
         }
         $this->table->setTitle($this->form->getInput("title"));
         $this->table->setObjId($this->obj_id);
         $this->table->setIsVisible($this->form->getInput("is_visible"));
         $this->table->setAddPerm($this->form->getInput("add_perm"));
         $this->table->setEditPerm($this->form->getInput("edit_perm"));
         $this->table->setDeletePerm($this->form->getInput("delete_perm"));
         $this->table->setEditByOwner($this->form->getInput("edit_by_owner"));
         $this->table->setViewOwnRecordsPerm($this->form->getInput('view_own_records_perm'));
         $this->table->setExportEnabled($this->form->getInput("export_enabled"));
         $this->table->setDefaultSortField($this->form->getInput("default_sort_field"));
         $this->table->setDefaultSortFieldOrder($this->form->getInput("default_sort_field_order"));
         $this->table->setPublicCommentsEnabled($this->form->getInput('public_comments'));
         $this->table->setLimited($this->form->getInput("limited"));
         $this->table->setDescription($this->form->getInput('description'));
         $limit_start = $this->form->getInput("limit_start");
         $limit_end = $this->form->getInput("limit_end");
         $this->table->setLimitStart($limit_start["date"] . " " . $limit_start["time"]);
         $this->table->setLimitEnd($limit_end["date"] . " " . $limit_end["time"]);
         if (!$this->table->hasPermissionToAddTable($this->parent_object->ref_id)) {
             $this->accessDenied();
             return;
         }
         if ($a_mode == "update") {
             $this->table->doUpdate();
             ilUtil::sendSuccess($this->lng->txt("dcl_msg_table_edited"), true);
             $this->ctrl->redirectByClass("ildatacollectiontableeditgui", "edit");
         } else {
             $this->table->doCreate();
             ilUtil::sendSuccess($this->lng->txt("dcl_msg_table_created"), true);
             $this->ctrl->setParameterByClass("ildatacollectionfieldlistgui", "table_id", $this->table->getId());
             $this->ctrl->redirectByClass("ildatacollectionfieldlistgui", "listFields");
         }
     } else {
         $this->form->setValuesByPost();
         $this->tpl->setContent($this->form->getHTML());
     }
 }