Releases for sf 1.4
| Version |
License |
API |
Released |
|
4.4.0stable
|
MIT license |
4.1.0stable
|
30/12/2012 |
|
4.3.0stable
|
MIT license |
4.0.2stable
|
16/12/2012 |
|
4.2.2stable
|
MIT license |
4.0.1stable
|
05/02/2012 |
|
4.2.1stable
|
MIT license |
4.0.1stable
|
06/12/2011 |
|
4.2.0stable
|
MIT license |
4.0.1stable
|
06/12/2011 |
|
4.1.1stable
|
MIT license |
4.0.1stable
|
20/10/2011 |
|
4.1.0stable
|
MIT |
4.0.1stable
|
03/09/2011 |
|
4.0.0stable
|
MIT |
4.0.0stable
|
10/04/2011 |
|
3.1.0stable
|
MIT |
3.1.0stable
|
20/02/2011 |
|
3.0.0stable
|
MIT |
3.0.0stable
|
12/02/2011 |
|
2.1.3stable
|
MIT |
2.2.1stable
|
03/02/2011 |
|
2.1.2stable
|
MIT |
2.2.0stable
|
01/02/2011 |
|
2.1.1stable
|
MIT |
2.2.0stable
|
24/01/2011 |
|
2.1.0stable
|
MIT |
2.2.0stable
|
24/12/2010 |
|
2.0.2stable
|
MIT |
2.1.1stable
|
20/11/2010 |
|
2.0.1stable
|
MIT |
2.1.0stable
|
22/08/2010 |
|
2.0.0stable
|
MIT |
2.1.0stable
|
22/08/2010 |
|
1.5.0stable
|
MIT |
2.0.0stable
|
28/06/2010 |
|
1.4.4stable
|
MIT |
1.1.1stable
|
09/06/2010 |
|
1.4.3stable
|
MIT |
1.1.1stable
|
26/05/2010 |
|
1.4.2stable
|
MIT |
1.1.1stable
|
24/05/2010 |
|
1.3.1stable
|
MIT |
1.1.0stable
|
17/04/2010 |
|
1.3.0stable
|
MIT |
1.1.0stable
|
17/04/2010 |
|
1.2.0stable
|
MIT |
1.0.1stable
|
11/01/2010 |
|
1.1.0stable
|
MIT |
1.0.1stable
|
20/12/2009 |
|
1.0.1stable
|
MIT |
1.0.0stable
|
18/12/2009 |
|
1.0.0stable
|
MIT |
1.0.0stable
|
16/12/2009 |
|
0.1.0beta
|
MIT |
0.1.0alpha
|
16/12/2009 |
Releases for sf 1.3
| Version |
License |
API |
Released |
|
4.4.0stable
|
MIT license |
4.1.0stable
|
30/12/2012 |
|
4.3.0stable
|
MIT license |
4.0.2stable
|
16/12/2012 |
|
4.2.2stable
|
MIT license |
4.0.1stable
|
05/02/2012 |
|
4.2.1stable
|
MIT license |
4.0.1stable
|
06/12/2011 |
|
4.2.0stable
|
MIT license |
4.0.1stable
|
06/12/2011 |
|
4.1.1stable
|
MIT license |
4.0.1stable
|
20/10/2011 |
|
4.1.0stable
|
MIT |
4.0.1stable
|
03/09/2011 |
|
4.0.0stable
|
MIT |
4.0.0stable
|
10/04/2011 |
|
3.1.0stable
|
MIT |
3.1.0stable
|
20/02/2011 |
|
3.0.0stable
|
MIT |
3.0.0stable
|
12/02/2011 |
|
2.1.3stable
|
MIT |
2.2.1stable
|
03/02/2011 |
|
2.1.2stable
|
MIT |
2.2.0stable
|
01/02/2011 |
|
2.1.1stable
|
MIT |
2.2.0stable
|
24/01/2011 |
|
2.1.0stable
|
MIT |
2.2.0stable
|
24/12/2010 |
|
2.0.2stable
|
MIT |
2.1.1stable
|
20/11/2010 |
|
2.0.1stable
|
MIT |
2.1.0stable
|
22/08/2010 |
|
2.0.0stable
|
MIT |
2.1.0stable
|
22/08/2010 |
|
1.5.0stable
|
MIT |
2.0.0stable
|
28/06/2010 |
|
1.4.4stable
|
MIT |
1.1.1stable
|
09/06/2010 |
|
1.4.3stable
|
MIT |
1.1.1stable
|
26/05/2010 |
|
1.4.2stable
|
MIT |
1.1.1stable
|
24/05/2010 |
|
1.3.1stable
|
MIT |
1.1.0stable
|
17/04/2010 |
|
1.3.0stable
|
MIT |
1.1.0stable
|
17/04/2010 |
|
1.2.0stable
|
MIT |
1.0.1stable
|
11/01/2010 |
|
1.1.0stable
|
MIT |
1.0.1stable
|
20/12/2009 |
|
1.0.1stable
|
MIT |
1.0.0stable
|
18/12/2009 |
|
1.0.0stable
|
MIT |
1.0.0stable
|
16/12/2009 |
|
0.1.0beta
|
MIT |
0.1.0alpha
|
16/12/2009 |
Changelog for release 1.1.0 - 20/12/2009
- ilya: update README
- ilya: tag name could be based on many columns
- ilya: checked opportunity to work with I18n behavior
Other releases
Release 4.4.0 - 30/12/2012
- [Handling cache tags rollback/commit inside Doctrine transactions GH-18
- [added] New two app.yml settings to customize collection and object tag names
- [updated] API partially changed
- [updated] README
- [fixed] Along the way fixed more than one minor bug and IMHO one major bug
- [fixed] Almost all tests were fixed because they used Doctrine transaction to keep test fixtures unchanged
Release 4.3.0 - 16/12/2012
- [fixed] When
SoftDelete installed after Cachetaggable (actAs section), preDqlDelete forces to update already softly deleted records (thanks to Paul Moore)
- [added] New approach to append custom parameter(-s) to the cache key only for authenticated users
- [added] more coverage tests
Release 4.2.2 - 05/02/2012
- ilya: [fixed] Minor fix to obtainCollectionVersion (thanks paulkmoore)
- ilya: [updated] Renewed copyright years
Release 4.2.1 - 06/12/2011
- ilya: [updated] README removed unnecessary block
Release 4.2.0 - 06/12/2011
- ilya: [fixed] Attaching unsaved record to cache block cause the error
- ilya: [added] Added custom HTTP request class and custom filter to differ cache blocks between authenticated users
- ilya: [updated] README - added notes how to keep different cache to each authenticated user
Release 4.1.1 - 20/10/2011
- ilya: [Test environment files removed from package. All tests available only from GIT repository. GH-15
- ilya: [updated] README
Release 4.1.0 - 03/09/2011
- ilya: [NestedSet behavior support GH-14
- ilya: [updated] README
Release 4.0.0 - 10/04/2011
- ilya: [added] Option invalidateCollectionVersionByChangingColumns to setup Cachetaggable behavior
- ilya: [added] Cascading tag deletion through the model relations
- ilya: [added] Doctrine_Record::link and Doctrine_Record::unlink updates refTable's tags
- ilya: [updated] README
- ilya: [updated] new API
- ilya: [fixed] skipOnChange did not work properly
Release 3.1.0 - 20/02/2011
- ilya: [added] New option for behavior setup invalidateCollectionVersionOnUpdate
- ilya: [changed] Doctrine_Record::getTags() by default return only one self tag (thanks Roman Grigorov)
- ilya: [changed] getTags() by default returns all tags recursively and getTags(false) NOT recursively
- ilya: [fixed] Removed custom object for storing data and tags (CacheMetadata), this kills PHP apc_bin_dump() functionality.
- ilya: [fixed] Doctrine_Record::replace() now works fine, when record is replaced.
- ilya: [fixed] I18n behavior never invalidates object tags on updating i18n-table columns. (thanks Yury Maksimenko)
- ilya: [fixed] Sometimes object version stays unchanged in database (as expected), but invalidated in backend.
Release 3.0.0 - 12/02/2011
- ilya: [added] Updating objects now does not invalidates collections tags. To invalidate collection tag you need to delete or add new object of specific collection. (thanks Roman Grigorov)
- ilya: [fixed] Calling an unknown method from actions with a disabled cache does not throws the Exception
- ilya: [changed] Some Cachetaggable behaviors method names renamed due to Doctrine possible conflicts.
- ilya: [added] new additional tests
- ilya: [updated] README
Release 2.1.3 - 03/02/2011
- ilya: [fixed] By using doctrine migration, default column "object_version" contains NULL value (throws an exception on frontend)
Release 2.1.2 - 01/02/2011
- ilya: [updated] README (added i18n limitation)
- ilya: [fixed] Conclicts with SoftDelete in "preDqlDelete" + tests
Release 2.1.1 - 24/01/2011
- ilya: [updated] README
- ilya: [fixed] Doctrine_Template_Listener_Cachetaggable::preDqlUpdate + tests
- ilya: [fixed] sfWebDebugLogInfo contains extra-incorrect message, sent by sfViewCacheTagManager
Release 2.1.0 - 24/12/2010
- ilya: [updated] README
- ilya: [added] "skipOnChange" directive (schema.yml)
- ilya: [fixed] sfFileTaggingCache::getCacheKeys
- ilya: [added] optimized sf*TaggingCache::getMany
- ilya: [removed] app_sfcachetaggingplugin_template_* directives
- ilya: [changed] Renamed getObjectVersion to obtainObjectVersion, setObjectVersion to assignObjectVersion
Release 2.0.2 - 20/11/2010
- ilya: [updated] README
- ilya: [fixed] SoftDelete behavior conflict
Release 2.0.1 - 22/08/2010
Release 2.0.0 - 22/08/2010
- ilya: [added] Storing doctrine objects/collections by using build-in Doctrine mechanism
- ilya: [added] Ability to specify differenct cache back-ends for data and tags cache
- ilya: [added] Easy customized logger
- ilya: [added] By switching cache off or migration to build-in cache manager will no
affect code functionality
- ilya: [added] cache info block (blue/yellow box) now display linked to cache
tags with its version
- ilya: [added] SQLite via PDO Cache backend
- ilya: [added] new tests - code coverage: 98%;
Release 1.5.0 - 28/06/2010
- ilya: [added] all tags now stored in symfony build in holder
- ilya: [added] more coverage tests (91%)
- ilya: [removed] all deprecated methods
- ilya: [added] added listener on sfComponents to enable short-handed methods to set tags from action or component (see README)
Release 1.4.4 - 09/06/2010
- ilya: [fixed] resolved conflict with SoftDelete build-in Doctrine behavior
- ilya: [fixed] by saving not modified object, version was updated
- ilya: [added] new unit/functional tests
Release 1.4.3 - 26/05/2010
- ilya: [fixed] in case sfViewCacheTagManager is enabled and some model (schema.yml) has no "actAs: Cachetaggable" - throws uncatched exception
Release 1.4.2 - 24/05/2010
- ilya: [fixed] confused lifetime logic on tags/locks/data
- ilya: [fixed] sf*Cache::has() does not checking tags versions
- ilya: [added] new section in README file: Adding tags to the action with layout
- ilya: [added] new section in README file: Adding tags to the action without layout
- ilya: [updated] updated tag/locks lifetime setup on 6 step section 1 (6.1)
- ilya: [added] new functional tests on action and page tagging
- ilya: [fixed] microtime_precision should be in range 0…6
- mcnilz: [added] ability to add tags to the page with layout
- ilya: [added] ability to add tags to the specific action without layout (inspired by mcnilz)
- ilya: [added] more unit/functional tests, code coverage at 84%
- ilya: [deleted] removed README.markdown (only for github.com)
- ilya: [added] ability to select log format (short|extended)
Release 1.3.1 - 17/04/2010
- ilya: [added] ability to select log format (short|extended)
Release 1.3.0 - 17/04/2010
- ilya: [updated] README
- ilya: [fixed] empty collections was never updated
- ilya: [added] support to add tags to Doctrine_Collection_Cachetaggable and Doctrine_Record using any compatible types (array|ArrayAccess|Doctrine_Collection_Cachetaggable|Doctrine_Record)
- ilya: [added] new tests
Release 1.2.0 - 11/01/2010
- ilya: updated README
- ilya: dql queries (update/delete) also updates version column and thier tags
Release 1.1.0 - 20/12/2009
- ilya: update README
- ilya: tag name could be based on many columns
- ilya: checked opportunity to work with I18n behavior
Release 1.0.1 - 18/12/2009
- ilya: correcting lexical/grammatical mistakes
Release 1.0.0 - 16/12/2009
- ilya: updated setup manual in README, added Limitation block.
Release 0.1.0 - 16/12/2009
sfCacheTaggingPlugin
The sfCacheTaggingPlugin is a Symfony plugin, that helps to store cache with
associated tags and to keep cache content up-to-date based by incrementing tag
version when cache objects are edited/removed or new objects are ready to be a
part of cache content.
Description
Tagging a cache is a concept that was invented in the same time by many developers
(Andrey Smirnoff, Dmitryj Koteroff
and, perhaps, by somebody else)
This software was developed inspired by Andrey Smirnoff`s theoretical work
"Cache tagging with Memcached (in Russian)".
Some ideas are implemented in the real world (i.e. tag versions based on datetime
and microtime, cache hit/set logging, cache locking) and part of them
are not (atomic counter).
Repository
Installation
Install the plugin
$ ./symfony plugin:install sfCacheTaggingPlugin
Setup
Check sfCacheTaggingPlugin plugin is enabled (/config/ProjectConfiguration.class.php)
<?php
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
# … other plugins
$this->enablePlugins('sfCacheTaggingPlugin');
}
}
Create a new file /config/factories.yml or edit each application`s level
/apps/%app%/config/factories.yml file
Cache tagging works for you each time you save/update/delete Doctrine record
or fetch them from DB. So you should enable caching (sf_cache: true) in
all applications you work with. I recommend you to create default factories.yml
for all applications you have by creating a file /config/factories.yml
(bellow that will be this file content). Symfony will check this file and load
it as a default factories.yml configuration to all applications you have in the project.
This is /config/factories.yml content (you can copy&paste this code
into your brand new created file) or merge this config with each application`s
factories.yml (applications, where you need the data to be fetched/written from/to cache)
Example: file /config/factories.yml
all:
view_cache:
class: sfTagCache
param:
logging: true # logging is enabled ("false" to disable)
cache:
class: sfMemcacheCache # Content will be stored in Memcache
# Here you can switch to any other backend
# (see Restrictions block for more info)
param:
persistent: true
storeCacheInfo: false
host: localhost
port: 11211
timeout: 5
lifetime: 86400
locker:
class: sfAPCCache # Locks will be stored in APC
# Here you can switch to any other backend sf*Cache
# (see Restrictions block for more info)
param: {}
view_cache_manager:
class: sfViewCacheTagManager # Extended sfViewCacheManager class
param:
cache_key_use_vary_headers: true
cache_key_use_host_name: true
Easter eggs: If you remove "all_view_cache_param_locker" section,
locker will be the same as section "all_view_cache_param_cache".
Restrictions: Backend`s class should be inheritable from sfCache
class. Also, it should support the caching of objects and/or arrays.
Bonus: In additional to this plugin comes sfFileTaggingCache
and sfSQLiteTaggingCache which are ready to use as backend class.
This classes already have serialization/unserialization support.
Edit Symfony`s predefined application`s level factories.yml files
If you have edited each application`s level factories.yml file in
2nd step - go to 4th step.
In each application you want to use cache tagging please remove
"all_view_cache_manager" section (you have already configured it
in global /config/factories.yml file).
Add "Cachetaggable" behavior to each model, which you want to be a part of cache content.
Exmaple: file /config/doctrine/schema.yml
BlogPost:
tableName: blog_post
actAs:
Cachetaggable: ~
#Cachetaggable:
# uniqueColumn: id # you can customize unique column name (default is "id")
# versionColumn: object_version # you can customize column name to store versions (default is "object_version")
# uniqueKeyFormat: '%d' # you can customize key format (default is "%d")
#
# # if you have more then 1 unique column, you could pass all of them
# # as array (tag name will be based on them)
#
# uniqueColumn: [id, is_enabled]
# uniqueKeyFormat: '%d-%02b' # the order of unique columns
# # matches the "uniqueKeyFormat" template variables order
columns:
id:
type: integer
primary: true
autoincrement: true
unsigned: true
title: string(255)
relations:
BlogPostComment:
class: BlogPostComment
type: many
local: id
foreign: blog_post_id
BlogPostComment:
tableName: blog_post_comment
actAs:
Cachetaggable: ~
columns:
id:
type: integer
primary: true
autoincrement: true
unsigned: true
blog_post_id:
type: integer
unsigned: true
notnull: false
author: string(20)
message: string(255)
indexes:
blog_post_id: { fields: [blog_post_id] }
relations:
BlogPost:
onUpdate: CASCADE
onDelete: CASCADE
Enable cache in settings.yml and add additionals helpers to standart_helpers
To setup cache, often, used a separate environment named "cache",
but in the same way you can do it in any other environments which you have.
prod:
.settings:
cache: true
cache:
.settings:
cache: true
all:
.settings:
cache: false
Add helpers to the frontend application
all:
.settings:
standard_helpers:
- Partial # symfony build in helper (mandatory)
- CacheTag # sfCacheTaggingPlugin helper (mandatory)
- PartialTag # sfCacheTaggingPlugin helper (mandatory)
Customize sfCacheTaggingPlugin in the /config/app.yml
all:
sfcachetaggingplugin:
template_lock: "lock_%s" # name for locks
template_tag: "tag_%s" # name for tags
microtime_precision: 5 # version precision (0, or positive number)
# (0 - without micro time, version will be 10 digits length)
# (5 - with micro time part, version will be 15 digits length)
lock_lifetime: 2 # seconds to keep lock, if failed to unlock after locking it
Using
Native use:
# Somewhere in the frontend, you need to print out latest posts
$posts = Doctrine::getTable('BlogPost')
->createQuery()
->orderBy('id DESC')
->limit(3)
->execute();
# write data to the cache ($posts is instance of the Doctrine_Collection_Cachetaggable)
$tagger->set('my_posts', $posts, 86400, $posts->getTags());
# fetch latest post to edit it
$post = posts->getFirst();
# prints something like "126070596212512"
print $post->getObjectVersion();
$post->setTitle('How to use sfCacheTaggingPlugin');
# save and update/upgrade version of the tag
$post->save();
# prints something like "126072290862231" (new version of the tag)
print $post->getObjectVersion();
# will return null
# $post object was updated, so, all $posts in cache "my_posts†is invalidated automatically)
if ($data = $tagger->get('my_posts'))
{
# this block will not be executed
}
# save new data to the cache
$tagger->set('my_posts', $posts, null, $posts->getTags());
# will return data (objects are fresh)
if ($data = $tagger->get('my_posts'))
{
# this code block will be executed
}
$post = new BlogPost();
$post->setTitle('New post should be in inserted to the cache results');
$post->save();
# will return null, because 'my_posts' cache knows that it contains BlogPost objects
# and listens on new objects with same type that are newer
if ($data = $tagger->get('my_posts'))
{
# this block will not be executed
}
$posts = Doctrine::getTable('BlogPost')
->createQuery()
->orderBy('id DESC')
->limit(3)
->execute();
$tagger->set('my_posts', $posts, null, $posts->getTags());
# will return data
if ($data = $tagger->get('my_posts'))
{
# this block will be executed
}
non-Doctrine use:
indexSuccess.php
<fieldset>
<legend>Daylight</legend>
<?php if (! cache_tag('daylight_content')) { ?>
<h1>Text to cache No-<?php rand(1, 1000000) ?></h1>
Text text text text text text text text text text text text text.
<?php cache_tag_save(array('sun' => time(), 'moon' => time())); ?>
<?php } ?>
</fieldset>
code.php
# when you want to update Daylight content
$this->getContext()->getViewCacheManager()->getTagger()->setTag('moon', time(), 86400);
Using with partials:
<fieldset>
<legend>Partial</legend>
<?php if (! cache_tag('latest-blog-posts-index-on-page')) { ?>
<?php foreach ($posts as $post) { ?>
<?php include_partial('posts/one_post', array('post' => $post) ?>
<?php } ?>
<?php cache_tag_save($posts->getTags()); ?>
<?php } ?>
</fieldset>
Using with components (simple):
indexSuccess.php
<fieldset>
<legend>Component</legend>
<?php if (! cache_tag('latest-blog-posts-index-on-page')) { ?>
<?php include_component_tag('posts', 'listOfPosts') ?>
<?php cache_tag_save(); ?>
<?php } ?>
</fieldset>
components.class.php
<?php
class postsComponents extends sfComponents
{
public function executeListOfPosts($request)
{
$posts = Doctrine::getTable('BlogPost')
->createQuery('bp')
->select('bp.*')
->orderBy('bp.id DESC')
->limit(3)
->execute();
$this->getContext()->getViewCacheManager()->setTags($posts->getTags());
$this->posts = $posts;
}
}
Using with components (complex - Combining posts with comments)
components.class.php
<fieldset>
<legend>Component (posts and comments)</legend>
<?php if (! cache_tag('posts_and_comments')) { ?>
<?php include_component_tag('post', 'listOfPostsAndComments') ?>
<?php cache_tag_save(); ?>
<?php } ?>
</fieldset>
components.class.php
<?php
class postsComponents extends sfComponents
{
public function executeListOfPostsAndComments($request)
{
$posts = Doctrine::getTable('BlogPost')
->createQuery('bp')
->addSelect('bp.*, bpc.*')
->innerJoin('bp.BlogPostComments bpc')
->orderBy('bp.id DESC')
->limit(3)
->execute();
foreach ($posts as $post)
{
# 1st variant (shorter)
# our cache should be updated if one of comment will be edited/deleted
# therefore, we are collecting comment's tags
$posts->addTags($post->getBlogPostComment()->getTags());
# or shorter
# $posts->addTags($post->getBlogPostComment());
}
$this->getContext()->getViewCacheManager()->setTags($posts->getTags());
$this->posts = $posts;
}
}
Limitations / Peculiarities
Do not use Doctrine::getTable('BlogPost')->delete()->where('id > ?', 10)->execute();
Object deletion should be performed using Doctrine_Record::delete() method.
This is necessary to remove object tags when object is fizicaly removed.
Otherwise your cache will be not expired.
In case, when model has translations (I18n behavior), it is enough to add
"actAs: Cachetaggable" to the model. I18n behavior should be free from Cachetaggable
behavior.
Unit test
- 400 of 400 successfully completed
Every combination is tested (data backend / locker backend) of listed below:
- sfMemcacheCache
- sfAPCCache
- sfSQLiteTaggingCache - file (extended from sfSQLiteCache)
- sfSQLiteTaggingCache - memory (extended from sfSQLiteCache)
- sfFileTaggingCache (extended from sfFilecache)
Partialy tested listed below backends. If anyone could help me to run functional tests
for this backends, I will be thankful to you:
- sfXCacheCache
- sfEAcceleratorCache
Contacts
- @: Ilya Sabelnikov
<fruit dot dev at gmail dot com>
- IRC:
- server: irc.freenode.net
- channel: #symfony
- username: fruit
- skype: ilya_roll