danielebarchiesi@0: export_type & EXPORT_IN_DATABASE) { danielebarchiesi@0: // Existing record. danielebarchiesi@0: $update = array($key); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: // New record. danielebarchiesi@0: $update = array(); danielebarchiesi@0: $object->export_type = EXPORT_IN_DATABASE; danielebarchiesi@0: } danielebarchiesi@0: return drupal_write_record($table, $object, $update); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Delete a single exportable object. danielebarchiesi@0: * danielebarchiesi@0: * This only deletes from the database, which means that if an item is in danielebarchiesi@0: * code, then this is actually a revert. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table to use to retrieve $schema values. This table danielebarchiesi@0: * must have an 'export' section containing data or this function danielebarchiesi@0: * will fail. danielebarchiesi@0: * @param $object danielebarchiesi@0: * The fully populated object to delete, or the export key. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_crud_delete($table, $object) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: danielebarchiesi@0: if (!empty($export['delete callback']) && function_exists($export['delete callback'])) { danielebarchiesi@0: return $export['delete callback']($object); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: // If we were sent an object, get the export key from it. Otherwise danielebarchiesi@0: // assume we were sent the export key. danielebarchiesi@0: $value = is_object($object) ? $object->{$export['key']} : $object; danielebarchiesi@0: db_delete($table) danielebarchiesi@0: ->condition($export['key'], $value) danielebarchiesi@0: ->execute(); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Get the exported code of a single exportable object. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table to use to retrieve $schema values. This table danielebarchiesi@0: * must have an 'export' section containing data or this function danielebarchiesi@0: * will fail. danielebarchiesi@0: * @param $object danielebarchiesi@0: * The fully populated object to delete, or the export key. danielebarchiesi@0: * @param $indent danielebarchiesi@0: * Any indentation to apply to the code, in case this object is embedded danielebarchiesi@0: * into another, for example. danielebarchiesi@0: * danielebarchiesi@0: * @return danielebarchiesi@0: * A string containing the executable export of the object. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_crud_export($table, $object, $indent = '') { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: danielebarchiesi@0: if (!empty($export['export callback']) && function_exists($export['export callback'])) { danielebarchiesi@0: return $export['export callback']($object, $indent); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: return ctools_export_object($table, $object, $indent); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Turn exported code into an object. danielebarchiesi@0: * danielebarchiesi@0: * Note: If the code is poorly formed, this could crash and there is no danielebarchiesi@0: * way to prevent this. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table to use to retrieve $schema values. This table danielebarchiesi@0: * must have an 'export' section containing data or this function danielebarchiesi@0: * will fail. danielebarchiesi@0: * @param $code danielebarchiesi@0: * The code to eval to create the object. danielebarchiesi@0: * danielebarchiesi@0: * @return danielebarchiesi@0: * An object created from the export. This object will NOT have been saved danielebarchiesi@0: * to the database. In the case of failure, a string containing all errors danielebarchiesi@0: * that the system was able to determine. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_crud_import($table, $code) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: danielebarchiesi@0: if (!empty($export['import callback']) && function_exists($export['import callback'])) { danielebarchiesi@0: return $export['import callback']($code); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: ob_start(); danielebarchiesi@0: eval($code); danielebarchiesi@0: ob_end_clean(); danielebarchiesi@0: danielebarchiesi@0: if (empty(${$export['identifier']})) { danielebarchiesi@0: $errors = ob_get_contents(); danielebarchiesi@0: if (empty($errors)) { danielebarchiesi@0: $errors = t('No item found.'); danielebarchiesi@0: } danielebarchiesi@0: return $errors; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $item = ${$export['identifier']}; danielebarchiesi@0: danielebarchiesi@0: // Set these defaults just the same way that ctools_export_new_object sets danielebarchiesi@0: // them. danielebarchiesi@0: $item->export_type = NULL; danielebarchiesi@0: $item->{$export['export type string']} = t('Local'); danielebarchiesi@0: danielebarchiesi@0: return $item; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Change the status of a certain object. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table to use to enable a certain object. This table danielebarchiesi@0: * must have an 'export' section containing data or this function danielebarchiesi@0: * will fail. danielebarchiesi@0: * @param $object danielebarchiesi@0: * The fully populated object to enable, or the machine readable name. danielebarchiesi@0: * @param $status danielebarchiesi@0: * The status, in this case, is whether or not it is 'disabled'. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_crud_set_status($table, $object, $status) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: danielebarchiesi@0: if (!empty($export['status callback']) && function_exists($export['status callback'])) { danielebarchiesi@0: $export['status callback']($object, $status); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: if (is_object($object)) { danielebarchiesi@0: ctools_export_set_object_status($object, $status); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: ctools_export_set_status($table, $object, $status); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Enable a certain object. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table to use to enable a certain object. This table danielebarchiesi@0: * must have an 'export' section containing data or this function danielebarchiesi@0: * will fail. danielebarchiesi@0: * @param $object danielebarchiesi@0: * The fully populated object to enable, or the machine readable name. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_crud_enable($table, $object) { danielebarchiesi@0: return ctools_export_crud_set_status($table, $object, FALSE); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Disable a certain object. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table to use to disable a certain object. This table danielebarchiesi@0: * must have an 'export' section containing data or this function danielebarchiesi@0: * will fail. danielebarchiesi@0: * @param $object danielebarchiesi@0: * The fully populated object to disable, or the machine readable name. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_crud_disable($table, $object) { danielebarchiesi@0: return ctools_export_crud_set_status($table, $object, TRUE); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * @} danielebarchiesi@0: */ danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Load some number of exportable objects. danielebarchiesi@0: * danielebarchiesi@0: * This function will cache the objects, load subsidiary objects if necessary, danielebarchiesi@0: * check default objects in code and properly set them up. It will cache danielebarchiesi@0: * the results so that multiple calls to load the same objects danielebarchiesi@0: * will not cause problems. danielebarchiesi@0: * danielebarchiesi@0: * It attempts to reduce, as much as possible, the number of queries danielebarchiesi@0: * involved. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table to be loaded from. Data is expected to be in the danielebarchiesi@0: * schema to make all this work. danielebarchiesi@0: * @param $type danielebarchiesi@0: * A string to notify the loader what the argument is danielebarchiesi@0: * - all: load all items. This is the default. $args is unused. danielebarchiesi@0: * - names: $args will be an array of specific named objects to load. danielebarchiesi@0: * - conditions: $args will be a keyed array of conditions. The conditions danielebarchiesi@0: * must be in the schema for this table or errors will result. danielebarchiesi@0: * @param $args danielebarchiesi@0: * An array of arguments whose actual use is defined by the $type argument. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_load_object($table, $type = 'all', $args = array()) { danielebarchiesi@0: $cache = &drupal_static(__FUNCTION__); danielebarchiesi@0: $cache_table_exists = &drupal_static(__FUNCTION__ . '_table_exists', array()); danielebarchiesi@0: $cached_database = &drupal_static('ctools_export_load_object_all'); danielebarchiesi@0: danielebarchiesi@0: if (!array_key_exists($table, $cache_table_exists)) { danielebarchiesi@0: $cache_table_exists[$table] = db_table_exists($table); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: if (empty($schema) || !$cache_table_exists[$table]) { danielebarchiesi@0: return array(); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: danielebarchiesi@0: if (!isset($cache[$table])) { danielebarchiesi@0: $cache[$table] = array(); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // If fetching all and cached all, we've done so and we are finished. danielebarchiesi@0: if ($type == 'all' && !empty($cached_database[$table])) { danielebarchiesi@0: return $cache[$table]; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $return = array(); danielebarchiesi@0: danielebarchiesi@0: // Don't load anything we've already cached. danielebarchiesi@0: if ($type == 'names' && !empty($args)) { danielebarchiesi@0: foreach ($args as $id => $name) { danielebarchiesi@0: if (isset($cache[$table][$name])) { danielebarchiesi@0: $return[$name] = $cache[$table][$name]; danielebarchiesi@0: unset($args[$id]); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // If nothing left to load, return the result. danielebarchiesi@0: if (empty($args)) { danielebarchiesi@0: return $return; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Build the query danielebarchiesi@0: $query = db_select($table, 't__0')->fields('t__0'); danielebarchiesi@0: $alias_count = 1; danielebarchiesi@0: if (!empty($schema['join'])) { danielebarchiesi@0: foreach ($schema['join'] as $join_key => $join) { danielebarchiesi@0: if ($join_schema = drupal_get_schema($join['table'])) { danielebarchiesi@0: $query->join($join['table'], 't__' . $alias_count, 't__0.' . $join['left_key'] . ' = ' . 't__' . $alias_count . '.' . $join['right_key']); danielebarchiesi@0: $query->fields('t__' . $alias_count); danielebarchiesi@0: $alias_count++; danielebarchiesi@0: danielebarchiesi@0: // Allow joining tables to alter the query through a callback. danielebarchiesi@0: if (isset($join['callback']) && function_exists($join['callback'])) { danielebarchiesi@0: $join['callback']($query, $schema, $join_schema); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $conditions = array(); danielebarchiesi@0: $query_args = array(); danielebarchiesi@0: danielebarchiesi@0: // If they passed in names, add them to the query. danielebarchiesi@0: if ($type == 'names') { danielebarchiesi@0: $query->condition($export['key'], $args, 'IN'); danielebarchiesi@0: } danielebarchiesi@0: else if ($type == 'conditions') { danielebarchiesi@0: foreach ($args as $key => $value) { danielebarchiesi@0: if (isset($schema['fields'][$key])) { danielebarchiesi@0: $query->condition($key, $value); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $result = $query->execute(); danielebarchiesi@0: danielebarchiesi@0: $status = variable_get($export['status'], array()); danielebarchiesi@0: // Unpack the results of the query onto objects and cache them. danielebarchiesi@0: foreach ($result as $data) { danielebarchiesi@0: if (isset($schema['export']['object factory']) && function_exists($schema['export']['object factory'])) { danielebarchiesi@0: $object = $schema['export']['object factory']($schema, $data); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $object = _ctools_export_unpack_object($schema, $data, $export['object']); danielebarchiesi@0: } danielebarchiesi@0: $object->table = $table; danielebarchiesi@0: $object->{$export['export type string']} = t('Normal'); danielebarchiesi@0: $object->export_type = EXPORT_IN_DATABASE; danielebarchiesi@0: // Determine if default object is enabled or disabled. danielebarchiesi@0: if (isset($status[$object->{$export['key']}])) { danielebarchiesi@0: $object->disabled = $status[$object->{$export['key']}]; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $cache[$table][$object->{$export['key']}] = $object; danielebarchiesi@0: if ($type == 'conditions') { danielebarchiesi@0: $return[$object->{$export['key']}] = $object; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Load subrecords. danielebarchiesi@0: if (isset($export['subrecords callback']) && function_exists($export['subrecords callback'])) { danielebarchiesi@0: $export['subrecords callback']($cache[$table]); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if ($type == 'names' && !empty($args) && !empty($export['cache defaults'])) { danielebarchiesi@0: $defaults = _ctools_export_get_some_defaults($table, $export, $args); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $defaults = _ctools_export_get_defaults($table, $export); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if ($defaults) { danielebarchiesi@0: foreach ($defaults as $object) { danielebarchiesi@0: if ($type == 'conditions') { danielebarchiesi@0: // if this does not match all of our conditions, skip it. danielebarchiesi@0: foreach ($args as $key => $value) { danielebarchiesi@0: if (!isset($object->$key)) { danielebarchiesi@0: continue 2; danielebarchiesi@0: } danielebarchiesi@0: if (is_array($value)) { danielebarchiesi@0: if (!in_array($object->$key, $value)) { danielebarchiesi@0: continue 2; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: else if ($object->$key != $value) { danielebarchiesi@0: continue 2; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: else if ($type == 'names') { danielebarchiesi@0: if (!in_array($object->{$export['key']}, $args)) { danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Determine if default object is enabled or disabled. danielebarchiesi@0: if (isset($status[$object->{$export['key']}])) { danielebarchiesi@0: $object->disabled = $status[$object->{$export['key']}]; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (!empty($cache[$table][$object->{$export['key']}])) { danielebarchiesi@0: $cache[$table][$object->{$export['key']}]->{$export['export type string']} = t('Overridden'); danielebarchiesi@0: $cache[$table][$object->{$export['key']}]->export_type |= EXPORT_IN_CODE; danielebarchiesi@0: $cache[$table][$object->{$export['key']}]->export_module = isset($object->export_module) ? $object->export_module : NULL; danielebarchiesi@0: if ($type == 'conditions') { danielebarchiesi@0: $return[$object->{$export['key']}] = $cache[$table][$object->{$export['key']}]; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $object->{$export['export type string']} = t('Default'); danielebarchiesi@0: $object->export_type = EXPORT_IN_CODE; danielebarchiesi@0: $object->in_code_only = TRUE; danielebarchiesi@0: $object->table = $table; danielebarchiesi@0: danielebarchiesi@0: $cache[$table][$object->{$export['key']}] = $object; danielebarchiesi@0: if ($type == 'conditions') { danielebarchiesi@0: $return[$object->{$export['key']}] = $object; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // If fetching all, we've done so and we are finished. danielebarchiesi@0: if ($type == 'all') { danielebarchiesi@0: $cached_database[$table] = TRUE; danielebarchiesi@0: return $cache[$table]; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if ($type == 'names') { danielebarchiesi@0: foreach ($args as $name) { danielebarchiesi@0: if (isset($cache[$table][$name])) { danielebarchiesi@0: $return[$name] = $cache[$table][$name]; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // For conditions, danielebarchiesi@0: return $return; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Reset all static caches in ctools_export_load_object() or static caches for danielebarchiesi@0: * a given table in ctools_export_load_object(). danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * String that is the name of a table. If not defined, all static caches in danielebarchiesi@0: * ctools_export_load_object() will be reset. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_load_object_reset($table = NULL) { danielebarchiesi@0: // Reset plugin cache to make sure new include files are picked up. danielebarchiesi@0: ctools_include('plugins'); danielebarchiesi@0: ctools_get_plugins_reset(); danielebarchiesi@0: if (empty($table)) { danielebarchiesi@0: drupal_static_reset('ctools_export_load_object'); danielebarchiesi@0: drupal_static_reset('ctools_export_load_object_all'); danielebarchiesi@0: drupal_static_reset('_ctools_export_get_defaults'); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $cache = &drupal_static('ctools_export_load_object'); danielebarchiesi@0: $cached_database = &drupal_static('ctools_export_load_object_all'); danielebarchiesi@0: $cached_defaults = &drupal_static('_ctools_export_get_defaults'); danielebarchiesi@0: unset($cache[$table]); danielebarchiesi@0: unset($cached_database[$table]); danielebarchiesi@0: unset($cached_defaults[$table]); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Get the default version of an object, if it exists. danielebarchiesi@0: * danielebarchiesi@0: * This function doesn't care if an object is in the database or not and danielebarchiesi@0: * does not check. This means that export_type could appear to be incorrect, danielebarchiesi@0: * because a version could exist in the database. However, it's not danielebarchiesi@0: * incorrect for this function as it is *only* used for the default danielebarchiesi@0: * in code version. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_get_default_object($table, $name) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: danielebarchiesi@0: if (!$export['default hook']) { danielebarchiesi@0: return; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Try to load individually from cache if this cache is enabled. danielebarchiesi@0: if (!empty($export['cache defaults'])) { danielebarchiesi@0: $defaults = _ctools_export_get_some_defaults($table, $export, array($name)); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $defaults = _ctools_export_get_defaults($table, $export); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $status = variable_get($export['status'], array()); danielebarchiesi@0: danielebarchiesi@0: if (!isset($defaults[$name])) { danielebarchiesi@0: return; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $object = $defaults[$name]; danielebarchiesi@0: danielebarchiesi@0: // Determine if default object is enabled or disabled. danielebarchiesi@0: if (isset($status[$object->{$export['key']}])) { danielebarchiesi@0: $object->disabled = $status[$object->{$export['key']}]; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $object->{$export['export type string']} = t('Default'); danielebarchiesi@0: $object->export_type = EXPORT_IN_CODE; danielebarchiesi@0: $object->in_code_only = TRUE; danielebarchiesi@0: danielebarchiesi@0: return $object; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Call the hook to get all default objects of the given type from the danielebarchiesi@0: * export. If configured properly, this could include loading up an API danielebarchiesi@0: * to get default objects. danielebarchiesi@0: */ danielebarchiesi@0: function _ctools_export_get_defaults($table, $export) { danielebarchiesi@0: $cache = &drupal_static(__FUNCTION__, array()); danielebarchiesi@0: danielebarchiesi@0: // If defaults may be cached, first see if we can load from cache. danielebarchiesi@0: if (!isset($cache[$table]) && !empty($export['cache defaults'])) { danielebarchiesi@0: $cache[$table] = _ctools_export_get_defaults_from_cache($table, $export); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (!isset($cache[$table])) { danielebarchiesi@0: // If we're caching, attempt to get a lock. We will wait a short time danielebarchiesi@0: // on the lock, but not too long, because it's better to just rebuild danielebarchiesi@0: // and throw away results than wait too long on a lock. danielebarchiesi@0: if (!empty($export['cache defaults'])) { danielebarchiesi@0: for ($counter = 0; !($lock = lock_acquire('ctools_export:' . $table)) && $counter > 5; $counter++) { danielebarchiesi@0: lock_wait('ctools_export:' . $table, 1); danielebarchiesi@0: ++$counter; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $cache[$table] = array(); danielebarchiesi@0: danielebarchiesi@0: if ($export['default hook']) { danielebarchiesi@0: if (!empty($export['api'])) { danielebarchiesi@0: ctools_include('plugins'); danielebarchiesi@0: $info = ctools_plugin_api_include($export['api']['owner'], $export['api']['api'], danielebarchiesi@0: $export['api']['minimum_version'], $export['api']['current_version']); danielebarchiesi@0: $modules = array_keys($info); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $modules = module_implements($export['default hook']); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: foreach ($modules as $module) { danielebarchiesi@0: $function = $module . '_' . $export['default hook']; danielebarchiesi@0: if (function_exists($function)) { danielebarchiesi@0: foreach ((array) $function($export) as $name => $object) { danielebarchiesi@0: // Record the module that provides this exportable. danielebarchiesi@0: $object->export_module = $module; danielebarchiesi@0: danielebarchiesi@0: if (empty($export['api'])) { danielebarchiesi@0: $cache[$table][$name] = $object; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: // If version checking is enabled, ensure that the object can be used. danielebarchiesi@0: if (isset($object->api_version) && danielebarchiesi@0: version_compare($object->api_version, $export['api']['minimum_version']) >= 0 && danielebarchiesi@0: version_compare($object->api_version, $export['api']['current_version']) <= 0) { danielebarchiesi@0: $cache[$table][$name] = $object; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: drupal_alter($export['default hook'], $cache[$table]); danielebarchiesi@0: danielebarchiesi@0: // If we acquired a lock earlier, cache the results and release the danielebarchiesi@0: // lock. danielebarchiesi@0: if (!empty($lock)) { danielebarchiesi@0: // Cache the index. danielebarchiesi@0: $index = array_keys($cache[$table]); danielebarchiesi@0: cache_set('ctools_export_index:' . $table, $index, $export['default cache bin']); danielebarchiesi@0: danielebarchiesi@0: // Cache each object. danielebarchiesi@0: foreach ($cache[$table] as $name => $object) { danielebarchiesi@0: cache_set('ctools_export:' . $table . ':' . $name, $object, $export['default cache bin']); danielebarchiesi@0: } danielebarchiesi@0: lock_release('ctools_export:' . $table); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $cache[$table]; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Attempt to load default objects from cache. danielebarchiesi@0: * danielebarchiesi@0: * We can be instructed to cache default objects by the schema. If so danielebarchiesi@0: * we cache them as an index which is a list of all default objects, and danielebarchiesi@0: * then each default object is cached individually. danielebarchiesi@0: * danielebarchiesi@0: * @return Either an array of cached objects, or NULL indicating a cache danielebarchiesi@0: * rebuild is necessary. danielebarchiesi@0: */ danielebarchiesi@0: function _ctools_export_get_defaults_from_cache($table, $export) { danielebarchiesi@0: $data = cache_get('ctools_export_index:' . $table, $export['default cache bin']); danielebarchiesi@0: if (!$data || !is_array($data->data)) { danielebarchiesi@0: return; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // This is the perfectly valid case where there are no default objects, danielebarchiesi@0: // and we have cached this state. danielebarchiesi@0: if (empty($data->data)) { danielebarchiesi@0: return array(); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $keys = array(); danielebarchiesi@0: foreach ($data->data as $name) { danielebarchiesi@0: $keys[] = 'ctools_export:' . $table . ':' . $name; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $data = cache_get_multiple($keys, $export['default cache bin']); danielebarchiesi@0: danielebarchiesi@0: // If any of our indexed keys missed, then we have a fail and we need to danielebarchiesi@0: // rebuild. danielebarchiesi@0: if (!empty($keys)) { danielebarchiesi@0: return; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Now, translate the returned cache objects to actual objects. danielebarchiesi@0: $cache = array(); danielebarchiesi@0: foreach ($data as $cached_object) { danielebarchiesi@0: $cache[$cached_object->data->{$export['key']}] = $cached_object->data; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $cache; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Get a limited number of default objects. danielebarchiesi@0: * danielebarchiesi@0: * This attempts to load the objects directly from cache. If it cannot, danielebarchiesi@0: * the cache is rebuilt. This does not disturb the general get defaults danielebarchiesi@0: * from cache object. danielebarchiesi@0: * danielebarchiesi@0: * This function should ONLY be called if default caching is enabled. danielebarchiesi@0: * It does not check, it is assumed the caller has already done so. danielebarchiesi@0: */ danielebarchiesi@0: function _ctools_export_get_some_defaults($table, $export, $names) { danielebarchiesi@0: foreach ($names as $name) { danielebarchiesi@0: $keys[] = 'ctools_export:' . $table . ':' . $name; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $data = cache_get_multiple($keys, $export['default cache bin']); danielebarchiesi@0: danielebarchiesi@0: // Cache hits remove the $key from $keys by reference. Cache danielebarchiesi@0: // misses do not. A cache miss indicates we may have to rebuild. danielebarchiesi@0: if (!empty($keys)) { danielebarchiesi@0: return _ctools_export_get_defaults($table, $export); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Now, translate the returned cache objects to actual objects. danielebarchiesi@0: $cache = array(); danielebarchiesi@0: foreach ($data as $cached_object) { danielebarchiesi@0: $cache[$cached_object->data->{$export['key']}] = $cached_object->data; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $cache; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Unpack data loaded from the database onto an object. danielebarchiesi@0: * danielebarchiesi@0: * @param $schema danielebarchiesi@0: * The schema from drupal_get_schema(). danielebarchiesi@0: * @param $data danielebarchiesi@0: * The data as loaded from the database. danielebarchiesi@0: * @param $object danielebarchiesi@0: * If an object, data will be unpacked onto it. If a string danielebarchiesi@0: * an object of that type will be created. danielebarchiesi@0: */ danielebarchiesi@0: function _ctools_export_unpack_object($schema, $data, $object = 'stdClass') { danielebarchiesi@0: if (is_string($object)) { danielebarchiesi@0: if (class_exists($object)) { danielebarchiesi@0: $object = new $object; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $object = new stdClass; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Go through our schema and build correlations. danielebarchiesi@0: foreach ($schema['fields'] as $field => $info) { danielebarchiesi@0: if (isset($data->$field)) { danielebarchiesi@0: $object->$field = empty($info['serialize']) ? $data->$field : unserialize($data->$field); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $object->$field = NULL; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (isset($schema['join'])) { danielebarchiesi@0: foreach ($schema['join'] as $join_key => $join) { danielebarchiesi@0: $join_schema = ctools_export_get_schema($join['table']); danielebarchiesi@0: if (!empty($join['load'])) { danielebarchiesi@0: foreach ($join['load'] as $field) { danielebarchiesi@0: $info = $join_schema['fields'][$field]; danielebarchiesi@0: $object->$field = empty($info['serialize']) ? $data->$field : unserialize($data->$field); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $object; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Unpack data loaded from the database onto an object. danielebarchiesi@0: * danielebarchiesi@0: * @param $table danielebarchiesi@0: * The name of the table this object represents. danielebarchiesi@0: * @param $data danielebarchiesi@0: * The data as loaded from the database. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_unpack_object($table, $data) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: return _ctools_export_unpack_object($schema, $data, $schema['export']['object']); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Export a field. danielebarchiesi@0: * danielebarchiesi@0: * This is a replacement for var_export(), allowing us to more nicely danielebarchiesi@0: * format exports. It will recurse down into arrays and will try to danielebarchiesi@0: * properly export bools when it can, though PHP has a hard time with danielebarchiesi@0: * this since they often end up as strings or ints. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_var_export($var, $prefix = '') { danielebarchiesi@0: if (is_array($var)) { danielebarchiesi@0: if (empty($var)) { danielebarchiesi@0: $output = 'array()'; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $output = "array(\n"; danielebarchiesi@0: foreach ($var as $key => $value) { danielebarchiesi@0: $output .= $prefix . " " . ctools_var_export($key) . " => " . ctools_var_export($value, $prefix . ' ') . ",\n"; danielebarchiesi@0: } danielebarchiesi@0: $output .= $prefix . ')'; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: else if (is_object($var) && get_class($var) === 'stdClass') { danielebarchiesi@0: // var_export() will export stdClass objects using an undefined danielebarchiesi@0: // magic method __set_state() leaving the export broken. This danielebarchiesi@0: // workaround avoids this by casting the object as an array for danielebarchiesi@0: // export and casting it back to an object when evaluated. danielebarchiesi@0: $output = '(object) ' . ctools_var_export((array) $var, $prefix); danielebarchiesi@0: } danielebarchiesi@0: else if (is_bool($var)) { danielebarchiesi@0: $output = $var ? 'TRUE' : 'FALSE'; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $output = var_export($var, TRUE); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $output; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Export an object into code. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_object($table, $object, $indent = '', $identifier = NULL, $additions = array(), $additions2 = array()) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: if (!isset($identifier)) { danielebarchiesi@0: $identifier = $schema['export']['identifier']; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $output = $indent . '$' . $identifier . ' = new ' . get_class($object) . "();\n"; danielebarchiesi@0: danielebarchiesi@0: if ($schema['export']['can disable']) { danielebarchiesi@0: $output .= $indent . '$' . $identifier . '->disabled = FALSE; /* Edit this to true to make a default ' . $identifier . ' disabled initially */' . "\n"; danielebarchiesi@0: } danielebarchiesi@0: if (!empty($schema['export']['api']['current_version'])) { danielebarchiesi@0: $output .= $indent . '$' . $identifier . '->api_version = ' . $schema['export']['api']['current_version'] . ";\n"; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Put top additions here: danielebarchiesi@0: foreach ($additions as $field => $value) { danielebarchiesi@0: $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n"; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $fields = $schema['fields']; danielebarchiesi@0: if (!empty($schema['join'])) { danielebarchiesi@0: foreach ($schema['join'] as $join) { danielebarchiesi@0: if (!empty($join['load'])) { danielebarchiesi@0: foreach ($join['load'] as $join_field) { danielebarchiesi@0: $fields[$join_field] = $join['fields'][$join_field]; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Go through our schema and joined tables and build correlations. danielebarchiesi@0: foreach ($fields as $field => $info) { danielebarchiesi@0: if (!empty($info['no export'])) { danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: if (!isset($object->$field)) { danielebarchiesi@0: if (isset($info['default'])) { danielebarchiesi@0: $object->$field = $info['default']; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $object->$field = ''; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Note: This is the *field* export callback, not the table one! danielebarchiesi@0: if (!empty($info['export callback']) && function_exists($info['export callback'])) { danielebarchiesi@0: $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . $info['export callback']($object, $field, $object->$field, $indent) . ";\n"; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $value = $object->$field; danielebarchiesi@0: if ($info['type'] == 'int') { danielebarchiesi@0: $value = (isset($info['size']) && $info['size'] == 'tiny') ? (bool) $value : (int) $value; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n"; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // And bottom additions here danielebarchiesi@0: foreach ($additions2 as $field => $value) { danielebarchiesi@0: $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . ctools_var_export($value, $indent) . ";\n"; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $output; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Get the schema for a given table. danielebarchiesi@0: * danielebarchiesi@0: * This looks for data the export subsystem needs and applies defaults so danielebarchiesi@0: * that it's easily available. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_get_schema($table) { danielebarchiesi@0: $cache = &drupal_static(__FUNCTION__); danielebarchiesi@0: if (empty($cache[$table])) { danielebarchiesi@0: $schema = drupal_get_schema($table); danielebarchiesi@0: danielebarchiesi@0: // If our schema isn't loaded, it's possible we're in a state where it danielebarchiesi@0: // simply hasn't been cached. If we've been asked, let's force the danielebarchiesi@0: // issue. danielebarchiesi@0: if (!$schema || empty($schema['export'])) { danielebarchiesi@0: // force a schema reset: danielebarchiesi@0: $schema = drupal_get_schema($table, TRUE); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (!isset($schema['export'])) { danielebarchiesi@0: return array(); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (empty($schema['module'])) { danielebarchiesi@0: return array(); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Add some defaults danielebarchiesi@0: $schema['export'] += array( danielebarchiesi@0: 'key' => 'name', danielebarchiesi@0: 'key name' => 'Name', danielebarchiesi@0: 'object' => 'stdClass', danielebarchiesi@0: 'status' => 'default_' . $table, danielebarchiesi@0: 'default hook' => 'default_' . $table, danielebarchiesi@0: 'can disable' => TRUE, danielebarchiesi@0: 'identifier' => $table, danielebarchiesi@0: 'primary key' => !empty($schema['primary key']) ? $schema['primary key'][0] : '', danielebarchiesi@0: 'bulk export' => TRUE, danielebarchiesi@0: 'list callback' => "$schema[module]_{$table}_list", danielebarchiesi@0: 'to hook code callback' => "$schema[module]_{$table}_to_hook_code", danielebarchiesi@0: 'cache defaults' => FALSE, danielebarchiesi@0: 'default cache bin' => 'cache', danielebarchiesi@0: 'export type string' => 'type', danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: // If the export definition doesn't have the "primary key" then the CRUD danielebarchiesi@0: // save callback won't work. danielebarchiesi@0: if (empty($schema['export']['primary key']) && user_access('administer site configuration')) { danielebarchiesi@0: drupal_set_message(t('The export definition of @table is missing the "primary key" property.', array('@table' => $table)), 'error'); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Notes: danielebarchiesi@0: // The following callbacks may be defined to override default behavior danielebarchiesi@0: // when using CRUD functions: danielebarchiesi@0: // danielebarchiesi@0: // create callback danielebarchiesi@0: // load callback danielebarchiesi@0: // load multiple callback danielebarchiesi@0: // load all callback danielebarchiesi@0: // save callback danielebarchiesi@0: // delete callback danielebarchiesi@0: // export callback danielebarchiesi@0: // import callback danielebarchiesi@0: // danielebarchiesi@0: // See the appropriate ctools_export_crud function for details on what danielebarchiesi@0: // arguments these callbacks should accept. Please do not call these danielebarchiesi@0: // directly, always use the ctools_export_crud_* wrappers to ensure danielebarchiesi@0: // that default implementations are honored. danielebarchiesi@0: $cache[$table] = $schema; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $cache[$table]; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Gets the schemas for all tables with ctools object metadata. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_get_schemas($for_export = FALSE) { danielebarchiesi@0: $export_tables = &drupal_static(__FUNCTION__); danielebarchiesi@0: if (is_null($export_tables)) { danielebarchiesi@0: $export_tables = array(); danielebarchiesi@0: $schemas = drupal_get_schema(); danielebarchiesi@0: foreach ($schemas as $table => $schema) { danielebarchiesi@0: if (!isset($schema['export'])) { danielebarchiesi@0: unset($schemas[$table]); danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: $export_tables[$table] = ctools_export_get_schema($table); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: return $for_export ? array_filter($export_tables, '_ctools_export_filter_export_tables') : $export_tables; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: function _ctools_export_filter_export_tables($schema) { danielebarchiesi@0: return !empty($schema['export']['bulk export']); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: function ctools_export_get_schemas_by_module($modules = array(), $for_export = FALSE) { danielebarchiesi@0: $export_tables = array(); danielebarchiesi@0: $list = ctools_export_get_schemas($for_export); danielebarchiesi@0: foreach ($list as $table => $schema) { danielebarchiesi@0: $export_tables[$schema['module']][$table] = $schema; danielebarchiesi@0: } danielebarchiesi@0: return empty($modules) ? $export_tables : array_keys($export_tables, $modules); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Set the status of a default $object as a variable. danielebarchiesi@0: * danielebarchiesi@0: * The status, in this case, is whether or not it is 'disabled'. danielebarchiesi@0: * This function does not check to make sure $object actually danielebarchiesi@0: * exists. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_set_status($table, $name, $new_status = TRUE) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $status = variable_get($schema['export']['status'], array()); danielebarchiesi@0: danielebarchiesi@0: $status[$name] = $new_status; danielebarchiesi@0: variable_set($schema['export']['status'], $status); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Set the status of a default $object as a variable. danielebarchiesi@0: * danielebarchiesi@0: * This is more efficient than ctools_export_set_status because it danielebarchiesi@0: * will actually unset the variable entirely if it's not necessary, danielebarchiesi@0: * this saving a bit of space. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_set_object_status($object, $new_status = TRUE) { danielebarchiesi@0: $table = $object->table; danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: $status = variable_get($export['status'], array()); danielebarchiesi@0: danielebarchiesi@0: // Compare danielebarchiesi@0: if (!$new_status && $object->export_type & EXPORT_IN_DATABASE) { danielebarchiesi@0: unset($status[$object->{$export['key']}]); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $status[$object->{$export['key']}] = $new_status; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: variable_set($export['status'], $status); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Provide a form for displaying an export. danielebarchiesi@0: * danielebarchiesi@0: * This is a simple form that should be invoked like this: danielebarchiesi@0: * @code danielebarchiesi@0: * $output = drupal_get_form('ctools_export_form', $code, $object_title); danielebarchiesi@0: * @endcode danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_form($form, &$form_state, $code, $title = '') { danielebarchiesi@0: $lines = substr_count($code, "\n"); danielebarchiesi@0: $form['code'] = array( danielebarchiesi@0: '#type' => 'textarea', danielebarchiesi@0: '#title' => $title, danielebarchiesi@0: '#default_value' => $code, danielebarchiesi@0: '#rows' => $lines, danielebarchiesi@0: ); danielebarchiesi@0: danielebarchiesi@0: return $form; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Create a new object based upon schema values. danielebarchiesi@0: * danielebarchiesi@0: * Because 'default' has ambiguous meaning on some fields, we will actually danielebarchiesi@0: * use 'object default' to fill in default values if default is not set danielebarchiesi@0: * That's a little safer to use as it won't cause weird database default danielebarchiesi@0: * situations. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_new_object($table, $set_defaults = TRUE) { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: danielebarchiesi@0: $object = new $export['object']; danielebarchiesi@0: foreach ($schema['fields'] as $field => $info) { danielebarchiesi@0: if (isset($info['object default'])) { danielebarchiesi@0: $object->$field = $info['object default']; danielebarchiesi@0: } danielebarchiesi@0: else if (isset($info['default'])) { danielebarchiesi@0: $object->$field = $info['default']; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $object->$field = NULL; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if ($set_defaults) { danielebarchiesi@0: // Set some defaults so this data always exists. danielebarchiesi@0: // We don't set the export_type property here, as this object is not saved danielebarchiesi@0: // yet. We do give it NULL so we don't generate notices trying to read it. danielebarchiesi@0: $object->export_type = NULL; danielebarchiesi@0: $object->{$export['export type string']} = t('Local'); danielebarchiesi@0: } danielebarchiesi@0: return $object; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Convert a group of objects to code based upon input and return this as a larger danielebarchiesi@0: * export. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_to_hook_code(&$code, $table, $names = array(), $name = 'foo') { danielebarchiesi@0: $schema = ctools_export_get_schema($table); danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: // Use the schema-specified function for generating hook code, if one exists danielebarchiesi@0: if (function_exists($export['to hook code callback'])) { danielebarchiesi@0: $output = $export['to hook code callback']($names, $name); danielebarchiesi@0: } danielebarchiesi@0: // Otherwise, the following code generates basic hook code danielebarchiesi@0: else { danielebarchiesi@0: $output = ctools_export_default_to_hook_code($schema, $table, $names, $name); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (!empty($output)) { danielebarchiesi@0: if (isset($export['api'])) { danielebarchiesi@0: if (isset($code[$export['api']['owner']][$export['api']['api']]['version'])) { danielebarchiesi@0: $code[$export['api']['owner']][$export['api']['api']]['version'] = max($code[$export['api']['owner']][$export['api']['api']]['version'], $export['api']['minimum_version']); danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: $code[$export['api']['owner']][$export['api']['api']]['version'] = $export['api']['minimum_version']; danielebarchiesi@0: $code[$export['api']['owner']][$export['api']['api']]['code'] = ''; danielebarchiesi@0: } danielebarchiesi@0: $code[$export['api']['owner']][$export['api']['api']]['code'] .= $output; danielebarchiesi@0: } danielebarchiesi@0: else { danielebarchiesi@0: if (empty($code['general'])) { danielebarchiesi@0: $code['general'] = ''; danielebarchiesi@0: } danielebarchiesi@0: $code['general'] .= $output; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: /** danielebarchiesi@0: * Default function to export objects to code. danielebarchiesi@0: * danielebarchiesi@0: * Note that if your module provides a 'to hook code callback' then it will danielebarchiesi@0: * receive only $names and $name as arguments. Your module is presumed to danielebarchiesi@0: * already know the rest. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_default_to_hook_code($schema, $table, $names, $name) { danielebarchiesi@0: $export = $schema['export']; danielebarchiesi@0: $output = ''; danielebarchiesi@0: $objects = ctools_export_crud_load_multiple($table, $names); danielebarchiesi@0: if ($objects) { danielebarchiesi@0: $output = "/**\n"; danielebarchiesi@0: $output .= " * Implements hook_{$export['default hook']}().\n"; danielebarchiesi@0: $output .= " */\n"; danielebarchiesi@0: $output .= "function " . $name . "_{$export['default hook']}() {\n"; danielebarchiesi@0: $output .= " \${$export['identifier']}s = array();\n\n"; danielebarchiesi@0: foreach ($objects as $object) { danielebarchiesi@0: $output .= ctools_export_crud_export($table, $object, ' '); danielebarchiesi@0: $output .= " \${$export['identifier']}s['" . check_plain($object->$export['key']) . "'] = \${$export['identifier']};\n\n"; danielebarchiesi@0: } danielebarchiesi@0: $output .= " return \${$export['identifier']}s;\n"; danielebarchiesi@0: $output .= "}\n"; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: return $output; danielebarchiesi@0: } danielebarchiesi@0: /** danielebarchiesi@0: * Default function for listing bulk exportable objects. danielebarchiesi@0: */ danielebarchiesi@0: function ctools_export_default_list($table, $schema) { danielebarchiesi@0: $list = array(); danielebarchiesi@0: danielebarchiesi@0: $items = ctools_export_crud_load_all($table); danielebarchiesi@0: $export_key = $schema['export']['key']; danielebarchiesi@0: foreach ($items as $item) { danielebarchiesi@0: // Try a couple of possible obvious title keys: danielebarchiesi@0: $keys = array('admin_title', 'title'); danielebarchiesi@0: if (isset($schema['export']['admin_title'])) { danielebarchiesi@0: array_unshift($keys, $schema['export']['admin_title']); danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: $string = ''; danielebarchiesi@0: foreach ($keys as $key) { danielebarchiesi@0: if (!empty($item->$key)) { danielebarchiesi@0: $string = $item->$key . " (" . $item->$export_key . ")"; danielebarchiesi@0: break; danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: if (empty($string)) { danielebarchiesi@0: $string = $item->$export_key; danielebarchiesi@0: } danielebarchiesi@0: $list[$item->$export_key] = check_plain($string); danielebarchiesi@0: } danielebarchiesi@0: return $list; danielebarchiesi@0: }