Dump current database state to Yii migration

There’s a wonderful extension to Yii 1.x, called database-command, written by the one and only schmunk, which allows you to quickly and easily generate any set of CDbMigrationCommands (actually, entire single migration code) based on current database schema.

This isn’t, of course, the only one out there. There are some others. But I like this one the most, mainly for flexibility (may parameters to suit generated migration file to your needs). However, if this is your first approach to using custom yiic commands, you may get a little bit confused. This article should help you.

Read More “Dump current database state to Yii migration”

An introduction to database migrations in Yii

If you’re new to Yii migrations, these sources might be a help for you:

  1. General information: Database Migration topic in The Definitive Guide to Yii.
  2. How to create initial migration basing on current database state, explains this Stack Overflow question and GitHub Gist (with InitialDbMigrationCommand class’ code) to support it.

To use migrations, you have to properly configure console version of your Yii application. Details follows.

Read More “An introduction to database migrations in Yii”

non-YiiBooster fields with YiiBooster prepends

I don’t like the idea of rewriting my entire application’s view to use new Bootstrap 3, so my Yii apps remain on Bootstrap 2, served by YiiBooster extension. The biggest problem, I find in it is that its controls have prepends somehow “built-in”.

Both field and its prepend is rendered with one line of code. So, when you want to replace any YiiBooster’s control with for example own widget / library, you always remove one line, but looses both field and prepend.

I found ugly and nasty workaround for this.

Read More “non-YiiBooster fields with YiiBooster prepends”

Cyclic jobs in Yii and MySQL

When we are talking about some cyclic tasks executed periodically in PHP, most of us automatically thinks about CRON. It is not surprising, since it is very popular, easy to manage (available often even on shared hostings) and easy to code (it simply fires given PHP script).

However, there are four other ways you can achieve exactly the same in Yii/PHP. And many Yii developers may not be aware about some of them.

Read More “Cyclic jobs in Yii and MySQL”

Capture double click on Yii’s CGridView row

I was using a simple Javascript code (attached to CGridView.selectionChanged property) to capture click on any grid view’s row and redirect user to row-specific URL. I wanted to change it to double click only.

CGridView exposes selectionChanged even only, no click or dblclick, so that was a quite nice challenge. It seems that the only way is to capture this event yourself.

Read More “Capture double click on Yii’s CGridView row”

Delete model with relations

To delete in Yii a model with some relations we usually have at least three options.

Depending on many factors (RDBMS type, table type, situation, context etc.) most of them have advantages and disadvantages. Good developer already knows these options, so intention of this post is not to discuss them, but to show you an interesting, new (at least for me) fourth approach to solve this problem, that I found recently.

Read More “Delete model with relations”

urlReferrer and opening new browser tab

To open particular URL in a new tab, you have at least two possibilities:

  • click a link with middle button (usually under mouse wheel) or
  • open a blank tab and copy-paste URL to URL bar.

There is slight difference it this (at least in Chrome) when it comes to urlReferrer in Yii:

  • in first case browser sets referrer correctly (i.e. Yii::app()->request->uUrlReferrer contains a valid URL),
  • in second approach URL referrer IS NOT set (i.e. Yii::app()->request->urlReferrer is an empty string).

The second situation is obvious. Opening a new tab means that browser does not have a history for it and thus it is unable to set urlReferrer correctly. However, it is better to keep this information in mind. If you rely on this information, you may get yourself (or your code) into a problem.

CGridView: the summaryText maddnes!

I’m finishing entry phase of my first big project (first big project, where I’m key project manager and lead developer, to be precise). Right now I’m after four days of sleeping for 5 hours and coding for remaining 19 hours each day. My brain simply bowls. In this specific situation, I’ve crafted a helper method, which makes mad-laughing or mad-screaming, each time I see it.

Read More “CGridView: the summaryText maddnes!”

Upload files via AJAX and fill up other model properties in the same time

There’s a comment to Yii 1.1: XUpload Workflow Wiki article, made by MeDroogie, who asks, how to handle situation, where file is correctly uploaded (via AJAX, in separate layer, handled by upload action), but form submission itself fails, as form processing action stops on some model’s validation errors.

I had the same problem with other AJAX uploader, that I think, I solved gracefully.

Keep in mind, that since solution, that I’m discussing in this article, is part of proprietary project, I cannot share any code. This is purely design or theoretical discussion.

Read More “Upload files via AJAX and fill up other model properties in the same time”

Logging user to LDAP directory under Yii

