How can I limit the result of ctools_export_load_object? Imagine I have something like this:

$result = ctools_export_load_object('mytable', 'conditions', array('date' => '1337020900'));

Also, What is the difference between ctools_export_load_object() and db_query()?


You are right; that is how you should call ctools_export_load_object() to filter the returned objects. Keep in mind that:

  • For each condition you can just enter a value a database field must have
  • If you enter more than one condition, the function will return the objects for which all the conditions are verified

The code used from the function for handling the conditions is the following one.

  else if ($type == 'conditions') {
    foreach ($args as $key => $value) {
      if (isset($schema['fields'][$key])) {
        $query->condition($key, $value);

Because that code, you cannot get (for example) the objects for which the date is 1337020900, or 1337020910, or 1337020940, or 1337020906. You cannot choose the operator to apply for the conditions, which means (for example) that you cannot get all the objects for which the date is greater than 1337020900, or lower than 1337020900.

The difference between ctools_export_load_object(), and db_query() is that:

  • ctools_export_load_object() doesn't just return the objects obtained from a database table; it returns also object returned from a specific hook. This is done from the following code, contained in _ctools_export_get_defaults().

    if ($export['default hook']) {
      if (!empty($export['api'])) {
        $info = ctools_plugin_api_include($export['api']['owner'], $export['api']['api'], $export['api']['minimum_version'], $export['api']['current_version']);
        $modules = array_keys($info);
      else {
        $modules = module_implements($export['default hook']);
      foreach ($modules as $module) {
        $function = $module . '_' . $export['default hook'];
        if (function_exists($function)) {
          foreach ((array) $function($export) as $name => $object) {
            // Record the module that provides this exportable.
            $object->export_module = $module;
            if (empty($export['api'])) {
              $cache[$table][$name] = $object;
            else {
              // If version checking is enabled, ensure that the object can be used.
              if (isset($object->api_version) && version_compare($object->api_version, $export['api']['minimum_version']) >= 0 && version_compare($object->api_version, $export['api']['current_version']) <= 0) {
                $cache[$table][$name] = $object;
      drupal_alter($export['default hook'], $cache[$table]);
  • ctools_export_load_object() can automatically join tables, if it finds the right information in the database schema defined in hook_schema().

    // Build the query
    $query = db_select($table, 't__0')->fields('t__0');
    $alias_count = 1;
    if (!empty($schema['join'])) {
      foreach ($schema['join'] as $join_key => $join) {
        if ($join_schema = drupal_get_schema($join['table'])) {
          $query->join($join['table'], 't__' . $alias_count, 't__0.' . $join['left_key'] . ' = ' . 't__' . $alias_count . '.' . $join['right_key']);
          $query->fields('t__' . $alias_count);
          // Allow joining tables to alter the query through a callback.
          if (isset($join['callback']) && function_exists($join['callback'])) {
            $join['callback']($query, $schema, $join_schema);
  • ctools_export_load_object() caches the result obtained, which means it could not execute any query at all.

  • ctools_export_load_object() uses many functions that are defined in the database schema. You can look at the comments contained in the code for ctools_export_get_schema() to see which functions are used.

As side note, a comment contained in ctools_export_get_schema() says (emphasis is mine):

Please do not call these directly, always use the ctools_export_crud_* wrappers to ensure that default implementations are honored.

| improve this answer | |

as i see it, you have to limit the $result array yourself, if the conditions are not limiting enough.

the difference, taken from the documentation:

This function will cache the objects, load subsidiary objects if necessary, check default objects in code and properly set them up. It will cache the results so that multiple calls to load the same objects will not cause problems.

It attempts to reduce, as much as possible, the number of queries involved.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.