| Commit | Line | Data |
|---|---|---|
| 4dabd52f | 1 | <?php |
| 4dabd52f KS |
2 | |
| 3 | /** | |
| 4 | * @file | |
| 5 | * Create/Read/Update/Delete functions for CCK-defined object types. | |
| 6 | */ | |
| 7 | ||
| 8 | /** | |
| a106b662 KS |
9 | * Expand field info to create field => widget info. |
| 10 | */ | |
| 11 | function content_field_instance_expand($field) { | |
| 12 | if (isset($field['widget'])) { | |
| 13 | return $field; | |
| 14 | } | |
| 15 | $field['widget'] = !empty($field['widget_settings']) ? $field['widget_settings'] : array(); | |
| 16 | $field['widget']['label'] = !empty($field['label']) ? $field['label'] : $field['field_name']; | |
| c3809c98 | 17 | $field['widget']['weight'] = !empty($field['weight']) ? $field['weight'] : 0; |
| a106b662 KS |
18 | $field['widget']['description'] = !empty($field['description']) ? $field['description'] : ''; |
| 19 | ||
| 20 | if (!empty($field['widget_type'])) { | |
| 21 | $field['widget']['type'] = $field['widget_type']; | |
| 22 | $widget_types = _content_widget_types(); | |
| 23 | $field['widget']['module'] = isset($widget_types[$field['widget_type']]['module']) ? $widget_types[$field['widget_type']]['module'] : $field['widget_module']; | |
| 24 | } | |
| 25 | elseif (!empty($field['widget_module'])) { | |
| 26 | $field['widget']['module'] = $field['widget_module']; | |
| 27 | } | |
| 28 | ||
| 29 | unset($field['widget_type']); | |
| 30 | unset($field['weight']); | |
| 31 | unset($field['label']); | |
| 32 | unset($field['description']); | |
| 33 | unset($field['widget_module']); | |
| 34 | unset($field['widget_settings']); | |
| 35 | ||
| 36 | // If content.module is handling the default value, | |
| 37 | // initialize $widget_settings with default values, | |
| 38 | if (isset($field['default_value']) && isset($field['default_value_php']) && | |
| 39 | content_callback('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) { | |
| 40 | $field['widget']['default_value'] = !empty($field['default_value']) ? $field['default_value'] : NULL; | |
| 41 | $field['widget']['default_value_php'] = !empty($field['default_value_php']) ? $field['default_value_php'] : NULL; | |
| 42 | unset($field['default_value']); | |
| 43 | unset($field['default_value_php']); | |
| 44 | } | |
| 45 | return $field; | |
| 46 | } | |
| 47 | ||
| 48 | /** | |
| 49 | * Collapse field info from field => widget to flattened form values. | |
| 50 | */ | |
| 51 | function content_field_instance_collapse($field) { | |
| 52 | if (!isset($field['widget'])) { | |
| 53 | return $field; | |
| 54 | } | |
| 55 | $field['widget_settings'] = !empty($field['widget']) ? $field['widget'] : array(); | |
| 56 | $field['widget_type'] = !empty($field['widget']['type']) ? $field['widget']['type'] : ''; | |
| 57 | $field['weight'] = !empty($field['widget']['weight']) ? $field['widget']['weight'] : 0; | |
| 58 | $field['label'] = !empty($field['widget']['label']) ? $field['widget']['label'] : $field['field_name']; | |
| 59 | $field['description'] = !empty($field['widget']['description']) ? $field['widget']['description'] : ''; | |
| 60 | $field['type_name'] = !empty($field['type_name']) ? $field['type_name'] : ''; | |
| 61 | ||
| 62 | if (!empty($field['widget']['module'])) { | |
| 63 | $widget_module = $field['widget']['module']; | |
| 64 | } | |
| 65 | elseif (!empty($field['widget']['type'])) { | |
| 66 | $widget_types = _content_widget_types(); | |
| 67 | $widget_module = $widget_types[$field['widget']['type']]['module']; | |
| 68 | } | |
| 69 | else { | |
| 70 | $widget_module = ''; | |
| 71 | } | |
| 72 | $field['widget_module'] = $widget_module; | |
| 73 | unset($field['widget_settings']['type']); | |
| 74 | unset($field['widget_settings']['weight']); | |
| 75 | unset($field['widget_settings']['label']); | |
| 76 | unset($field['widget_settings']['description']); | |
| 77 | unset($field['widget_settings']['module']); | |
| 78 | unset($field['widget']); | |
| 79 | return $field; | |
| 80 | } | |
| 81 | ||
| 82 | /** | |
| 740bb756 YC |
83 | * Rebuild content type information from node tables. |
| 84 | * | |
| 240a4b43 KS |
85 | * Used to update CCK tables that might have missed changes made when CCK was disabled. |
| 86 | * Called by hook_form_alter() on system modules page whenever CCK is enabled. | |
| 4dabd52f | 87 | */ |
| 240a4b43 KS |
88 | function content_types_rebuild() { |
| 89 | $db_types = content_types(); | |
| 740bb756 | 90 | |
| 240a4b43 KS |
91 | $result = db_query("SELECT type_name FROM {node_field_instance}"); |
| 92 | while ($type = db_fetch_array($result)) { | |
| 93 | $field_types[] = $type['type_name']; | |
| 94 | } | |
| 4dabd52f | 95 | |
| 240a4b43 | 96 | foreach ($db_types as $content_type) { |
| 33d63a0a | 97 | // Find content types that are missing the content table and add it |
| d658947d | 98 | content_type_create((object)array('type' => $content_type['type'])); |
| 240a4b43 KS |
99 | } |
| 100 | content_clear_type_cache(); | |
| 4dabd52f KS |
101 | } |
| 102 | ||
| 103 | /** | |
| 240a4b43 | 104 | * Make changes needed when a content type is created. |
| 4dabd52f | 105 | * |
| 3920e7fb | 106 | * @param $info |
| 4dabd52f | 107 | * value supplied by hook_node_type() |
| 4dabd52f | 108 | */ |
| 240a4b43 | 109 | function content_type_create($info) { |
| 33d63a0a YC |
110 | content_clear_type_cache(); |
| 111 | $type = content_types($info->type); | |
| bf3ca8a9 | 112 | $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); |
| d658947d | 113 | if (!db_table_exists($table)) { |
| 240a4b43 KS |
114 | switch ($GLOBALS['db_type']) { |
| 115 | case 'mysql': | |
| 116 | case 'mysqli': | |
| d658947d | 117 | db_query("CREATE TABLE {". $table ."} ( |
| 240a4b43 KS |
118 | vid int unsigned NOT NULL default '0', |
| 119 | nid int unsigned NOT NULL default '0', | |
| 06828f7c YC |
120 | PRIMARY KEY (vid), |
| 121 | KEY nid (nid) | |
| c8943474 | 122 | ) /*!40100 DEFAULT CHARACTER SET utf8 */"); |
| 240a4b43 KS |
123 | break; |
| 124 | ||
| 125 | case 'pgsql': | |
| d658947d | 126 | db_query("CREATE TABLE {". $table ."} ( |
| 5688cacb KS |
127 | vid int_unsigned NOT NULL default '0', |
| 128 | nid int_unsigned NOT NULL default '0', | |
| 240a4b43 KS |
129 | PRIMARY KEY (vid) |
| 130 | )"); | |
| 06828f7c | 131 | db_query("CREATE INDEX {". $table ."}_nid_idx ON {". $table ."}(nid)"); |
| 240a4b43 KS |
132 | break; |
| 133 | } | |
| d658947d | 134 | drupal_set_message(t('The content fields table %name has been created.', array('%name' => $table))); |
| 240a4b43 | 135 | } |
| 4dabd52f KS |
136 | } |
| 137 | ||
| 138 | /** | |
| 139 | * Make changes needed when an existing content type is updated. | |
| 140 | * | |
| 3920e7fb | 141 | * @param $info |
| 4dabd52f | 142 | * value supplied by hook_node_type() |
| 4dabd52f KS |
143 | */ |
| 144 | function content_type_update($info) { | |
| 240a4b43 KS |
145 | if (!empty($info->old_type) && $info->old_type != $info->type) { |
| 146 | // rename the content type in all fields that use changed content type. | |
| 77f9b7e9 | 147 | db_query("UPDATE {node_field_instance} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type)); |
| 240a4b43 KS |
148 | |
| 149 | // Rename the content fields table to match new content type name. | |
| 33d63a0a | 150 | $old_type = content_types($info->old_type); |
| bf3ca8a9 | 151 | $old_name = _content_tablename($old_type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); |
| d658947d | 152 | $new_name = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE); |
| 33d63a0a YC |
153 | if (db_table_exists($old_name)) { |
| 154 | switch ($GLOBALS['db_type']) { | |
| 155 | case 'mysql': | |
| 156 | case 'mysqli': | |
| 38830b9b | 157 | db_query("RENAME TABLE {". $old_name ."} TO {". $new_name ."}"); |
| 33d63a0a YC |
158 | break; |
| 159 | ||
| 160 | case 'pgsql': | |
| 38830b9b | 161 | db_query("ALTER TABLE {". $old_name ."} RENAME TO {". $new_name ."}"); |
| 33d63a0a YC |
162 | break; |
| 163 | } | |
| 164 | drupal_set_message(t('Content fields table %old_name has been renamed to %new_name and field instances have been updated.', array('%old_name' => $old_name, '%new_name' => $new_name))); | |
| 240a4b43 | 165 | } |
| 4dabd52f | 166 | } |
| f5383df5 | 167 | // reset all content type info. |
| 4dabd52f | 168 | content_clear_type_cache(); |
| 4dabd52f KS |
169 | } |
| 170 | ||
| 171 | /** | |
| 172 | * Make changes needed when a content type is deleted. | |
| 173 | * | |
| 3920e7fb | 174 | * @param $info |
| 4dabd52f | 175 | * value supplied by hook_node_type() |
| 4dabd52f KS |
176 | */ |
| 177 | function content_type_delete($info) { | |
| f5383df5 YC |
178 | // Don't delete data for content-type defined by disabled modules. |
| 179 | if (!empty($info->disabled)) { | |
| 180 | return; | |
| 181 | } | |
| 182 | ||
| 33d63a0a | 183 | $type = content_types($info->type); |
| 740bb756 | 184 | |
| 33d63a0a YC |
185 | foreach ($type['fields'] as $field) { |
| 186 | content_field_instance_delete(array('type_name' => $info->type, 'field_name' => $field['field_name'])); | |
| 4dabd52f | 187 | } |
| bf3ca8a9 | 188 | $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE); |
| d658947d YC |
189 | if (db_table_exists($table)) { |
| 190 | db_query('DROP TABLE {'. $table .'}'); | |
| 191 | drupal_set_message(t('The content fields table %name has been deleted.', array('%name' => $table))); | |
| ff51a722 | 192 | } |
| 4dabd52f | 193 | |
| f5383df5 | 194 | // Reset all content type info. |
| 4dabd52f | 195 | content_clear_type_cache(); |
| 4dabd52f KS |
196 | } |
| 197 | ||
| 198 | ||
| 199 | /** | |
| 200 | * Create a new field. | |
| 201 | * | |
| 202 | * Any call to this function *must* be immediately followed by a call to | |
| 203 | * content_field_instance_create(), or the database could be left in an | |
| 204 | * inconsistent state. | |
| 205 | * | |
| 206 | * @param $properties | |
| 207 | * An array of properties to load the field with. Valid keys: | |
| 3920e7fb | 208 | * - '' - |
| 4dabd52f KS |
209 | * @return |
| 210 | * The ID of the newly-created field. | |
| 211 | */ | |
| 212 | function content_field_create($properties) { | |
| 213 | // TODO | |
| 214 | } | |
| 215 | ||
| 216 | /** | |
| 217 | * Load a field. | |
| 218 | * | |
| 219 | * @param $properties | |
| 220 | * An array of properties to use in selecting a field. Valid keys: | |
| 3920e7fb | 221 | * - '' - |
| 4dabd52f KS |
222 | * @return |
| 223 | * The field array. | |
| 224 | */ | |
| 225 | function content_field_read($properties) { | |
| 226 | // TODO | |
| 227 | } | |
| 228 | ||
| 229 | /** | |
| 230 | * Update an existing field. | |
| 231 | * | |
| 232 | * @param $properties | |
| 233 | * An array of properties to set in the field. Valid keys: | |
| 3920e7fb | 234 | * - '' - |
| 4dabd52f KS |
235 | * @return |
| 236 | * The number of fields updated. | |
| 237 | */ | |
| 238 | function content_field_update($properties) { | |
| 239 | // TODO | |
| 240 | } | |
| 241 | ||
| 242 | /** | |
| 243 | * Delete an existing field. | |
| 244 | * | |
| 245 | * @param $properties | |
| 246 | * An array of properties to use in selecting a field. Valid keys: | |
| 247 | * - 'field_name' - The name of the field to be deleted. | |
| 248 | * @return | |
| 249 | * The number of fields deleted. | |
| 250 | */ | |
| 251 | function content_field_delete($properties) { | |
| 252 | $result = db_query("SELECT type_name FROM {node_field_instance} WHERE field_name = '%s'", $properties['field_name']); | |
| 253 | $type_names = array(); | |
| 254 | while ($type = db_fetch_array($result)) { | |
| 255 | $type_names[] = $type['type_name']; | |
| 256 | } | |
| 257 | foreach ($type_names as $type_name) { | |
| 258 | content_field_instance_delete(array('type_name' => $type_name, 'field_name' => $properties['field_name'])); | |
| 259 | } | |
| 260 | return (count($type_names) ? 1 : 0); | |
| 261 | } | |
| 262 | ||
| 263 | ||
| 264 | /** | |
| 265 | * Create a new field instance. | |
| 266 | * | |
| 267 | * @param $properties | |
| 268 | * An array of properties to load the field instance with. Valid keys: | |
| 3920e7fb | 269 | * - '' - |
| 4dabd52f KS |
270 | * @return |
| 271 | * The ID of the newly-created field instance. | |
| 272 | */ | |
| 273 | function content_field_instance_create($properties) { | |
| 274 | // TODO | |
| 275 | } | |
| 276 | ||
| 277 | /** | |
| 278 | * Load a field instance. | |
| 279 | * | |
| 280 | * @param $properties | |
| 281 | * An array of properties to use in selecting a field instance. Valid keys: | |
| 282 | * - 'type_name' - The name of the content type in which the instance exists. | |
| 283 | * - 'field_name' - The name of the field whose instance is to be loaded. | |
| 284 | * @return | |
| 285 | * The field instance array. | |
| 286 | */ | |
| 287 | function content_field_instance_read($properties) { | |
| 288 | // TODO | |
| 289 | } | |
| 290 | ||
| 291 | /** | |
| 292 | * Update an existing field instance. | |
| 293 | * | |
| 294 | * @param $properties | |
| 295 | * An array of properties to set in the field instance. Valid keys: | |
| 3920e7fb | 296 | * - '' - |
| 4dabd52f KS |
297 | * @return |
| 298 | * The number of field instance updated. | |
| 299 | */ | |
| 300 | function content_field_instance_update($properties) { | |
| 301 | // TODO | |
| 302 | } | |
| 303 | ||
| 304 | /** | |
| 305 | * Delete an existing field instance. | |
| 306 | * | |
| 307 | * @param $properties | |
| 308 | * An array of properties to use in selecting a field instance. Valid keys: | |
| 309 | * - 'type_name' - The name of the content type in which the instance exists. | |
| 310 | * - 'field_name' - The name of the field whose instance is to be deleted. | |
| 311 | * @return | |
| 312 | * The number of field instances deleted. | |
| 313 | */ | |
| 314 | function content_field_instance_delete($properties) { | |
| 315 | $number_deleted = db_query("DELETE FROM {node_field_instance} WHERE type_name = '%s' AND field_name = '%s'", $properties['type_name'], $properties['field_name']); | |
| 740bb756 | 316 | |
| 4dabd52f KS |
317 | $type = content_types($properties['type_name']); |
| 318 | $field = $type['fields'][$properties['field_name']]; | |
| 319 | $field_types = _content_field_types(); | |
| 320 | $field_type = $field_types[$field['type']]; | |
| 321 | $columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $field); | |
| 740bb756 | 322 | |
| 4dabd52f KS |
323 | $instances = db_result(db_query("SELECT COUNT(*) FROM {node_field_instance} WHERE field_name = '%s'", $properties['field_name'])); |
| 324 | ||
| 325 | // If only one instance remains, we may need to change the database | |
| 326 | // representation for this field. | |
| 327 | if ($instances == 1) { | |
| 328 | if (!($field['multiple'])) { | |
| 329 | // Multiple-valued fields are always stored per-content-type. | |
| 330 | if (is_array($columns) && count($columns)) { | |
| 331 | $new_field = $field; | |
| 332 | $new_field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE; | |
| 333 | db_query("UPDATE {node_field} SET db_storage = %d WHERE field_name = '%s'", CONTENT_DB_STORAGE_PER_CONTENT_TYPE, $properties['field_name']); | |
| 334 | content_alter_db_field($field, $columns, $new_field, $columns); | |
| 335 | } | |
| 336 | } | |
| 337 | } | |
| 338 | ||
| 339 | // If no instances remain, delete the field entirely. | |
| 3920e7fb | 340 | elseif ($instances == 0) { |
| 4dabd52f KS |
341 | if (is_array($columns) && count($columns)) { |
| 342 | content_alter_db_field($field, $columns, array(), array()); | |
| 343 | } | |
| 344 | db_query("DELETE FROM {node_field} WHERE field_name = '%s'", $properties['field_name']); | |
| 345 | } | |
| 346 | ||
| 347 | content_clear_type_cache(); | |
| 3920e7fb | 348 | |
| 4dabd52f KS |
349 | return $number_deleted; |
| 350 | } |