diff --git a/ctools.install b/ctools.install index ca77e96b8505f90dd6e442da7db8aeba47aea896..938ba8504c07e188ecf8e2a87804cc6c82950d96 100644 --- a/ctools.install +++ b/ctools.install @@ -38,11 +38,43 @@ function ctools_schema_2() { // update the 'name' field to be 128 bytes long: $schema['ctools_object_cache']['fields']['name']['length'] = 128; + // DO NOT MODIFY THIS TABLE -- this definition is used to create the table. + // Changes to this table must be made in schema_3 or higher. + $schema['ctools_css_cache'] = array( + 'description' => t('A special cache used to store CSS that must be non-volatile.'), + 'fields' => array( + 'cid' => array( + 'type' => 'varchar', + 'length' => '128', + 'description' => t('The CSS ID this cache object belongs to.'), + ), + 'filename' => array( + 'type' => 'varchar', + 'length' => '255', + 'description' => t('The filename this CSS is stored in.'), + ), + 'css' => array( + 'type' => 'text', + 'size' => 'big', + 'description' => t('CSS being stored.'), + 'serialize' => TRUE, + ), + 'filter' => array( + 'type' => 'int', + 'size' => 'tiny', + 'description' => t('Whether or not this CSS needs to be filtered.'), + ), + ), + 'primary key' => array('cid'), + ); + return $schema; } /** - * ctools' initial schema; separated for the purposes of updates. + * CTools' initial schema; separated for the purposes of updates. + * + * DO NOT MAKE CHANGES HERE. This schema version is locked. */ function ctools_schema_1() { $schema['ctools_object_cache'] = array( @@ -71,7 +103,7 @@ function ctools_schema_1() { 'description' => t('The time this cache was created or updated.'), ), 'data' => array( - 'type' => 'blob', + 'type' => 'text', 'size' => 'big', 'description' => t('Serialized data being stored.'), 'serialize' => TRUE, @@ -99,3 +131,16 @@ function ctools_update_6001() { return $ret; } + +/** + * Add the new css cache table. + */ +function ctools_update_6002() { + $ret = array(); + + // Schema 2 is locked and should not be changed. + $schema = ctools_schema_2(); + + db_create_table($ret, 'ctools_css_cache', $schema['ctools_css_cache']); + return $ret; +} diff --git a/includes/css.inc b/includes/css.inc index 25830176cd980ac7c7b2bb4085dc11fc7b8345e9..e1a4fccd6ea3884ac570d14ad56f4c4249618ed5 100644 --- a/includes/css.inc +++ b/includes/css.inc @@ -31,8 +31,85 @@ * a backup method of re-generating the CSS cache in case it is removed, so * that it is easy to force a re-cache by simply deleting the contents of the * directory. + * + * Finally, if for some reason your application cannot store the filename + * (which is true of Panels where the style can't force the display to + * resave unconditionally) you can use the ctools storage mechanism. You + * simply have to come up with a unique Id: + * + * @code + * $filename = ctools_css_store($id, $css, TRUE); + * @endcode + * + * Then later on: + * @code + * $filename = ctools_css_retrieve($id); + * drupal_add_css($filename); + * @endcode + * + * The CSS that was generated will be stored in the database, so even if the + * file was removed the cached CSS will be used. It is your module's + * responsibility to know when this CSS is outdated and needs to be + * changed. This storage is non-volatile and will never be removed unless + * you remove it: + * + * @code + * ctools_css_clear($id); + * @endcode */ +/** + * Store CSS with a given id and return the filename to use. + * + * This function associates a piece of CSS with an id, and stores the + * cached filename and the actual CSS for later use with + * ctools_css_retrieve. + */ +function ctools_css_store($id, $css, $filter = TRUE) { + $filename = db_result(db_query("SELECT filename FROM {ctools_css_cache} WHERE cid = '%s'", $id)); + if ($filename) { + file_delete($filename); + } + // Remove any previous records. + db_query("DELETE FROM {ctools_css_cache} WHERE cid = '%s'", $id); + + $filename = ctools_css_cache($css, $filter); + + db_query("INSERT INTO {ctools_css_cache} (cid, filename, css, filter) VALUES ('%s', '%s', '%s', %d)", $id, $filename, $css, $filter); + + return $filename; +} + +/** + * Retrieve a filename associated with an id of previously cached CSS. + * + * This will ensure the file still exists and, if not, create it. + */ +function ctools_css_retrieve($id) { + $cache = db_fetch_object(db_query("SELECT * FROM {ctools_css_cache} WHERE cid = '%s'", $id)); + if (!$cache) { + return; + } + + if (!file_exists($cache->filename)) { + $filename = ctools_css_cache($cache->css, $cache->filter); + if ($filename != $cache->filename) { + db_query("UPDATE {ctools_css_cache} SET filename = '%s' WHERE cid = '%s'", $filename, $id); + $cache->filename = $filename; + } + } + + return $cache->filename; +} + +/** + * Remove stored CSS and any associated file. + */ +function ctools_css_clear($id) { + db_query("DELETE FROM {ctools_css_cache} WHERE cid = '%s'", $id); +} + + /** * Write a chunk of CSS to a temporary cache file and return the file name. * @@ -50,6 +127,9 @@ * @param $filter * If TRUE the css will be filtered. If FALSE the text will be cached * as-is. + * + * @return $filename + * The filename the CSS will be cached in. */ function ctools_css_cache($css, $filter = TRUE) { if ($filter) {