| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660 | 
							- <?php
 
- /**
 
-  * @file
 
-  * CRUD functions for backup and migrate types (schedules, profiles etc.).
 
-  */
 
- define('BACKUP_MIGRATE_STORAGE_NONE', 0);
 
- define('BACKUP_MIGRATE_STORAGE_DB', 1);
 
- define('BACKUP_MIGRATE_STORAGE_OVERRIDEN', 2);
 
- /**
 
-  * Return a list of CRUD types in the module.
 
-  */
 
- function backup_migrate_crud_types() {
 
-   $out = array(
 
-     'destination' => array(
 
-       'class' => 'backup_migrate_destination',
 
-       'include' => 'destinations',
 
-     ),
 
-     'profile' => array(
 
-       'class' => 'backup_migrate_profile',
 
-       'include' => 'profiles',
 
-     ),
 
-     'schedule' => array(
 
-       'class' => 'backup_migrate_schedule',
 
-       'include' => 'schedules',
 
-     ),
 
-   );
 
-   return $out;
 
- }
 
- /**
 
-  * Get a generic object of the given type to be used for static-like functions.
 
-  *
 
-  * I'm not using actual static method calls since they don't work on variables prior to PHP 5.3.0
 
-  */
 
- function backup_migrate_crud_type_load($type) {
 
-   $out = NULL;
 
-   $types = backup_migrate_crud_types();
 
-   if (!empty($types[$type])) {
 
-     $info = $types[$type];
 
-     if ($info['include']) {
 
-       backup_migrate_include($info['include']);
 
-     }
 
-     $out = new $info['class'];
 
-   }
 
-   return $out;
 
- }
 
- /**
 
-  * Get the menu items handled by the CRUD code.
 
-  */
 
- function backup_migrate_crud_menu() {
 
-   $items = array();
 
-   foreach (backup_migrate_crud_types() as $type => $info) {
 
-     $type = backup_migrate_crud_type_load($type);
 
-     $items += (array)$type->get_menu_items();
 
-   }
 
-   return $items;
 
- }
 
- /**
 
-  * Page callback to create a new item.
 
-  */
 
- function backup_migrate_crud_ui_create() {
 
-   if ($type = backup_migrate_crud_type_load(arg(BACKUP_MIGRATE_MENU_DEPTH))) {
 
-     $item = $type->create(array());
 
-     return drupal_get_form('backup_migrate_crud_edit_form', $item);
 
-   }
 
- }
 
- /**
 
-  * Page callback to list all items.
 
-  */
 
- function backup_migrate_crud_ui_list() {
 
-   $out = '';
 
-   if ($type = backup_migrate_crud_type_load(arg(BACKUP_MIGRATE_MENU_DEPTH))) {
 
-     $out = $type->get_list();
 
-   }
 
-   return $out;
 
- }
 
- /**
 
-  * Page callback to edit an item.
 
-  */
 
- function backup_migrate_crud_ui_edit($item_id = NULL) {
 
-   if ($type = backup_migrate_crud_type_load(arg(BACKUP_MIGRATE_MENU_DEPTH))) {
 
-     if ($item_id && $item = $type->item($item_id)) {
 
-       return drupal_get_form('backup_migrate_crud_edit_form', $item);
 
-     }
 
-     drupal_goto(BACKUP_MIGRATE_MENU_PATH. '/' . arg(BACKUP_MIGRATE_MENU_DEPTH));
 
-   }
 
- }
 
- /**
 
-  * A form callback to edit an item.
 
-  */
 
- function backup_migrate_crud_edit_form($form, $form_state, $item) {
 
-   $form = $item->edit_form();
 
-   $form['item'] = array(
 
-     '#type' => 'value',
 
-     '#value' => $item,
 
-   );
 
-   $form['#validate'][]  = 'backup_migrate_crud_edit_form_validate';
 
-   $form['#submit'][]    = 'backup_migrate_crud_edit_form_submit';
 
-   return $form;
 
- }
 
- /**
 
-  * Validate the item edit form.
 
-  */
 
