Frederik Holljen wrote:
> Hi,
>
> Here is a proposal for the solution of issue 8323. Alexandru, this mail is
> mostly meant for you as you know the inner workings of ezcMail as well as I
> do (or better). All opinions are welcome though..
>
> The typical case when caching is needed for generating mail is when you have
> a
> mail that is mostly similar but that changes one or two parts for each mail
> sent out.
>
> Case
> -------
> - Write some multipart mail with attachments. All the mail are the same
> except
> for the text part where you substitute th
> e "Dear mr. XXX" with the correct name from the database.
> - Of course all mail should have a unique message id's.
The headers are also different, like To, Subject, etc.
>
> Requirements
> -------------------
> - backwards compatible
> - should preferably add caching on a low level so it doesn't need to be
> implemented in each part
>
> Discussion
> --------------
> Basically there are two approaches to solve this problem:
> 1. The user tells us which parts of the mail can not be cached
> + Caching can be implemented on the right MIME level since we know what can
> be
> cached and what we can't cache when we generate.
> - The user needs to be active in using the cache
> 2. A "dirty flag" system where each part knows if it is changed or not and we
> can use cached parts of the mail based on that.
> + No user input needed
> - All parts must implement functionality to make sure that they are
> marked "dirty" when someone changes it.
> - All MIME parts must always cache leading to a lot of overhead (which is
> what
> we want to avoid with the cache system in the first place)
>
> The overhead in option 2 is not acceptable (I think) so the rest of this
> discussion is for option 1.
I also like option 1 better.
> Observations:
> - Leaf MIME nodes are the the ones that the user should set if they are
> cacheable or not.
> - Multiparts can not know if the are cacheable or not unless they ask their
> subparts if they are cacheable.
>
> Proposal
> -----------
> The proposal uses two new variables in ezcMailPart to control caching:
> isCacheable - Set by the user to indicate to the caching system if the part
> can be cached or not. By default this is set to true which means the part
> will not change between each mail generated.
> doCache - This property is set by multiparts and indicates to the part if it
> should actually perform caching. This is used to make sure that no
> unnecessary caching is performed.
>
> Pseudo Code
> ----------------
> /**
> * property-write bool $isCacheable If this part can be cached.
> * True for all parts by default. The property does not do
> * anything for multiparts
> * property bool $doCache set by parent MIME object (if any) to indicate if
> this
> * object actually needs to cache or not. True by default.
> */
> class ezcMailPart
> {
> public function isCacheable()
> {
> return $this->isCacheable();
> }
>
> public function generate()
> {
> if( $this->doCache && cache_exists )
> {
> return cache;
> }
> else
> {
> // call generateHeaders() and generateBody()
> // store cache
> if( $this->doCache )
> {
> // store cache here...
> }
> }
> }
> }
>
>
> For multiparts the situation is slightly different. Multiparts themselves
> must
> check if the children are cacheable or not.
>
> ezcMailMultiPart
> {
> public function isCachable()
> {
> foreach( $this->parts as $part )
> {
> if( $this->part->isCacheable() == false )
> {
> return false;
> }
> }
> return true;
> }
>
> public generate()
> {
> foreach( $this->parts as $part )
> {
> if( $this->isCacheable() == true )
> {
> $part->doCache = false;
> $part->generate();
> }
> }
> }
> }
The last generate() method seems a little wrong. I think it sould not
call $this->isCacheable() for each part as isCacheable() goes through
all the parts anyway. And multiparts implement generateBody() instead of
generate().
> This system has several advantages:
> - It caches in the ezcMailPart class, so you get caching for free in all
> subclasses
> - Even if you override generate() and don't provide any caching at all it
> will
> still work: if the parent MIME class can cache the result will be cached
> there. If the part can't be cached it will just generate it's contents every
> time.
>
> Open questions:
> - Do we want to have an option somewhere for a mail to turn caching on and
> off? Where should it be? (it must be reachable for all parts) I say yes,
> since generating multiple mail will behave different from the current
> implementation (the parts will then be automatically cached and your changes
> won't be seen). Which is a BC break.
I think that option could be doCache. So in your application you create
an ezcMail object, set doCache on it, set isCacheable = false on the
text part, and then send the ezcMail to your opt-in mailing list by
changing everytime the Subject, To, text part, etc.
I think doCache should be off by default to not cause any memory
problems with big attachments.
> - should isCacheable() be implemented as a read/write property but with logic
> in the "__get" method?
A property would be nicer.
Some ideas:
- Maybe a method like clearCache() would be useful, for those cases
where you want to send many mails in the same script. If you call
clearCache() on ezcMail it should propagate to all mail parts.
I like the proposal, and it is much nicer than what I had in mind. Hope
to see it soon. :)
Cheers,
Alex.
--
Alexandru Stanoi
eZ Components System Developer
eZ Systems | http://ez.no
--
Components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/components