The jist is there is a bad conditional in the form helper, and i don’t care what the “test” case says its wrong. I went to a lot of trouble finding the source of the problem, more time to write it up, and it is dismissed, when you can plainly see the code is incorrect. unless php changed how its operators worked since the last time i checked (and i’m open to hearing about it if they did). but !== is invalid.
further, I’m working on real data, on a real project, and I’m a real person who went to some lengths to nail the issue down. trusting a test case over that is irresponsible and bordering on stupid, actually.
I grow less and less impressed with the cake community, as with the code base itself.
I can’t specifically say why.. but i don’t get the sense the cake people really care about the people who have to use their tools.
if someone wants to take a stab at what they think this evaluates to, i’m all for it:
if (!array_key_exists('escape', $options) || $options['escape'] !== false) {
aside from the wrongheadedness of the entire conditional which asks first if not something exists then asks if the key doesnt equal false can anyone tell me they’ve ever seen !== used anywhere and what it evaluates to?
how bout using some sense people and evaluating for truths now and then evaluating for not not falses.
Felix discusses the challenges of php errors, and language quirks and i applaud him for bringing questions like this to light because we may talk about solutions a lot, or how to do something, but we rarely talk about the smaller, often important way we think about a problem.
I thought I would chime in with my take on the matter, for whatever that’s worth. Imagine a scenario where you have an array of values, consider them boolean for the sake of argument. true or false, or at least they will evaluate to that.
he discusses a few different ways of avoiding those pesky php errors for missing array elements, and goes so far as to flirt with inline error suppression using the @ operator which is akin to slaughering your firstborn for kicks. or, feels that way at least.
I find whenever you have to really go against the grain and fight your data, or your language its usually a sign that I am looking at it wrong. There are cases, of course, when the language just fails. it cannot in a real way do what you need it to do without some magic, and php has lots of those issues. its an ugly language and barely expressive. that said, it works.
so back to our array then. his issue lies in this code:
if (isset($step['options']['merge']) && $step['options']['merge']) { // do stuff }
the thought process being you to avoid errors you have to check “pre-check” the value with the isset. While i’m not a huge fan of isset (or a number of php evaluations) and find them quirky at best, the line of code is essentially right. Whether concise or not is beyond the point.
my version is mostly the same:
if (array_key_exists('merge', $step['options']) && $step['options']['merge']) { // do stuff }
I like these collapsing conditionals. there is an explicitness (while verbose) to them that makes them valuable. And, when the array key fails the entire evaluation fails, skipping the possible error from running the second part of the condition.
better that than some external function as some suggest, and better that than supressing errors. Sometimes the confines of your language make your code a bit ugly, sometimes you must be verbose to be correct.
either way, i appreciate him writing out his thought process, and his possible solutions. We need more of that.
Everyone but the cake team knows the cake docs suck huge. Obviously written by someone with a solid understanding of cake internals and pretty sparse at the best of times. Add to that the api docs often don’t even list all the functionality for a class (usually due to parent objects exposing functions) and you end up having to search for something obvious and simple like:
$this->modelName->getAffectedRows();
which obviously tells you how many rows were affected by your last query. Search the cake docs and find nothing. browse the api and find nothing. You’re left with following the object tree through code or google.
this is but one of a million tiny things that should be expressly documented at least in the API, which take time to find answers for and I think likely annoys new cake deveopers—possibly right out of cake.
symfony made huge strides in growing its developer base because of its great documentation, and to my knowledge i never went looking for a function call in the api and was unable to find it. these things matter when you’re in the learning curve, and they matter when you need to find information rarely used.
If you’re already smart enough to be using jquery for your projects (and i know you are cuz you’re clearly a bright developer) then i strongly recommend jwysiwyg.
I’ve implemented a bunch of wysiwyg editors over the years and its almost always painful. Symfony with TinyMCE is a headache with over 2mb of files introduced to your project. I wanted to avoid any sort of extra work or hassles on the project I’m on and we only needed the simplest editor we could get.
its worth noting the less editing options you give the better. Inexperienced users + text editors = serious headaches.
though the site gives no documentation to speak of setup was breezy simple. do the following:
download the plugin.
copy the js to your js folder, the css to your css folder, the controls gif to your images folder
add the relevant css + js declarations to your header to pull them into the page
update the control image location in the css file to point to where you actually keep your images (if you see no controls once its running this is set wrong)
add the code to your jquey file
add the id whysiwyg to your form element. (you can use classes if you prefer, just update the above jquery selector to look for .wysiwyg instead of #wysiwyg.
you can set rows and columns for the html input to determine the size of the editor
viola. In less time than it took me to write this you have a good rich text editor. who loves jquery!
er. we haven’t talked since last year. thats not love.
I have a couple things i want to share, or expand, or complain about but as things tend to go when you near the end of a project (my first commercial cake gig) it gets a bit nuts and time gets short.
i hope to wrap this beast up in the next few days then write you some articles about some of the things i’ve learnt about cake over the last couple months. so sit tight folks :)
I decided today, since i’m writing here anyways, i would sign up to the cakePhp site and maybe do some cross posting for articles heavily focused on cake. the signup process was brutal.
I know that they are gearing it towards advanced users, but i’m an advanced user and still i can’t read the minds of other developers (all i hear when i read your mind is ’ ruzz, you’re the awesome’ and you say it with a chinese accent. weird).
lets start with the actual sign up.
first problem i had was the real name field says it accepts punctuation, but errored out on me every time i tried to use my name: i. m. ruzz. small annoyance.
second, passwords. Am i creating a password that will store the secret locations of all my hidden money? no. am I dealing with highly sensitive information? no? why am i forced to use an industrial military strength password? these conditions exist:
6-15 characters. most sites do this now.
at least one number (myspace does this)
at least one captial letter (no one but the cake site does this)
listen. the truth about passwords is they belong to me, not the app. I’m the one charged with rememebering them so I should have some say about it. I’d fully understand if you encouraged these strict rules, thats good system administration. I can even understand enforcing them if there was real meaningful damage that could be done by cracking one. but lets leave the ethereal world of password security and use some commen sense. No one wants to hack my cakephp bakery account, and even if they did, what can they do? mess my articles up some? not vital but the password rules treat it as if it is. theres a disconnect at play in the developers mind.
the real cost of this is on me. I will forget my one time crafted to meet your rules password and have to go through arcane and uncomfortable password recovery/reset routines if i rarely use the site, and this hassle makes me much less likely to use the site. period. truth. reality.
if the inner unix admin in you just can’t deal why not implement a password strength widget that gently nudges me towards your desire, but lets me have the final say, within reason.
so after doing that process. I actually had to reset my password due to a glitch and found something even more interesting in the new password they sent me.
it doesn’t comply with their own requirements.
this just pissed me off.
it was all lower case, no capitals. so they don’t have to be secure, but i do.
once through that I customized my profile like all good users do (haha). and this is what i found.
I added the question mark for emphasis. I know what your first thought is, if i start typing something like mountain standard time it will auto lookup. no. wrong.
i just have to guess what they want is:
which does nothing after entering it but magically converts it after save. thats friendly.
same deal for user icon. what do they want? an url?
i never found out what they wanted even after submit, it never gets rendered to anything that i can see. fun!
i really should be working not writing up tutorials for this site, but hopefully this can be a quicky.
a few years a go I worked for a client who had a very sophisticated ui built before i got there, and they had these really sexy transparent image rollover controls. I did end up replacing the entire control breaking it out of a mess of js, to a reasonably tidy prototype/scriptaculous solution which worked great but was overly complicated.
an example of that can be seen to the right.
its a good idea to hide controls, it makes the interface much more interesting but what i took away was a love of that transparent part of the control bar and a desire to use that for captions.
I’m quite sure some super css whiz could do this entire thing without any jquery at all but the jquery gives me a reliable way to use transparency without having to worry about cross browser issues so thats the route i went for this little demo.
Our goal: create a snazzy transparent caption that sits across the bottom of an image that degrades nicely for those pesky non-js enabled browsers (as if).
What I want it to look like is this:
and, when js isn’t enabled, I want it to look like this:
so basically all the js is doing is making it transparent and shifting it up to hover over the image. simple right?
okay. the html.
we have three html elements for every image we want to wrap. A wrapper div called caption-wrap. an img element, and a span with the class caption. thats fairly simple.
the reason we need to wrap the image (and i tried other ways, believe me) is we want a fixed-with box to so the caption is the right width (even if we don’t know the image size). so lets add some styles to this bad-boy.
okay so we’ve got two styles. Caption wrap and caption. Caption wrap doesn’t need a width if you have elements around it keeping it a fixed with (like a row of images in a fixed with box) but it does have to have the position: relative. without that it won’t work.
.caption is the default caption style. which is what it will display if the js isn’t working, so you should style that to match your page before you do add the magic then you know that your bullet proof.
now we need to add some jquery magic.
what this bit of jquery is doing is finding all the elements that match the span.caption rule. then stopping any other animations that might be happening (this is wise in case you have other functions performing against those elements). then setting the opacity, then removing the class .caption and adding a new class of hover-caption.
the hover-caption class will define the look of the “hovering transparent” caption. which will only happen if the js is working, and only after we’ve set the opacity. so now we need a .hover-caption class.
that class lets you style your hovering caption to look how you want, given your layout and expected level of transparency. which is handy because you don’t want it to look the same as it would if there was no js.
thats it. your done. your finished product should look like the image above. to be extra nice, i’ve added all the files in this demo to a zip file which you can download and test out yourself.
i’m sure the code can be cleaned up, but i just want to communicate the idea to you so you can run with it. enjoy.
update: extending this idea to be on hover only.
you can pretty quickly extend this idea so captions only show up when you hover by adding making the following changes:
add display: none; to .hover-caption. this will hide the captions by default then just add a trigger to the .caption-wrap rule for hovering to trigger it. like so.
for those of you who’ve done any in depth ajax stuff you know it can be a blessing or a nightmare depending on the structures you have in place. here, workflow and semantics become vital so you don’t get lost in the details. one of the really great things is getting cake to throw real server errors that let you do valid things.
theres a concept you have to understand first though to make proper use of this technique and that is the difference between an ajax request being successful and your code responding with code based on the requested function being successful.
the simple way to conceptualize this is there are two levels of errors in reality:
the ajax request failed for some network or server reason and could not complete the request properly
the ajax request went swell, but the request failed programmatically for some reason (missing a passed argument, requesting an invalid blog, whatever).
the shortcut is to build your layouts based the expectation most ajax requests will succeed and render back content in the form of html, which can be plugged into your page. the basic thought is you send error information or success information but it always ends up in the same control (div, li) no matter if cake gave an error or not. so your errors become part of an inline process in the control.
not only is this bad form—which quickly leads all manner of organizational headaches—but it also limits how you can interact with your page. severly.
imagine this scenario:
on the left you have a list of valid images. on the right a list of buttons that can generate images for the ones missing from the list on the left. this is from an actual project i am on right now where the system maintains several image sizes for every image.
if we use the shortcut method we have to wrap our working area in some sort of control, say a div. and then replace the content of that control with updated html from our server. imagine a div around the button for simplicity.
thats our working area. the reason its our working area is because we can’t easily evaluate the content of the incoming html to decide further if cake gave us back an error or a success block of html, so we have to render it there and let the html given back decide what happens next. like so perhaps:
for clarity i’ve outlined our working div in yellow again. Basically the server responded with a crafted html response for a cake error which gives us the original content (so we can try again, presumably) and an error msg. now we might fade the error msg and allow them another whack at the mole. Or we may, on success, have some embedded js to fade the div after showing the success msg. lots of options but we are still bound to that working area which is sort of odd when we have a list of valid images to the left.
what if we wanted then to fade the div on success and push a new list item over to the list. we simply can’t do it working the way we are now.
enter js freaks who insist we could write some fancy js to do it, and we could but it’s not simple, and i think it becomes error prone when you are serving multiple responses and hand crafting an evaluation of them. some js guys might say this is a perfect case for json, and it really is, but that means if you have to make a template for the json response, and a template for the non-ajax enabled response (you do degrade gracefully right?) and that again makes things more complex.
the answer, i think, is to make use of the ajax server error mechanism already in place and usable. it lets you make post ajax-call decisions and influence any portion of the page you like easily. how do we do this?
first step, build a test action on your controller. you want first to ensure header redirects are working for you. try this code (sorry for the image, but tumblr is lame about code blocks).
what we are doing is turning off debugging on the fly. then rendering the page content we want (a generic error page) with an ajax layout, then doing a redirect with an http code of 500, with false to allow our ajax error layout to be rendered.
what should happen now is we get a firebug 500 code when we load that page:
and our content should look like an html snippet:
this particular snippet can contain cake error specific information like invalid blog post requested, or whatever is right in context to your request.
not getting that error code? check all your models and controllers for white space at the end of the file. number one cause of the redirect not working. see how hard it can be to spot sometimes?
that last line number is because there is a CR there and that gets output and breaks php’s ability to send headers correctly. search and search, i’m sure you will find a hidden bit of whitespace if you can’t get $this->redirect() to work right.
still with me? great.
now that we have that in place we have decoupled the working area (and response) from the response itself. if the server throws an error we can maybe pop up an error box with the right msg in it but do nothing to any other part of the page, like so:
I should point out right now if you can make a uniform screen control to handle your loading msgs, and your error msgs you will be much rewarded in programmer heaven. what you see above is a handy box that slides up from the bottom of the screen (which i will write about in detail later). i also have one for loading msgs. but where it gets really slick is using jquery .ajax events. you can attach an event to the popup of the bar that is triggered by any .ajax failure which gives you a uniform interface (and saves you writing error: function() {}; for every .ajax request. see an example of how to do that:
whats going on here is i have a hidden div at the bottom of the screen which is called #pop-error whenever there is an ajaxError triggered it pops up the div, and inserts the response from the call (which one assumes is an error msg from cake in html) into the #pop-error-msg div which is a div inside #pop-error.
its sexy. i know.
whats awesome though is you can do the same with ajaxStart and ajaxComplete to trigger your loading controls to start and stop which means in each jquery .ajax call you write you only need to write the success function, the rest is handled automagically.
so now we have broke our response from our working area, and made sexy error handling. what was the gain we made from a user perspective? now, on success we can just update the list on the left—which i think is what you would expect to happen when naturally.
so we do something like this:
whats going on here is we are writing a jquery .ajax request which on success hides the element that was clicked (a button for generating the image) then appending the response html to a ul and highlighting the list so the user follows the action correctly. it looks like so when complete.
which i think makes a lot of sense. there are now no more images that may need generation, and all the valid images are listed. and round trip we sent one line of html for either a success or a failure rather than passing elements back and forth through the ajax calls.
I think there is one more touch we can do for users who may miss the highlight when it fires and wonder if anything happened. we can callout the newly added list items by giving them a class named .added and monkeying with the .css for them. first we addd the class in jquery (note i swapped my icons a bit so they are uniform):
what we’ve done here is modified our success function a bit. first we find the last li item in the ul with the find command. then we chain an addClass call on it adding the class .added then for clarity we end() which puts us back into the ul, where we call a highlight against the whole ul (rather than the single li).
write a css class for .added and viola.
so a completed call looks like this:
which i think clearly gives the user a understanding that they just created the systhumb image and we didn’t have to muck up our ui at all.
a video of it in action so you can see the entire experience. watch and then ask yourself if this is cleaner, more fluid, and easier for the user.
i think that about wraps up this long one. I hope if you are fuzzy on specifics you are at least clear on the idea of how to use jquery + cake to make some really oustanding user experiences. I will write a separate post, a tutorial, on my loading and error solutions when i get a few minutes :)
so you make your awesome ajax page which is going to pull in a nifty snippet of html, which will also have some ajax goodness in it. you test both pages independently and everything works great. then, you start pulling the second page in and find the events for the elements in the ajax result aren’t binding, or firing. why?
good question. the answer if you were using prototype would be to add a script=’true’ to your ajax request and whatever it brought in would work. but you’re not. so get over it.
this is a conceptual issue. the gain made by going to jquery (or one of them) over prototype is largely one of a cleaner implementation. by using event binding (rather than js sprinkles everywhere) you get to declare a bit of js for a link click in one place and one place only and it’s always there.
the downside to this is when you bring in new html elements through an ajax call, which, lets say contains a link with the id #generate, you would expect the code you wrote which triggers events for $(“a#generate”).click(function(){}); would fire right?
wrong. they won’t because the DOM was parsed once at ready and you brought them in after that. follow?
the answer is reasonably simple. use the livequery plugin. no really. use it. it will handle all the sex for you.
before you wrote this:
$("a#generate").click(function(){ //do something here });
now you write this:
$("a#generate").livequery('click', function(){ //do something here });
and thusly livequery will worry about binding and unbinding. gay, i know. but jquery is worth a bit of gay now and then.
in the course of writing an article about good cakephp ajax i found myself stumped by bizzare behaviour.
in a nutshell, i was forcing a http 500 error through a test action in a test controller using the following code:
which, by all intents an purproses should throw up a 500 code with my text template shown. And it did (after i tracked a bunch of empty whitespace throughout cakes libraries, gar!).
it did but it would only throw a 500 if you loaded the page through the browser. load it through an ajax request (jquery) and it shat the bed with a http 200 ok code. I confirmed the headers generated by the browser in both instances to find what was different:
the obvious one highlighted. So I started following that through the cakephp maze. First stop \cake\libs\controller\components\request_handler.php. fun!
by adding the early return false, i sidestep any isAjax whoopee being done after the fact, and guess what. It works. Now either type of request serves up a 500 error. interesting stuff. So I tried to follow the chain down further to establish exactly where things were going awry but i quickly found myself in a mess of code I wasn’t interested in dealing with. A quick search of ajax related code in the base gives back a lot of responses, most of which are easy to rule out, but i found that i quickly got lost in the myre. cake’s internals are so rife with magic relationships between values and functions it’s painful to debug. This is one major issue i find repeatedly under the covers of cake, and nothing will fix that because its the core.
having said all that, initial tests show that i can just turn that sucker off and it works without poorly effecting my other code. i lose the ability to magically determine an incoming ajax request but thats fine, i can do it manually or just plan around it. what i can’t have is some vagabond code throwing some whitespace in somewhere and breaking the headers thus forcing me to write very sloppy ajax.
and my guess, which i feel strongly would be correct is somewhere in there is a bad bit of code echoing something, or pushing an early header which results in the redirect headers never making it to the browser (like birth, you can only do it once). But thats on the guys at cake to fix.
if i hadn’t wasted so much time i would post a bug to cake (and figure out how to do that, ahem). but as it is, i blew out the night solving something that should work in the first place.. and makes me so miss symfony’s $this->getResponse()->setStatusCode(500); which worked every single time i called it without fail.
btw..1.2.0.7296 RC2
now, i can finish my next article about how to do good jquery ajax with cake.. soon.