- function backup_migrate_crud_edit_form_validate($form, &$form_state) {
 
-   $item = $form_state['values']['item'];
 
-   $item->edit_form_validate($form, $form_state);
 
- }
 
- /**
 
-  * Submit the item edit form.
 
-  */
 
- function backup_migrate_crud_edit_form_submit($form, &$form_state) {
 
-   $item = $form_state['values']['item'];
 
-   $item->edit_form_submit($form, $form_state);
 
-   if (empty($form_state['redirect'])) {
 
-     $form_state['redirect'] = BACKUP_MIGRATE_MENU_PATH . '/'. $item->type_name;
 
-   }
 
- }
 
- /**
 
-  * Page callback to delete an item.
 
-  */
 
- function backup_migrate_crud_ui_delete($item_id = NULL) {
 
-   if ($type = backup_migrate_crud_type_load(arg(BACKUP_MIGRATE_MENU_DEPTH))) {
 
-     if ($item_id && $item = $type->item($item_id)) {
 
-       return drupal_get_form('backup_migrate_crud_delete_confirm_form', $item);
 
-     }
 
-     drupal_goto('admin/content/backup_migrate/'. arg(BACKUP_MIGRATE_MENU_DEPTH));
 
-   }
 
- }
 
- /**
 
-  * Ask confirmation for deletion of a item.
 
-  */
 
- function backup_migrate_crud_delete_confirm_form($form, &$form_state, $item) {
 
-   $form['item'] = array(
 
-     '#type' => 'value',
 
-     '#value' => $item,
 
-   );
 
-   $message = $item->delete_confirm_message();
 
-   return confirm_form($form, t('Are you sure?'), BACKUP_MIGRATE_MENU_PATH . '/'. $item->type_name, $message, t('Delete'), t('Cancel'));
 
- }
 
- /**
 
-  * Delete a item after confirmation.
 
-  */
 
- function backup_migrate_crud_delete_confirm_form_submit($form, &$form_state) {
 
-   if ($form_state['values']['confirm']) {
 
-     $item = $form_state['values']['item'];
 
-     $item->delete();
 
-   }
 
-   $form_state['redirect'] = BACKUP_MIGRATE_MENU_PATH . "/". $item->type_name;
 
- }
 
- /**
 
-  * Export an item.
 
-  */
 
- function backup_migrate_crud_ui_export($item_id = NULL) {
 
-   if ($type = backup_migrate_crud_type_load(arg(BACKUP_MIGRATE_MENU_DEPTH))) {
 
-     if ($item_id && $item = $type->item($item_id)) {
 
-       return drupal_get_form('backup_migrate_crud_export_form', $item->export());
 
-     }
 
-     drupal_goto(BACKUP_MIGRATE_MENU_PATH . '/' . arg(BACKUP_MIGRATE_MENU_DEPTH));
 
-   }
 
- }
 
- /**
 
-  * Ask confirmation for deletion of a destination.
 
-  */
 
- function backup_migrate_crud_export_form($form, &$form_state, $export) {
 
-   $form['export'] = array(
 
-     '#title' => t('Exported content'),
 
-     '#type' => 'textarea',
 
-     '#rows' => min(30, count(explode("\n", $export))),
 
-     '#value' => $export,
 
-   );
 
-   return $form;
 
- }
 
- /**
 
-  * Get all items of the given type.
 
-  */
 
- function backup_migrate_crud_get_items($type) {
 
-   if ($type = backup_migrate_crud_type_load($type)) {
 
-     return $type->all_items();
 
-   }
 
- }
 
- /**
 
-  * Get an item of the specified type.
 
-  */
 
- function backup_migrate_crud_get_item($type, $id) {
 
-   if ($type = backup_migrate_crud_type_load($type)) {
 
-     return $type->item($id);
 
-   }
 
- }
 
- /**
 
-  * Create a new item of the given type.
 
-  */
 
- function backup_migrate_crud_create_item($type, $params) {
 
-   if ($type = backup_migrate_crud_type_load($type)) {
 
-     return $type->create($params);
 
-   }
 
- }
 