On certain systems and LDAP configurations you are required to use two-step login approach. It goes like this:

  1. Bind anonymously, by specifying only $bind = @ldap_bind($connection);.
  2. ldap_search for a given username. Search will return you a valid user’s DN (or NULL, if user does not exist).
  3. Using returned LDAP call another ldap_bind, this time attempting to actually login user.

Thus, in this approach you are not constructing your own DN, but relying on returned one instead.

Getting root path in Javascript files included in Yii application

A server-side root path in client-side Javascript code? Are you mad? Why would I need this? Well… For example, when referencing image files (placed on server, right?), that are using dynamic paths or for any other reasons can’t be added statically (for example using CSS).

Getting root path in Javascript files is a hard task itself. When do you need to combine this problem with Yii client-assets publishing mechanism, it can become even harder. However, I found nice, clean and simple solution, using HTML5’s data- attributes.

Read More “Getting root path in Javascript files included in Yii application”

Model saving vs. model validation when uploading files

Newbies to Yii and ActiveRecord design pattern, are often confused, what is difference between $model->save() and $model->validate(). though difference should be obvious, there are many code examples in the forum and Yii wiki, that proves, that many people still doesn’t understand it. Especially, when it comes to performing additional operations around saving model, like file upload.

Read More “Model saving vs. model validation when uploading files”

Using Twitter Bootstrap’s popups like real menu items

Twitter Bootstrap framework is fabulous and thanks to many Yii extensions supporting it (Yii-Boostrap, Yii-Booster, Yiistrap, YiiWheels and more) using it in own application is like snapping with fingers.

One of the best features of Bootstrap is a very easy way of creating menus and adding popup menus to elements (like buttons). However, in default implementation popups are oriented toward working just like a fancy links — i.e. redirecting browser to destination URL. In this article, you’ll find how force them to work as real menu items — i.e. capturing their onclick event and doing something with content.

Read More “Using Twitter Bootstrap’s popups like real menu items”

CGridView and CDetailView column or attribute value by expression

CDetailView does not use “deferred” evaluation like CGridView does on rendering rows. CDetailView gives you direct access to your model, while CGridView only to a per-row prepared data. So, to render CGridView‘s column or CDetailView‘s attribute row, you must use slightly different approaches. Here is how.

Read More “CGridView and CDetailView column or attribute value by expression”

Grouping controllers without using modules

Basic Yii application’s route consists of controller and action. Sometimes you have to add an extra separation layer, to group controllers and actions belonging to separate groups. Not everyone know, that you don’t have to use modules for this purpose. Controllers subdirectory can also be a considerable option. For me, this was a nifty discovery, so I decided to write this down as a personal memo.

Read More “Grouping controllers without using modules”

Sending app written in Yii through Gmail

Just a small notice, if you’re ever going to send a Yii application through Gmail. Make sure, that you browse archive, that you’re about to send, and delete all *.bat files from framework folder. If you miss that, Gmail will refuse to send email with such attachment, due to “executable file inside”.

Pity is, that this error pops up after attachment is uploaded to Gmail. An archive containing full framework code can take 10 MB or more and can waste some time to attache it to Gmail.

JS and PHP or Yii photo manipulation libraries

I was faced with a problem of picking a good photo manipulation library. Either client-side or server-side. Both for working with my newest Yii project. This article is a summary of my quick research in this field.

All JavaScript libraries works on Canvas, so require HTML5 and Canvas-enabled browsers. Most modern browsers supports both of them in newest versions.

The only PHP image manipulation library works mostly on uploaded image.

Read More “JS and PHP or Yii photo manipulation libraries”

Alternative module configuration that does not affect main configuration

In Yii main application is actually a module (core one) so each module configuration actually shares nearly everything what you can put to main application’s configuration file.

Thus, you can configure any Yii module, just as you would do with your main application. The only difference is that you don’t use external configuration file, but CModule::configure() function instead.

Read More “Alternative module configuration that does not affect main configuration”

Passing current or last page full URL as a part of URL

By using five separate PHP functions, in correct order, you can easily pass (code and decode) entire page’s URL as a parameter of any other script call, redirect etc. And be sure that it will be read (decoded) correctly, no matter, how long your URL is or what kind of characters it is using.

You can encode any URL (current page, last visited page or any otherwise important) and pass it in another URL in the way that your user won’t notice that you’re actually passing an URL.

Presented solution can potentially be used as URL shortening service. Generated URLs aren’t that short (as maybe expected), but for really long URLs it does provides some shortening.

Read More “Passing current or last page full URL as a part of URL”