/**
  * Deletes one or more object types from the system and cache
  *
  * @version 1.0
  * @since 1.0
  * @param int/array $type_id | Single type_id as int. Multiple type_ids as array of ints.
  * @return bool | Exception on failure. True on success. False on nonexistent.
  */
 public function dropType($type_id)
 {
     $db = new FOX_db();
     if (!is_array($type_id)) {
         $type_id = array($type_id);
     }
     // Fetch the type_id, type_slug, and module_id for each object type to be
     // deleted. This info is necessary to remove each type's cache entries.
     $args = array(array("col" => "type_id", "op" => "=", "val" => $type_id));
     $columns = array("mode" => "include", "col" => array("type_id", "type_slug", "module_id"));
     $ctrl = array("format" => "array_key_array", "key_col" => array("type_id"));
     try {
         $del_types = $db->runSelectQuery($this->_struct(), $args, $columns, $ctrl);
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 1, 'text' => "Error reading from database", 'data' => array('args' => $args, 'columns' => $columns, 'ctrl' => $ctrl), 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
     }
     if ($del_types) {
         // The if($del_types) prevents foreach() crashing if
         // none of the object types specified actually exist in the db
         // Lock and load the cache
         // ==========================
         try {
             $cache_image = self::lockCache();
         } catch (FOX_exception $child) {
             throw new FOX_exception(array('numeric' => 2, 'text' => "Error locking cache", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
         }
         // Run the update
         // ==========================
         try {
             $rows_changed = $db->runDeleteQueryCol($this->_struct(), "type_id", "=", $type_id);
         } catch (FOX_exception $child) {
             throw new FOX_exception(array('numeric' => 3, 'text' => "Error writing to database", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
         }
         // Rebuild the cache image
         // ==========================
         foreach ($del_types as $type => $data) {
             unset($cache_image["slug_to_type_id"][$data["module_id"]][$data["type_slug"]]);
             unset($cache_image["module_id_types"][$data["module_id"]]);
             unset($cache_image["keys"][$type]);
         }
         unset($type, $data);
         // Update the persistent cache, releasing our lock
         // ===========================================================
         try {
             self::writeCache($cache_image);
         } catch (FOX_exception $child) {
             throw new FOX_exception(array('numeric' => 4, 'text' => "Cache write error", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
         }
         // Overwrite the class cache
         $this->cache = $cache_image;
     }
     return (bool) $rows_changed;
 }
 /**
  * Deletes one or more modules
  *
  * @version 1.0
  * @since 1.0
  * @param int/array $module_id | Single module_id as int. Multiple module_ids as array of ints.
  * @return int | Exception on failure. Number of affected db rows on success.
  */
 public function dropModule($module_id)
 {
     $db = new FOX_db();
     if (!is_array($module_id)) {
         $module_id = array($module_id);
     }
     // Fetch the level_id, level_slug, and type_id for each level_id owned
     // by the module_id to be deleted.
     // **This info is necessary to remove each level's cache entries**
     // ========================================================================
     $args = array(array("col" => "module_id", "op" => "=", "val" => $module_id));
     $columns = array("mode" => "include", "col" => array("level_id", "level_slug", "type_id"));
     $ctrl = array("format" => "array_key_array", "key_col" => array("level_id"));
     try {
         $del_types = $db->runSelectQuery($this->_struct(), $args, $columns, $ctrl);
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 1, 'text' => "Error reading from database", 'data' => array('args' => $args, 'columns' => $columns, 'ctrl' => $ctrl), 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
     }
     if (!$del_types) {
         // No items exist in the db
         return 0;
     }
     // Lock the cache
     // ==========================
     try {
         $cache_image = self::lockCache();
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 2, 'text' => "Cache read error", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
     }
     // Clear items from the db
     // ==========================
     try {
         $rows_changed = $db->runDeleteQueryCol($this->_struct(), "module_id", "=", $module_id);
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 3, 'text' => "Error while deleting from database", 'data' => array("module_id" => $module_id), 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
     }
     // Rebuild the cache image
     // ==========================
     foreach ($del_types as $level => $data) {
         unset($cache_image["slug_to_level_id"][$data["module_id"]][$data["type_id"]][$data["level_slug"]]);
         unset($cache_image["type_levels"][$data["type_id"]]);
         unset($cache_image["keys"][$level]);
     }
     unset($level, $data);
     // Update the persistent cache, releasing our lock
     // ===========================================================
     try {
         self::writeCache($cache_image);
     } catch (FOX_exception $child) {
         throw new FOX_exception(array('numeric' => 4, 'text' => "Cache write error", 'file' => __FILE__, 'class' => __CLASS__, 'function' => __FUNCTION__, 'line' => __LINE__, 'child' => $child));
     }
     // Overwrite the class cache
     $this->cache = $cache_image;
     return (int) $rows_changed;
 }