aboutsummaryrefslogtreecommitdiff
path: root/lib/models/MvvFile.php
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:07:19 +0200
committerJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:19:12 +0200
commita3da1483a9e689846179159355badfec8073dbec (patch)
tree770dcca6bdf5f6f2a11b0e7fcbbeda6919a3fc52 /lib/models/MvvFile.php
current code from svn, revision 62608
Diffstat (limited to 'lib/models/MvvFile.php')
-rw-r--r--lib/models/MvvFile.php482
1 files changed, 482 insertions, 0 deletions
diff --git a/lib/models/MvvFile.php b/lib/models/MvvFile.php
new file mode 100644
index 0000000..b508b9a
--- /dev/null
+++ b/lib/models/MvvFile.php
@@ -0,0 +1,482 @@
+<?php
+/**
+ * MvvFile.php
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author Timo Hartge <hartge@data-quest.de>
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category Stud.IP
+ * @since 4.5
+ */
+
+class MvvFile extends ModuleManagementModel
+{
+ /**
+ * @param array $config
+ */
+ protected static function configure($config = [])
+ {
+ $config['db_table'] = 'mvv_files';
+
+ $config['has_many']['file_refs'] = [
+ 'class_name' => MvvFileFileref::class,
+ 'foreign_key' => 'mvvfile_id'
+ ];
+ $config['has_many']['ranges'] = [
+ 'class_name' => MvvFileRange::class,
+ 'foreign_key' => 'mvvfile_id'
+ ];
+ $config['additional_fields']['count_relations']['get'] = 'countRelations';
+
+ parent::configure($config);
+ }
+
+ /**
+ * Finds all documents related to the given object.
+ *
+ * @param string $object A MVV object
+ * @return array Array of documents.
+ */
+ public static function findByObject(SimpleORMap $object)
+ {
+ $condition = self::getFilterSql(['mdz.range_type' => get_class($object)]);
+ $query = "SELECT md.*, mdz.position, mdz.mkdate, mdz.chdate
+ FROM mvv_files md
+ INNER JOIN mvv_files_ranges mdz USING(mvvfile_id)
+ WHERE mdz.range_id = ? {$condition}
+ ORDER BY mdz.position";
+ return parent::getEnrichedByQuery($query, [$object->id]);
+ }
+
+ public static function findByRange_id($range_id)
+ {
+ return self::findBySQL('JOIN mvv_files_ranges USING (mvvfile_id) WHERE range_id =? ORDER BY position ASC', [$range_id]);
+ }
+
+ /**
+ * Returns the name of the object to display in a specific context..
+ *
+ * @return string The name for
+ */
+ public function getDisplayName($options = null)
+ {
+ if ($this->file_refs) {
+ return $this->file_refs[0]->name;
+ }
+ return '';
+ }
+
+ /**
+ * Returns the name of the rangetype this mvvfile is bound to.
+ *
+ * @return string type of range
+ */
+ public function getRangeType()
+ {
+ if ($this->ranges) {
+ return $this->ranges[0]->range_type;
+ }
+ return '';
+ }
+
+ /**
+ * Returns the number of assignments to other MVV objects.
+ *
+ * @return int Number of assignments.
+ */
+ public function countRelations()
+ {
+ return MvvFileRange::countBySql('mvvfile_id = ?', [$this->mvvfile_id]);
+ }
+
+ /**
+ * Returns the position in given range.
+ *
+ * @return int position.
+ */
+ public function getPositionInRange($range_id)
+ {
+ return MvvFileRange::find([$this->mvvfile_id, $range_id])->position;
+ }
+
+ /**
+ * Returns the ids of related ranges.
+ *
+ * @return array Ids of related ranges.
+ */
+ public function getRangesArray()
+ {
+ return MvvFileRange::findAndMapBySQL(
+ function ($range) {
+ return $range->range_id;
+ },
+ 'mvvfile_id = ?',
+ [$this->mvvfile_id]
+ );
+ }
+
+ /**
+ * Returns the filenames of related filerefs.
+ *
+ * @return string available filenames.
+ */
+ public function getFilenames()
+ {
+ return MvvFileFileref::findAndMapBySQL(
+ function ($ref) {
+ return $ref->getFilename();
+ },
+ 'mvvfile_id = ?',
+ [$this->mvvfile_id]
+ );
+ }
+
+ /**
+ * Returns the filetypes of related filerefs.
+ *
+ * @return string available filetypes.
+ */
+ public function getFiletypes()
+ {
+ return MvvFileFileref::findAndMapBySQL(
+ function ($ref) {
+ return $ref->getFileType();
+ },
+ 'mvvfile_id = ?',
+ [$this->mvvfile_id]
+ );
+ }
+
+
+ /**
+ * Returns all or a specified (by row count and offset) number of
+ * documents sorted and filtered by given parameters and enriched with
+ * some additional fields. This function is mainly used in the list view.
+ *
+ * @param string $sortby Field name to order by.
+ * @param string $order ASC or DESC direction of order.
+ * @param array $filter Key-value pairs of filed names and values
+ * to filter the result set.
+ * @param int $row_count The max number of objects to return.
+ * @param int $offset The first object to return in a result set.
+ * @return object A SimpleORMapCollection of Dokument objects.
+ */
+ public static function getAllEnriched($sortby = 'chdate', $order = 'DESC',
+ $row_count = null, $offset = null, $filter = null)
+ {
+ $sortby = self::createSortStatement(
+ $sortby,
+ $order,
+ 'mvvfile_id',
+ ['count_zuordnungen', 'mvv_files_filerefs.name', 'file_refs.name']
+ );
+
+ $parameters = [
+ ':ranges' => self::getIdsFiltered($filter),
+ ];
+
+ $name_filter_sql = '';
+ if ($filter['searchnames']) {
+ $name_filter_sql = " AND CONCAT_WS(' ', `file_refs`.`name`, `mvv_files_filerefs`.`name`, `mvv_files`.`category`,`mvv_files`.`tags`) LIKE :needle";
+ $parameters[':needle'] = "%{$filter['searchnames']}%";
+ }
+ unset($filter['searchnames']);
+
+ $query = "SELECT `mvv_files`.*,
+ COUNT(`mvv_files_ranges`.`range_id`) AS `count_relations`,
+ `file_refs`.`name` AS `filename`,
+ `mvv_files_ranges`.`range_type` AS `range_type`
+ FROM `mvv_files`
+ LEFT JOIN `mvv_files_ranges` USING (`mvvfile_id`)
+ LEFT JOIN `mvv_files_filerefs` USING (`mvvfile_id`)
+ INNER JOIN `file_refs` ON (`fileref_id` = `file_refs`.`id`)
+ INNER JOIN `folders` ON (file_refs.folder_id = folders.id)
+ WHERE `mvv_files_ranges`.`range_id` IN (:ranges) {$name_filter_sql}
+ GROUP BY `mvvfile_id`
+ ORDER BY {$sortby}";
+ return parent::getEnrichedByQuery($query, $parameters, $row_count, $offset);
+ }
+
+ /**
+ * Returns all relations of the documents specified by the given ids.
+ * The returned array is ordered by the types of the referenced objects.
+ *
+ * @param array $dokument_ids Ids of the documents.
+ * @return array References ordered by object types.
+ */
+ public static function getAllRelations($dokument_ids = [])
+ {
+ $files = [];
+ if ($dokument_ids) {
+ foreach ($dokument_ids as $dokument_id) {
+ foreach (self::findBySQL('mvvfile_id = ?', [$dokument_id]) as $mvv_file) {
+ $files[] = $mvv_file;
+ }
+ }
+ } else {
+ $files = self::findBySQL('1');
+ }
+ $zuordnungen = [];
+ foreach ($files as $file) {
+ foreach ($file->ranges as $file_range) {
+ $zuordnungen[$file_range['range_type']][$file_range['range_id']] = $file;
+ }
+ }
+ return $zuordnungen;
+ }
+
+ /**
+ * Returns all relations of this document grouped by object types.
+ *
+ * @return Array Relations ordered by object types
+ */
+ public function getRelations()
+ {
+ $zuordnungen = [];
+ foreach (MvvFileRange::findBySQL('mvvfile_id =?', [$this->mvvfile_id]) as $range) {
+ $zuordnungen[$range['range_type']][$range['range_id']] = $range;
+ }
+ return $zuordnungen;
+ }
+
+ /**
+ * Find Documents by given search term.
+ * Used as search function in list view.
+ *
+ * @param type $term The search term.
+ * @param type $filter Optional filter parameters.
+ * @return array An array of Dokument ids.
+ */
+ public static function findBySearchTerm($term, $filter = null)
+ {
+ $sql = "LEFT JOIN mvv_files_ranges USING (mvvfile_id)
+ LEFT JOIN mvv_files_filerefs USING (mvvfile_id)
+ LEFT JOIN file_refs ON (fileref_id = file_refs.id)
+ LEFT JOIN folders ON (file_refs.folder_id = folders.id)
+ WHERE (mvv_files_filerefs.name LIKE CONCAT('%', :term, '%') OR file_refs.name LIKE CONCAT('%', :term, '%')) GROUP BY mvvfile_id";
+ $params['term'] = $term;
+
+ /* if ($filter) {
+ foreach ($filter as $column => $val) {
+ if ($column == null || $val == null) {
+ continue;
+ }
+ if (is_array($val)) {
+ $sql .= ' AND '. $column . ' IN('
+ . join(',', array_map(
+ function ($val) {
+ return DBManager::get()->quote($val);
+ }, $val))
+ . ') ';
+ } else {
+ $sql .= ' AND '.$column.' = ? ';
+ //$params[] = $column;
+ $params[] = $val;
+ }
+ }
+ } */
+
+ return SimpleORMapCollection::createFromArray(self::findBySQL($sql, $params));
+ }
+
+
+
+ /**
+ * Returns the number of Documents comply with the given filter parameters.
+ *
+ * @param array $filter Array of filter parameters
+ * @see ModuleManagementModel::getFilterSql()
+ * @return int The number of Documents.
+ */
+ public static function getCount($filter = null)
+ {
+ if (empty($filter)) {
+ return parent::getCount();
+ }
+ $searchnames = $filter['searchnames'];
+ $name_filter_sql = '';
+ if ($searchnames) {
+ $name_filter_sql = " AND CONCAT_WS(' ', `file_refs`.`name`, `mvv_files_filerefs`.`name`, `mvv_files`.`category`,`mvv_files`.`tags`) LIKE ". DBManager::get()->quote('%' . $searchnames . '%');
+ }
+ unset($filter['searchnames']);
+ $ids = self::getIdsFiltered($filter);
+ return parent::getCountBySql("
+ SELECT COUNT(DISTINCT `mvv_files`.`mvvfile_id`)
+ FROM `mvv_files_ranges`
+ INNER JOIN `mvv_files` USING(`mvvfile_id`)
+ INNER JOIN `mvv_files_filerefs` USING(`mvvfile_id`)
+ INNER JOIN `file_refs` ON `fileref_id` = `file_refs`.`id`
+ WHERE `mvv_files_ranges`.`range_id` IN ('" . implode("','", $ids) . "') $name_filter_sql");
+ }
+
+ /**
+ * Returns a ready to use quick search widget.
+ *
+ * @param array $exclude Ids of documents excluded from search.
+ * @return array Array with quick search id and quick search html.
+ */
+ public static function getQuickSearch($exclude = array())
+ {
+ $query = "
+ SELECT mvv_files.mvvfile_id, mvv_files_filerefs.name
+ FROM mvv_files
+ WHERE (mvv_files_filerefs.name LIKE :input OR file_refs.name LIKE :input)
+ AND mvv_files.fileref_id NOT IN ('"
+ . implode("','", $exclude) . "')
+ ORDER BY name ASC";
+ $search = new SQLSearch($query, _('Dokument suchen'));
+ $qs_id = md5(serialize($search));
+ $qs_html = QuickSearch::get('dokumente', $search)
+ ->fireJSFunctionOnSelect('STUDIP.MVV.Search.addSelected')
+ ->noSelectbox();
+ return ['id' => $qs_id, 'html' => $qs_html];
+ }
+
+ /**
+ * Returns the highest current sorting position.
+ *
+ * @param sting $range_id Id of the mvv object.
+ * @return int Number of the highest current sorting position.
+ */
+ public static function getMaxSortingPos($range_id)
+ {
+ $ret = DBManager::get()->fetchOne("
+ SELECT MAX(`position`)
+ FROM `mvv_files_ranges`
+ JOIN mvv_files USING (`mvvfile_id`) WHERE `range_id` = ?;", [$range_id]);
+ return $ret['MAX(`position`)'];
+ }
+
+ /**
+ * Adds this mvvfile to given range.
+ *
+ * @param sting $range_id Id of the mvv object.
+ */
+ public function addToRange($range_id, $range_type)
+ {
+ $mvvfile_range = new MvvFileRange([$this->mvvfile_id, $range_id]);
+ $mvvfile_range->range_type = $range_type;
+ if ($mvvfile_range->isNew()) {
+ $mvvfile_range->position = self::getMaxSortingPos($range_id) + 1;
+ }
+ $mvvfile_range->store();
+ }
+
+ /**
+ * Removes this mvvfile from given range.
+ *
+ * @param sting $range_id Id of the mvv object.
+ */
+ public function removeFromRange($range_id)
+ {
+ if ($mvvfile_range = MvvFileRange::find([$this->mvvfile_id, $range_id])) {
+ $vacant = $mvvfile_range->position;
+ if ($mvvfile_range->delete()) {
+ foreach (MvvFileRange::findBySQL('range_id = ? ORDER BY position ASC',[$range_id]) as $other_range) {
+ if ($other_range->position > $vacant) {
+ $tmp = $other_range->position;
+ $other_range->position = $vacant;
+ $other_range->store();
+ $vacant = $tmp;
+ }
+ }
+ }
+ }
+ }
+
+ public function validate()
+ {
+ $ret = parent::validate();
+ if ($this->isDirty()) {
+ $messages = array();
+ $rejected = false;
+
+ /* if (!$this->name) {
+ $ret['name'] = true;
+ $messages[] = _('Es muss ein Anzeigename für das Dokument angegeben werden.');
+ $rejected = true;
+ } */
+
+ if ($rejected) {
+ throw new InvalidValuesException(join("\n", $messages), $ret);
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Returns all institutes assigned to files. Sorted and filtered by
+ * optional parameters.
+ *
+ * @param string $sortby DB field to sort by.
+ * @param string $order ASC or DESC
+ * @param array $filter Array of filter.
+ * @return array Array of found Fachbereiche.
+ */
+ public static function getAllAssignedInstitutes($sortby = 'name',
+ $order = 'ASC', $filter = null, $row_count = null, $offset = null)
+ {
+ $sortby = Fachbereich::createSortStatement($sortby, $order, 'name',
+ ['count_objects']);
+
+ return Fachbereich::getEnrichedByQuery("
+ SELECT `Institute`.*,
+ `Institute`.`Name` as `name`,
+ `Institute`.`Institut_id` AS `institut_id`,
+ COUNT(DISTINCT `mvv_files`.`mvvfile_id`) as `count_objects`
+ FROM `mvv_files`
+ LEFT JOIN `mvv_files_ranges` USING(`mvvfile_id`)
+ LEFT JOIN `mvv_abschl_zuord` ON (`mvv_abschl_zuord`.`kategorie_id` = `mvv_files_ranges`.`range_id`)
+ INNER JOIN `abschluss` USING(`abschluss_id`)
+ LEFT JOIN `mvv_studiengang` ON (`mvv_studiengang`.`abschluss_id` = `abschluss`.`abschluss_id`
+ OR `mvv_studiengang`.`studiengang_id` = `mvv_files_ranges`.`range_id`)
+ INNER JOIN `Institute` USING(`institut_id`)
+ LEFT JOIN `semester_data` `start_sem`
+ ON (`mvv_studiengang`.`start` = `start_sem`.`semester_id`)
+ LEFT JOIN `semester_data` `end_sem`
+ ON (`mvv_studiengang`.`end` = `end_sem`.`semester_id`)"
+ . Fachbereich::getFilterSql($filter, true) . "
+ GROUP BY `institut_id` ORDER BY " . $sortby, [], $row_count, $offset
+ );
+ }
+
+ /**
+ * Returns range_ids (ids of Studiengang/Abschluss-Kategorie) of assigned files.
+ *
+ * @staticvar array $ids The range_ids of assigned files after filtration.
+ * @param array $filter An array with keys (table_name.column_name) and
+ * values (skalar or array) used in where clause.
+ * @param boolean $refresh Refresh ids if true.
+ * @return array An array with range_ids of assigned files.
+ */
+ public static function getIdsFiltered($filter, $refresh = false)
+ {
+ static $ids = null;
+
+ if (is_array($ids) && !$refresh) {
+ return $ids;
+ }
+
+ $sql = "SELECT DISTINCT `mvv_files_ranges`.`range_id`
+ FROM `mvv_files`
+ LEFT JOIN `mvv_files_ranges` USING (`mvvfile_id`)
+ LEFT JOIN `mvv_abschl_zuord` ON (`mvv_abschl_zuord`.`kategorie_id` = `mvv_files_ranges`.`range_id`)
+ LEFT JOIN `abschluss` USING(`abschluss_id`)
+ LEFT JOIN `mvv_studiengang` ON (`mvv_studiengang`.`abschluss_id` = `abschluss`.`abschluss_id`
+ OR `mvv_studiengang`.`studiengang_id` = `mvv_files_ranges`.`range_id`)
+ LEFT JOIN `semester_data` `start_sem`
+ ON (`mvv_studiengang`.`start` = `start_sem`.`semester_id`)
+ LEFT JOIN `semester_data` `end_sem`
+ ON (`mvv_studiengang`.`end` = `end_sem`.`semester_id`)"
+ . self::getFilterSql($filter, true);
+
+ $stm = DBManager::get()->prepare($sql);
+ $stm->execute();
+ return $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+ }
+
+}