- /**
 
-  * A base class for items which can be stored in the database, listed, edited, deleted etc.
 
-  */
 
- class backup_migrate_item {
 
-   var $db_table = '';
 
-   var $type_name = '';
 
-   var $storage = FALSE;
 
-   var $default_values = array();
 
-   var $singular = 'item';
 
-   var $plural = 'items';
 
-   /**
 
-    * Constructor, set the basic info pulled from the db or generated programatically.
 
-    */
 
-   function __construct($params = array()) {
 
-     $this->from_array((array)$params + (array)$this->get_default_values());
 
-   }
 
-   /**
 
-    * Get the default values for standard parameters.
 
-    */
 
-   function get_default_values() {
 
-     return $this->default_values;
 
-   }
 
-   /**
 
-    * Save the item to the database.
 
-    */  
 
-   function save() {
 
-     if (!$this->get_id()) {
 
-       $this->generate_id();
 
-     }
 
-     $data = $this->to_array();
 
-     drupal_write_record($this->db_table, $data, !empty($this->storage) ? $this->get_primary_key() : array());
 
-   }
 
-   /**
 
-    * Delete the item from the database.
 
-    */  
 
-   function delete() {
 
-     $keys = (array)$this->get_primary_key();
 
-     db_query('DELETE FROM {' . $this->db_table . '} WHERE ' . $keys[0] . ' = :id', array(':id' => $this->get_id()));
 
-   }
 
-   /**
 
-    * Load an existing item from an array.
 
-    */
 
-   function from_array($params) {
 
-     foreach ($params as $key => $value) {
 
-       if (method_exists($this, 'set_'. $key)) {
 
-         $this->{'set_'. $key}($value);
 
-       }
 
-       else {
 
-         $this->{$key} = $value;
 
-       }
 
-     }
 
-   }
 
-   /**
 
-    * Return as an array of values.
 
-    */
 
-   function to_array() {
 
-     $out = array();
 
-     // Return fields as specified in the schema.
 
-     $schema = $this->get_schema();
 
-     if (!empty($schema['fields']) && is_array($schema['fields'])) {
 
-       foreach ($schema['fields'] as $field => $info) {
 
-         $out[$field] = $this->get($field);
 
-       }
 
-     }
 
-     return $out;
 
-   }
 
-   /**
 
-    * Return as an exported array of values.
 
-    */
 
-   function export() {
 
-     $out = $this->to_array();
 
-     ob_start();
 
-     var_export($out);
 
-     $out = ob_get_contents();
 
-     ob_end_clean();
 
-     return $out;
 
-   }
 
-   /**
 
-    * Load an existing item from an database (serialized) array.
 
-    */
 
-   function load_row($data) {
 
-     $params = array();
 
-     $schema = $this->get_schema();
 
-     // Load fields as specified in the schema.
 
-     foreach ($schema['fields'] as $field => $info) {
 
-       $params[$field] = empty($info['serialize']) ? $data[$field] : unserialize($data[$field]);
 
-     }
 
-     $this->from_array($params);
 
-   }
 
-   /**
 
-    * Decode a loaded db row (unserialize necessary fields).
 
-    */
 
-   function decode_db_row($data) {
 
-     $params = array();
 
-     $schema = $this->get_schema();
 
-     // Load fields as specified in the schema.
 
-     foreach ($schema['fields'] as $field => $info) {
 
-       $params[$field] = empty($info['serialize']) ? $data[$field] : unserialize($data[$field]);
 
-     }
 
-     return $params;
 
-   }
 
-   /**
 
-    * Return the fields which must be serialized before saving to the db.
 
-    */
 
-   function get_serialized_fields() {
 
-     $out = array();
 
-     $schema = $this->get_schema();
 
-     foreach ($schema['fields'] as $field => $info) {
 
-       if (!empty($info['serialize'])) {
 
-         $out[] = $field;
 
-       }
 
-     }
 
-     return $out;
 
-   }
 
-   /**
 
-    * Get the primary key field title from the schema.
 
-    */
 
-   function get_primary_key() {
 
-     $schema = $this->get_schema();
 
-     return @$schema['primary key'];
 
-   }
 
-   /**
 
-    * Get the schema for the item type.
 
-    */
 
-   function get_schema() {
 
-     return drupal_get_schema($this->db_table);
 
-   }
 
-   /**
 
-    * Get the primary id for this item (if any is set).
 
-    *
 
-    * We only handle single field keys since that's all we need.
 
-    */
 
-   function get_id() {
 
-     $keys = (array)$this->get_primary_key();
 
-     return !empty($this->{$keys[0]}) ? (string)$this->{$keys[0]} : '';
 
-   }
 
-   /**
 
-    * Set the primary id for this item (if any is set).
 
-    */
 
-   function set_id($id) {
 
-     $keys = (array)$this->get_primary_key();
 
-     if (!empty($keys[0])) {
 
-       return $this->{$keys[0]} = $id;
 
-     }
 
-     return NULL;
 
-   }
 
-   /**
 
-    * Return a random (very very likely unique) string id for a new item.
 
-    */
 
-   function generate_id() {
 
-     $this->set_id(md5(uniqid(mt_rand(), true)));
 
-   }
 
-   /**
 
-    * Get the name of the item.
 
-    */
 
-   function get_name() {
 
-     return @$this->name;
 
-   }
 
-   /**
 
-    * Get the member with the given key.
 
-    */  
 
-   function get($key) {
 
-     if (method_exists($this, 'get_'. $key)) {
 
-       return $this->{'get_'. $key}();
 
-     }
 
-     return @$this->{$key};
 
-   }
 
-   /* UI Stuff */
 
-   /**
 
-    * Get the action links for a destination.
 
-    */
 
-   function get_action_links() {
 
-     $out = array('edit' => '', 'delete' => '');
 
-     $item_id = $this->get_id();
 
-     if (@$this->storage == BACKUP_MIGRATE_STORAGE_DB || @$this->storage == BACKUP_MIGRATE_STORAGE_OVERRIDEN) {
 
-       $out['edit'] = l(t("edit"), BACKUP_MIGRATE_MENU_PATH . "/$this->type_name/list/edit/$item_id");
 
-     }
 
-     else if (@$this->storage == BACKUP_MIGRATE_STORAGE_NONE) {
 
-       $out['edit'] = l(t("override"), BACKUP_MIGRATE_MENU_PATH . "/$this->type_name/list/edit/$item_id");
 
-     }
 
-     if (@$this->storage == BACKUP_MIGRATE_STORAGE_DB) {
 
-       $out['delete'] = l(t("delete"), BACKUP_MIGRATE_MENU_PATH . "/$this->type_name/list/delete/$item_id");
 
-     }
 
-     else if (@$this->storage == BACKUP_MIGRATE_STORAGE_OVERRIDEN) {
 
-       $out['delete'] = l(t("revert"), BACKUP_MIGRATE_MENU_PATH . "/$this->type_name/list/delete/$item_id");
 
-     }
 
-     // Export link disabled until we have an import function.
 
-     //$out['export'] = l(t("export"), BACKUP_MIGRATE_MENU_PATH . "/$this->type_name/list/export/$item_id");
 
-     return $out;
 
-   }
 
-   /**
 
-    * Get a table of all items of this type.
 
-    */  
 
-   function get_list() {
 
-     $items = $this->all_items();
 
-     $rows = array();
 
-     foreach ($items as $item) {
 
-       if ($row = $item->get_list_row()) {
 
-         $rows[] = $row;
 
-       }
 
-     }
 
-     if (count($rows)) {
 
-       $out = theme('table', array('header' => $this->get_list_header(), 'rows' => $rows));
 
-     }
 
-     else {
 
-       $out = t('There are no !items to display.', array('!items' => $this->plural));
 
-     }
 
-     return $out;
 
-   }
 
-   /**
 
-    * Get the columns needed to list the type.
 
-    */  
 
-   function get_list_column_info() {
 
-     return array(
 
-       'actions' => array('title' => t('Operations'), 'html' => TRUE),
 
-     );
 
-   }
 
-   /**
 
-    * Get header for a lost of this type.
 
-    */  
 
-   function get_list_header() {
 
-     $out = array();
 
-     foreach ($this->get_list_column_info() as $key => $col) {
 
-       $out[] = $col['title'];
 
-     }
 
-     return $out;
 
-   }
 
-   /**
 
-    * Get a row of data to be used in a list of items of this type.
 
-    */  
 
-   function get_list_row() {
 
-     $out = array();
 
-     foreach ($this->get_list_column_info() as $key => $col) {
 
-       $out[$key] = empty($col['html']) ? check_plain($this->get($key)) : $this->get($key);
 
-     }
 
-     return $out;
 
-   }
 
-   /**
 
-    * Get the rendered action links for a destination.
 
-    */
 
-   function get_actions() {
 
-     $links = $this->get_action_links();
 
-     return implode("   ", $links);
 
-   }
 
-   /**
 
-    * Get the edit form for the item.
 
-    */
 
-   function edit_form() {
 
-     $form = array();
 
-     $form['item'] = array(
 
-       '#type' => 'value',
 
-       '#value' => $this,
 
-     );
 
-     $form['id'] = array(
 
-       '#type' => 'value',
 
-       '#value' => $this->get_id(),
 
-     );
 
-     $form['actions'] = array('#prefix' => '<div class="container-inline">', '#suffix' => '</div>', '#weight' => 99);
 
-     $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save !type', array('!type' => t($this->singular))));
 
-     $form['actions']['cancel'] = array('#markup' => l(t('Cancel'), BACKUP_MIGRATE_MENU_PATH . '/destination'));
 
-     return $form;
 
-   }
 
-   /**
 
-    * Validate the edit form for the item.
 
-    */
 
-   function edit_form_validate($form, &$form_state) {
 
-   }
 
-   /**
 
-    * Submit the edit form for the item.
 
-    */
 
-   function edit_form_submit($form, &$form_state) {
 
-     $this->from_array($form_state['values']);
 
-     $this->save();
 
-     _backup_migrate_message('!type saved', array('!type' => t(ucwords($this->singular))));
 
-   }
 
-   /**
 
-    * Get the message to send to the user when confirming the deletion of the item.
 
-    */
 
-   function delete_confirm_message() {
 
-     return t('Are you sure you want to delete this !type?', array('!type' => t($item->singular)));
 
-   }
 
-   /* Static Functions */
 
-  
 
-    /**
 
-    * This function is not supposed to be called. It is just here to help the po extractor out.
 
-    */
 
-   function strings() {
 
-     // Help the pot extractor find these strings.
 
-     t('List !type');
 
-     t('Create !type');
 
-     t('Delete !type');
 
-     t('Edit !type');
 
-     t('Export !type');
 
-   }
 
-   /**
 
-    * Get the menu items for manipulating this type.
 
-    */
 
-   function get_menu_items() {
 
-     $type = $this->type_name;
 
-     $items[BACKUP_MIGRATE_MENU_PATH . '/' . $type] = array(
 
-       'title' => ucwords($this->plural),
 
-       'page callback' => 'backup_migrate_menu_callback',
 
-       'page arguments' => array('crud', 'backup_migrate_crud_ui_list', TRUE),
 
-       'access arguments' => array('administer backup and migrate'),
 
-       'weight' => 2,
 
-       'type' => MENU_LOCAL_TASK,
 
-     );
 
-     $items[BACKUP_MIGRATE_MENU_PATH . '/' . $type .'/list'] = array(
 
-       'title' => 'List !type',
 
-       'title arguments' => array('!type' => t(ucwords($this->plural))),
 
-       'weight' => 1,
 
-       'type' => MENU_DEFAULT_LOCAL_TASK,
 
-     );
 
-     $items[BACKUP_MIGRATE_MENU_PATH . '/' . $type .'/list/add'] = array(
 
-       'title' => 'Add !type',
 
-       'title arguments' => array('!type' => t(ucwords($this->singular))),
 
-       'page callback' => 'backup_migrate_menu_callback',
 
-       'page arguments' => array('crud', 'backup_migrate_crud_ui_create', TRUE),
 
-       'access arguments' => array('administer backup and migrate'),
 
-       'weight' => 2,
 
-       'type' => MENU_LOCAL_ACTION,
 
-     );
 
-     $items[BACKUP_MIGRATE_MENU_PATH . '/' . $type .'/list/delete'] = array(
 
-       'title' => 'Delete !type',
 
-       'title arguments' => array('!type' => t(ucwords($this->singular))),
 
-       'page callback' => 'backup_migrate_menu_callback',
 
-       'page arguments' => array('crud', 'backup_migrate_crud_ui_delete', TRUE),
 
-       'access arguments' => array('administer backup and migrate'),
 
-       'type' => MENU_CALLBACK,
 
-     );
 
-     $items[BACKUP_MIGRATE_MENU_PATH . '/' . $type .'/list/edit'] = array(
 
-       'title' => 'Edit !type',
 
-       'title arguments' => array('!type' => t(ucwords($this->singular))),
 
-       'page callback' => 'backup_migrate_menu_callback',
 
-       'page arguments' => array('crud', 'backup_migrate_crud_ui_edit', TRUE),
 
-       'access arguments' => array('administer backup and migrate'),
 
-       'type' => MENU_CALLBACK,
 
-     );
 
-     $items[BACKUP_MIGRATE_MENU_PATH . '/' . $type .'/list/export'] = array(
 
-       'title' => 'Export !type',
 
-       'title arguments' => array('!type' => t(ucwords($this->singular))),
 
-       'page callback' => 'backup_migrate_menu_callback',
 
-       'page arguments' => array('crud', 'backup_migrate_crud_ui_export', TRUE),
 
-       'access arguments' => array('administer backup and migrate'),
 
-       'type' => MENU_CALLBACK,
 
-     );
 
-     return $items;
 
-   }
 
-   /**
 
-    * Create a new items with the given input. Doesn't load the parameters, but could use them to determine what type to create.
 
-    */
 
-   function create($params = array()) {
 
-     $type = get_class($this);
 
-     return new $type($params);
 
-   }
 
-   /**
 
-    * Get all of the given items.
 
-    */
 
-   function all_items() {
 
-     static $cache = array();
 
-     // Allow other modules to declare destinations programatically.
 
-     $items = array();
 
-     foreach (module_implements($this->db_table) as $module) {
 
-       $fn = $module . '_' . $this->db_table;
 
-       $items += $fn();
 
-     }
 
-     // Get any items stored as a variable. This allows destinations to be defined in settings.php
 
-     $defaults = (array)variable_get($this->db_table .'_defaults', array());
 
-     foreach ($defaults as $info) {
 
-       if (is_array($info) && $item = $this->create($info)) {
 
-         $items[$item->get_id()] = $item;
 
-       }
 
-     }
 
-     // Get the items from the db.
 
-     $result = db_query("SELECT * FROM {{$this->db_table}}", array(), array('fetch' => PDO::FETCH_ASSOC));
 
-     foreach ($result as $info) {
 
-       $info = $this->decode_db_row($info);
 
-       if ($item = $this->create($info)) {
 
-         $item->storage = empty($items[$item->get_id()]) ? BACKUP_MIGRATE_STORAGE_DB : BACKUP_MIGRATE_STORAGE_OVERRIDEN;
 
-         $items[$item->get_id()] = $item;
 
-       }
 
-     }
 
-     // Allow other modules to alter the items. This should maybe be before the db override code above
 
-     // but then the filters are not able to set defaults for missing values. Other modules should just
 
-     // be careful not to overwrite the user's UI changes in an unexpected way.
 
-     drupal_alter($this->db_table, $items);
 
-     return $items;
 
-   }
 
-   /**
 
-    * A particular item.
 
-    */
 
-   function item($item_id) {
 
-     $items = $this->all_items();
 
-     return !empty($items[$item_id]) ? $items[$item_id] : NULL;
 
-   }
 
- }
 
 
  |