1 <?php
  2 
  3 /**
  4  * MetaForm Addon.
  5  *
  6  * @author markus[dot]staab[at]redaxo[dot]de Markus Staab
  7  *
  8  * @package redaxo\metainfo
  9  */
 10 
 11 /**
 12  * Fügt einen neuen Feldtyp ein.
 13  *
 14  * Gibt beim Erfolg die Id des Feldes zurück, bei Fehler die Fehlermeldung
 15  */
 16 function rex_metainfo_add_field_type($label, $dbtype, $dblength)
 17 {
 18     if (!is_string($label) || empty($label)) {
 19         return rex_i18n::msg('minfo_field_error_invalid_name');
 20     }
 21 
 22     if (!is_string($dbtype) || empty($dbtype)) {
 23         return rex_i18n::msg('minfo_field_error_invalid_type');
 24     }
 25 
 26     if (!is_int($dblength) || empty($dblength)) {
 27         return rex_i18n::msg('minfo_field_error_invalid_length');
 28     }
 29 
 30     $qry = 'SELECT * FROM ' . rex::getTablePrefix() . 'metainfo_type WHERE label=:label LIMIT 1';
 31     $sql = rex_sql::factory();
 32     $sql->setQuery($qry, [':label' => $label]);
 33     if ($sql->getRows() != 0) {
 34         return rex_i18n::msg('minfo_field_error_unique_type');
 35     }
 36 
 37     $sql->setTable(rex::getTablePrefix() . 'metainfo_type');
 38     $sql->setValue('label', $label);
 39     $sql->setValue('dbtype', $dbtype);
 40     $sql->setValue('dblength', $dblength);
 41 
 42     $sql->insert();
 43     return $sql->getLastId();
 44 }
 45 
 46 /**
 47  * Löscht einen Feldtyp.
 48  *
 49  * Gibt beim Erfolg true zurück, sonst eine Fehlermeldung
 50  */
 51 function rex_metainfo_delete_field_type($field_type_id)
 52 {
 53     if (!is_int($field_type_id) || empty($field_type_id)) {
 54         return rex_i18n::msg('minfo_field_error_invalid_typeid');
 55     }
 56 
 57     $sql = rex_sql::factory();
 58     $sql->setTable(rex::getTablePrefix() . 'metainfo_type');
 59     $sql->setWhere(['id' => $field_type_id]);
 60 
 61     $sql->delete();
 62     return $sql->getRows() == 1;
 63 }
 64 
 65 /**
 66  * Fügt ein MetaFeld hinzu und legt dafür eine Spalte in der MetaTable an.
 67  */
 68 function rex_metainfo_add_field($title, $name, $priority, $attributes, $type, $default, $params = null, $validate = null, $restrictions = '', $callback = null)
 69 {
 70     $prefix = rex_metainfo_meta_prefix($name);
 71     $metaTable = rex_metainfo_meta_table($prefix);
 72 
 73     // Prefix korrekt?
 74     if (!$metaTable) {
 75         return rex_i18n::msg('minfo_field_error_invalid_prefix');
 76     }
 77 
 78     // TypeId korrekt?
 79     $qry = 'SELECT * FROM ' . rex::getTablePrefix() . 'metainfo_type WHERE id=' . $type . ' LIMIT 2';
 80     $sql = rex_sql::factory();
 81     $typeInfos = $sql->getArray($qry);
 82 
 83     if ($sql->getRows() != 1) {
 84         return rex_i18n::msg('minfo_field_error_invalid_type');
 85     }
 86 
 87     $fieldDbType = $typeInfos[0]['dbtype'];
 88     $fieldDbLength = $typeInfos[0]['dblength'];
 89 
 90     // Spalte existiert schon?
 91     $sql->setQuery('SELECT * FROM ' . $metaTable . ' LIMIT 1');
 92     if (in_array($name, $sql->getFieldnames())) {
 93         return rex_i18n::msg('minfo_field_error_unique_name');
 94     }
 95 
 96     // Spalte extiert laut metainfo_field?
 97     $qry = 'SELECT * FROM ' . rex::getTablePrefix() . 'metainfo_field WHERE name=:name LIMIT 1';
 98     $sql = rex_sql::factory();
 99     $sql->setQuery($qry, [':name' => $name]);
100     if ($sql->getRows() != 0) {
101         return rex_i18n::msg('minfo_field_error_unique_name');
102     }
103 
104     $sql->setTable(rex::getTablePrefix() . 'metainfo_field');
105     $sql->setValue('title', $title);
106     $sql->setValue('name', $name);
107     $sql->setValue('priority', $priority);
108     $sql->setValue('attributes', $attributes);
109     $sql->setValue('type_id', $type);
110     $sql->setValue('default', $default);
111     $sql->setValue('params', $params);
112     $sql->setValue('validate', $validate);
113     $sql->setValue('restrictions', $restrictions);
114     $sql->setValue('callback', $callback);
115     $sql->addGlobalUpdateFields();
116     $sql->addGlobalCreateFields();
117 
118     $sql->insert();
119 
120     // replace LIKE wildcards
121     $prefix = str_replace(['_', '%'], ['\_', '\%'], $prefix);
122 
123     rex_sql_util::organizePriorities(rex::getTablePrefix() . 'metainfo_field', 'priority', 'name LIKE "' . $prefix . '%"', 'priority, updatedate');
124 
125     $tableManager = new rex_metainfo_table_manager($metaTable);
126     return $tableManager->addColumn($name, $fieldDbType, $fieldDbLength, $default);
127 }
128 
129 function rex_metainfo_delete_field($fieldIdOrName)
130 {
131     // Löschen anhand der FieldId
132     if (is_int($fieldIdOrName)) {
133         $fieldQry = 'SELECT * FROM ' . rex::getTablePrefix() . 'metainfo_field WHERE id=:idOrName LIMIT 2';
134         $invalidField = rex_i18n::msg('minfo_field_error_invalid_fieldid');
135     }
136     // Löschen anhand des Feldnames
137     elseif (is_string($fieldIdOrName)) {
138         $fieldQry = 'SELECT * FROM ' . rex::getTablePrefix() . 'metainfo_field WHERE name=:idOrName LIMIT 2';
139         $invalidField = rex_i18n::msg('minfo_field_error_invalid_name');
140     } else {
141         throw new InvalidArgumentException('MetaInfos: Unexpected type for $fieldIdOrName!');
142     }
143     // Feld existiert?
144     $sql = rex_sql::factory();
145     $sql->setQuery($fieldQry, [':idOrName' => $fieldIdOrName]);
146 
147     if ($sql->getRows() != 1) {
148         return $invalidField;
149     }
150 
151     $name = $sql->getValue('name');
152     $field_id = $sql->getValue('id');
153 
154     $prefix = rex_metainfo_meta_prefix($name);
155     $metaTable = rex_metainfo_meta_table($prefix);
156 
157     // Spalte existiert?
158     $sql->setQuery('SELECT * FROM ' . $metaTable . ' LIMIT 1');
159     if (!in_array($name, $sql->getFieldnames())) {
160         return rex_i18n::msg('minfo_field_error_invalid_name');
161     }
162 
163     $sql->setTable(rex::getTablePrefix() . 'metainfo_field');
164     $sql->setWhere(['id' => $field_id]);
165 
166     $sql->delete();
167 
168     $tableManager = new rex_metainfo_table_manager($metaTable);
169     return $tableManager->deleteColumn($name);
170 }
171 
172 /**
173  * Extrahiert den Prefix aus dem Namen eine Spalte.
174  */
175 function rex_metainfo_meta_prefix($name)
176 {
177     if (!is_string($name)) {
178         return false;
179     }
180 
181     if (($pos = strpos($name, '_')) !== false) {
182         return substr(strtolower($name), 0, $pos + 1);
183     }
184 
185     return false;
186 }
187 
188 /**
189  * Gibt die mit dem Prefix verbundenen Tabellennamen zurück.
190  */
191 function rex_metainfo_meta_table($prefix)
192 {
193     $metaTables = rex_addon::get('metainfo')->getProperty('metaTables', []);
194 
195     if (isset($metaTables[$prefix])) {
196         return $metaTables[$prefix];
197     }
198 
199     return false;
200 }
201 
202 /**
203  * Bindet ggf extensions ein.
204  *
205  * @param rex_extension_point $ep
206  */
207 function rex_metainfo_extensions_handler(rex_extension_point $ep)
208 {
209     $page = $ep->getSubject();
210     $mainpage = rex_be_controller::getCurrentPagePart(1);
211     $mypage = 'metainfo';
212 
213     // additional javascripts
214     if ($mainpage == 'metainfo' || $page == 'content/metainfo' || $page == 'structure' || $page == 'system/lang') {
215         rex_view::addJsFile(rex_url::addonAssets($mypage, 'metainfo.js'));
216     }
217 
218     // include extensions
219     $curDir = __DIR__ . '/..';
220     if ($page == 'structure') {
221         require_once $curDir . '/lib/handler/category_handler.php';
222     } elseif ($mainpage == 'mediapool') {
223         require_once $curDir . '/lib/handler/media_handler.php';
224     } elseif ($page == 'system/lang') {
225         require_once $curDir . '/lib/handler/clang_handler.php';
226     } elseif ($mainpage == 'content') {
227         require_once $curDir . '/extensions/extension_content_sidebar.php';
228     } elseif ($page == 'backup') {
229         require_once $curDir . '/extensions/extension_cleanup.php';
230     }
231 }
232