I am trying to create textimages in a particular folders with particular names, so that I can programmatically chose my preferred textimage for my banner in particular situations. However, I have two problems, the 'files/textimage' folder continues to be created as well as my folder and I don't know why. Also I am using rules to unlink the textimage when the text changes so that the image is recreated.
Here is the code I am using...
$display = theme('textimage_image', array(
'preset' => 'bannertitle',
'text' => 'my text',
'additional_text' => NULL,
'format' => 'png',
'file_path' => 'public://users/myfolder/bannertitle'
));
echo $display;
Should this function create the textimage if it doesn't exist in 'myfolder'?
Also if I delete the image will this function recreate the textimage?
| Comment | File | Size | Author |
|---|---|---|---|
| #36 | textimage-target_uri-2133587-36.patch | 8.56 KB | mondrake |
| #36 | interdiff_29-36.txt | 1.95 KB | mondrake |
| #31 | textimage-target_uri-2133587-29.patch | 6.77 KB | mondrake |
| #19 | textimage-target_uri-2133587-19.patch | 6.79 KB | mondrake |
| #19 | interdiff_19-19.txt | 1.34 KB | mondrake |
Comments
Comment #1
webservant316 commentedJust how does textimage work? Is the file_path expected to be unique for each distinct text string? Or if I revise the text for a particular filepath will it update the image file? It does not appear to. So then how can I programmatically update the image file?
$display = theme('textimage_image', array(
'preset' => 'bannertitle',
'text' => 'my text - revised text',
'additional_text' => NULL,
'format' => 'png',
'file_path' => 'public://users/myfolder/bannertitle'
));
echo $display;
Comment #2
mondrakeHi @webservant316
the logic for path management and theme calls in 7.x-2.x is indeed pretty clumsy :(
If I understand correctly what you are trying to do, I'd suggest to checkout 7.x-3.0-beta1 instead.
Firstly, you'll have to create an Image Style named 'bannertitle', including the textimage effects you need. Have a look at the README.txt file.
Then you'd have two options (just example code on top of my mind, not tested):
Option 1 - use theme calls
Just call the theme to render the output with your text. You do not need to care about the path where the image is stored.
In fact, the images will be created as 'public://textimage/bannertitle/my text.png' and 'public://textimage/bannertitle/my text - revised text.png' . Or as 'private://...' if you choose to store the images in the private file system (it's an option on the Image Style edit form). The only exception is if your filename cannot be created 'cleanly' (e.g. if your text array contains very long text or special characters); in this case the file will be stored in a special directory and the filename consist of a md5 hash; but you don't have to care - Textimage manages that for you under the hood.
Option 2 - use API calls
You want to create textimages programmatically. There's a specific API for that: you create the textimages, get the URI where they reside, and you can render them with a call to theme('image', ...). The location of the image file follows the same logic as in previous option.
Hope it helps... feedback appreciated.
Comment #3
webservant316 commentedSeems like people will either want textimages stored per unique text OR per unique file. If you store per unique text perhaps there is not a concern about text expressions that are no longer needed.
In my case I want to allow a unique textimage for each registered user, to be used as their banner. I could use option 1 above, but if they change their banner text I will have a lot of abandoned textimages laying around. Ideally I want to store textimages per unique path/filename. Also I want to specify the path/filename because I am trying to keep each user's files in one folder. Even more ideally I would like to overwrite the path/filename if the text changes. That way I conserve file resources because each user only ever has one textimage for their banner. How can I overwrite the image only if the text changes?
Does TextimageImager::getImageUri both create the image and return the uri? Seems like you still choose the location for the image. I am trying to build a system that is prepared for thousands of textimages so I am not sure that I want them all in one folder for performance concerns.
Also your option 2 example above seems to demonstrate the revision of a text image named 'bannertitle'. However, is the image overwritten or a new image created? Your example seems to indicate that both images are still available at $my_text_uri and $my_revised_text_uri.
Comment #4
webservant316 commented7.x-3.0-beta1 = WSOD
Comment #5
webservant316 commentedHoping to help you with the feedback you need to get this working. This module has become essential to me because of wanting to allow the user to customize their own banner. I could use text itself as the banner, however, textimages have the cool feature of resizing properly with my responsive theme.
Let me know how I can help with feedback. As I look at your module is seems to be designed with the thought that you do the file management for unique text strings. Perhaps the design could be extended with the thought that the user could specify unique textimage folder/filenames to contain any string.
Comment #6
webservant316 commented7.x-2.0 worked great for me. Except this function doesn't return a new image if the text changes...
theme('textimage_image', array(
'preset' => 'Preset',
'text' => 'Text',
'additional_text' => array('Additional', 'Text'),
'format' => 'png',
// Don't include the file extension!
'file_path' => 'public://myimages/sub_folder/image-filename'
));
Comment #7
mondrakeStrange. True this version is pretty new, but this is the first report of WSOD, while some issues already are about using the module, so someone has got it installed and working. Have you tried a clean install?
Yes - it creates the image, and returns the URI to the image created.
A new image file is created, with the new text inside the new image. So you have two files, one with text A and one with text B, under the same 'public://textimage/bannertitle' directory. This helps with caching because if you need again an image with text A, it will pick the existing one instead of re-creating it.
If you do not want to cache the textimages, and accept that they get created on the fly, you can disable caching. There's a variable for that in the theme call, and an argument in getImageUri.
non cached images are be stored in a different directory (private://textimage_store/uncached/{hash}.{extension}), and get removed upon each cron run. getImageUri will return the URI to the uncached image. From there, you can either display the image to the user as such, or programmatically copy that file to whatever directory structure/filename you need.
Yes that is correct: input is a) an image style and b) some variable text. Textimage makes sure that given (a) and (b), an image file with text in (b) is generated and cached for further access.
Can't remember how 2.0 was exactly doing this, but definitely it had problems - see e.g. #1969774: when chaining presets, cached image considers only last preset value and #1936172: Fatal error: Call to a member function realpath() on a non-object.... I suppose that's because if you specify a filename for text A and then the same filename for text B, 2.0 will anyway see that a filename exists already and return the image for text A.
Comment #8
webservant316 commentedThe 7.x-3.0-beta1 = WSOD was a clean install. Here is my PHP error log.
===
PHP Fatal error: Call to undefined function array_replace_recursive() in ../sites/all/modules/textimage/textimage.module on line 840
===
At this point I plan to use Option 1 explained in #2 above.
Though, I am concerned about the performance of having thousands of textimages under your file management scheme. My preference would be a simple API that specifies the text, preset, and exact location/filename of the image. The return value would be the HTML markup or fail. If the image file doesn't exist it would be created. If the text changes the image would be recreated, same filename. That would be most excellent for me.
Of course before I can use 7.x-3.0-beta1 I need a fix for the error message above.
Comment #9
mondrakeThanks
array_replace_recursive() is a PHP function, available for PHP >= 5.3.0. Which version of PHP are you on? If below 5.3.0, I found an alternate implementation in stackoverflow, maybe we can include that as a patch in the module. It would be great if you could test and let me know.
Hm. This would have serious implications on the caching mechanism, as we should store away the text currently represented in a image file - how would textimage know that the text has to be changed otherwise?
If your concern is about having 'loose' textimages on the file system, you can always put a call
image_style_flush('bannertitle');in a periodic job (i.e. cron). That would remove all the image files under public://textimage/bannertitle, and next time getImageUri is called a new image will be recreated.Comment #10
webservant316 commentedThe requirement for Drupal 7 is PHP 5.2.5. You probably need to downgrade the use of that function for a Drupal 7 module. I am using PHP 5.2.17 with no plans to upgrade.
As for my simple API, that is a good point about how to figure out if the text changed. All the options that come to my mind include: 1) Database table linking the filename with the current text string, 2) EXIF data in the image itself? 3) a second file, '.banner.txt' next to the image file containing the current text (though this would require a file read each time) and 4) prepare your code to allow me to delete the file myself after I change the text and then next time the API is called since the file is no longer there is gets recreated.
Option 4 seems the easiest for you and also for me since I will know exactly were each banner image is located. It is also offers the optimal performance. Everytime a user updates their profile I will just delete their banner image. I tried to do that with 7.x-2.0 but it didn't work for some reason. I think the file storage mechanism is messed up when trying to specify your own location for the image.
Comment #11
mondrake1. I'm on 5.4, no access to 5.2. Can you just test, placing the code snippet indicated in #9 from stackoverflow into textimage.module? If that solves the issue I will include it in the main repo.
2. Option 4 - use the solution in #7, using getImageUri and disabling caching. Get the URI of the textimage, copy it to whatever path/filename, delete the file from where you copied.
Comment #12
mondrakeCreated spinoff #2134439: Installing on PHP < 5.3.0 results in WSOD errors for the WSOD issue related to usage of array_replace_recursive() .
Comment #13
webservant316 commented#11 - 1) hope to do that tommorrow.
#11 - 2) I think I understand, but my code wrapper around yours it going to look pretty clunky. If possible please consider my simple API as a feature request. It would be a simple extension to allow the caller to choose the filename and location.
Comment #14
mondrakeForget about #11.1, sorry.
It looks like I should have been using drupal_array_merge_deep() instead of array_replace_recursive(). Please watch out for #2134439: Installing on PHP < 5.3.0 results in WSOD errors, I'll post a patch there tomorrow.
Comment #15
mondrakeChanged to feature request based on comment in #13.2
Comment #16
mondrakeHere's a patch. It extends the getImageUri method with an additional argument, $target_uri, where you can specify the full URI where the image should be stored. The file just gets generated at the URI specified (note the URI shall be inclusive of the file extension, differently than in 2.0). If there is a file at $target_uri, it will be deleted and recreated with the specified $text.
Use like
$my_textimage_uri will be set to 'public://my_path/my_filename.png' upon return.
NOTE: there will be no caching of an image if you specify $target_uri. That's because, given a URI, we could overwrite that file with whatever $text.
Comment #17
mondrake... and the patch ...
Comment #18
webservant316 commentedThanks.
I had originally thought the API should only create the textimage if doesn't exist and simply return the uri if it already exists. However, your solution to always delete if exists and create is better. In my use case this will save unneeded calls to your function. When my text is created or changed I will simply call your API. However, when displaying the image, if the image file already exists I just display the image. If it doesn't exist I call your function.
I will test soon.
Comment #19
mondrakeReviewing, most probably we do not need to explicitly delete the file, as the lower level
imagexxx()functions called by the toolkit viaimage_toolkit_invoke('save', ...)will anyway replace a file if already existing. Shorter patch then...Comment #20
webservant316 commentedprovided that the imagexxx() functions delete and create a file by the same name.
Comment #21
mondrakeOf course, see the tests, I have one that generates a file for an URI, and then another one with different text for the same URI - they are passing i.e. only one file is counted in the destination directory.
Comment #22
webservant316 commentedshould I test with 7.x-3.0-beta1 or 7.x-3.x-dev?
Comment #23
mondrakePatches are always against dev, but in this case beta1 is currently equal to dev. To cut short - my recommendation would be to test with dev.
Could you also provide feeedback to #2134439: Installing on PHP < 5.3.0 results in WSOD errors?
I'd like to go for a beta2 when these patches are confirmed - we shouldn't live with a release that ends in a WSOD or a fatal (see #2106417: Fatal error: Call to undefined function _color_pack()).
Thank you for your help here.
Comment #24
webservant316 commentedModule installed properly. However, when I went to create a preset I got a
WSOD here PHP Parse error: syntax error, unexpected T_STATIC in ../textimage/classes/TextimageStyles.inc on line 34.
Comment #25
mondrakeSorry for that, looks like a PHP 5.2 issue again. Will post a new patch under #2134439: Installing on PHP < 5.3.0 results in WSOD errors soon.
Comment #26
mondrakeOK, the patch in #2134439: Installing on PHP < 5.3.0 results in WSOD errors passes. Unfortunately, the patch in this issue is colliding with that, so it would need to be re-rolled. To do that, I need to commit #2134439: Installing on PHP < 5.3.0 results in WSOD errors first. Can you check if you can install and run the module with the patch there?
Comment #27
webservant316 commentedPHP version issues seem to be solved. however the api call as directed in #16 does not work correctly. The image was created, but was not located where I directed. Instead it was located at private://textimage_store/uncached/hashfilename.png.
Getting closer.
Comment #28
webservant316 commentedAlso in my code I am assuming that if empty(TextimageImager::getImageUri()) = TRUE then the image creation mission failed. Or do you have another recommendation?
Comment #29
webservant316 commentedThe repairs for the php 5.2 compatibility seem to have fixed #27. So I think everything is ok with your module. I still have to figure out how to use rules to grab updated text from a profile field edit after the submit, but before the change is available in load_user(). However, this new API seems to be functioning. Thanks.
I will report back one more time with final confirmation.
Comment #30
webservant316 commentedthe function call in #16 is creating the file in the proper location, but if the file exists the function does not appear to delete and recreate the image. your suggestion that the function always create and/or delete and create seemed the best, but the delete and recreate may not be working. I'll test further on Monday.
Comment #31
mondrake#29 - I was not expecting this to be functioning yet. Can you please test with the patch here, and the new dev that will be built after the commits today.
#28 - getImageUri() returns the URI where the image is saved, or NULL if it fails. So you can simply have
Patch here is a reroll of #19 after #2134439: Installing on PHP < 5.3.0 results in WSOD errors was committed.
Cheers
Comment #32
webservant316 commentedHope to get to this Monday.
Comment #33
webservant316 commented7.x-3.x-dev installs, configures, and operates without PHP or Drupal error.
The textimage is created in the right location with the right name. However, subsequent calls to the API will not overwrite an existing file.
Comment #34
webservant316 commentedSo I am just deleting the text image before I want to update and so I have the function I need. Post back if you get this figured out.
Comment #35
mondrakeGreat! Glad it's working. So this means I have to reintroduce the explicit file deletion I removed in #19. I would like to understand why the file does not get overwritten, though. I will look into it tomorrow.
Comment #36
mondrakeI investigated a bit, and modified the logic of buildImage(). We may have the case that multiple requests require to access the image file at URI at the same time, and if we delete the image before we start the generation process, some of them will fail and render no image. I know it's not your use case, but still we need to look for this. So, instead of explicitly deleting the file, we let it be overwritten by the image generation process when the image is ready. So we shouldn't have the temp blackout in this case.
NOTE - while testing, I noticed that the browser may be caching the image at URI, and use a local copy even if we are rebuilding the source. This patch does nothing to prevent that, just the server side of overwriting the image file.
Comment #37
webservant316 commentedYes - I was wondering about the temp blackout case as well. Overwriting is definitely the way to go. And yes, may not be much to do about the browser cache since the image isn't changing names. Some browsers are better (FF) and some worse (IE) at refreshing their cache when needed. I just need to warn my user with a note that their change may not be evident until their browser cache is refreshed.
I will test you latest patch and report back.
Comment #38
mondrakeHave a look at this, just in case. It's something to be probably done at the theme('image',...) level.
Comment #39
webservant316 commentedno php errors or critical Drupal errors after
1. fresh install of patched module
2. configuration of textimage
3. clean up textimage function
4. creation of configuration of image style
5. custom calls to TextimageImager::getImageUri as explained in #16
Calls to TextimageImager::getImageUri will create or recreate the image filename and location as directed. So I do not need to unlink the textimage file myself.
So it would see all is well. Thanks!
I did get these errors in my Drupal logs....
10 occurances of this specifying both public:// and private:// in alternating entries.
and 2 of this specifying public:// and private:// in alternating entries.
I didn't manually delete any files before I uninstalled and reinstalled your module, but only used the interface. Though, everytime after I get things set up to my taste there has been an 'uncached' folder in the private folder that seemed unneeded so I have deleted that manually.
Anyway maybe those Drupal errors are not significant, but it seems like some code somewhere is trying to do unneeded work.
Comment #40
mondrakeGreat! Thanks, I will commit this then.
... it's a Drupal core issue, see #2079315: Image style editing leads to redundant watchdog entries.
Yes. That folder is (also) storing the previews of the image shown in the Textimage text effect admin UI. It's an image itself, and has to go somewhere... :) All the files in that directory get removed upon each cron run, so you shoudn't worry about that.
Strange. If you understand more when this happens, please open a new issue, let's close this one now.
Comment #41
webservant316 commentedSuper. I look forward to installed the module with the patch installed. For any following this post this addition is awesome for me and allows me to use textimage banners per user. Images are ideal for this application because they can be styled to resize with responsive themes.
Thanks again @mondrake.
Comment #42
mondrakeCommitted and pushed to dev.
Comment #43
mondrakeReleased 7.x-3.0-beta2
Comment #44
webservant316 commented7.x-3.0-beta2 fresh install, configured, operating. Thanks again.
Comment #45
sigalasgeo commentedIs there any way to use tokens in order to retrieve the hashed target uri? The idea is to use the path of the image in OG meta tags.
I am using text image to create image quotes but i cannot figure any way in order to retrieve the actual path of the image via tokens. you may see the site (www.posts.gr).
Thanks in advance and thanks for the great module.
Comment #46
mondrake@sigalasgeo re. #45
I opened a new issue #2146495: Implement Textimage tokens to retrieve images' URI/URL. Let's continue there and leave this issue rest in peace :)
Comment #48
webservant316 commentedThe API doesn't work on 7.x-3.0-rc1. The text image made is always the preset default.
Comment #49
webservant316 commentedsorry. my fault. it does work.