Posts categorized “Yii”.

Yii 1, PHP 7.1, yii-pdf and Mpdf

Mpdf 6.x only supports PHP versions up to 7.0. If you’re upgrading your local machine, or hosting environment to PHP 7.1 or beyond (you should be) then you’ll need to upgrade your Mpdf install to something more recent than 6. That requires a few changes.

Now just to make things complex here, the latest version of Mpdf happens to be version 7.1. From here on I’ll try and prefix any version numbers with either PHP or Mpdf.

Mpdf 7 and greater is composer install only. You could still download and copy the files into place, but I highly recommend using composer to manage your vendor packages in Yii (and Yii 2). It will save you hours and hours over time.

Mpdf 7 has updated it’s class name to be Mpdf with a capital M, and changed it’s construct method to accept a config array instead of separate parameters. Small but significant updates we’ll have to deal with.

If you’re already using composer, then you’ll have a composer.json file in the root of your codebase, and in there you should have a line which starts “mpdf/mpdf”.

That line will probably end something like “^6.0” orĀ “^6.4”

Assuming it’s less than “7.x.x” we’re going to update with composer.

Back up your codebase. I shouldn’t have to mention it, but do it, honest.

Run composer require mpdf/mpdf “^7.0”

That line will install the latest version, Mpdf 7.1, allow anything newer to be installed if you update in the future, and change your composer.json file (and likely your composer.lock file too) to include the newer information.

So we have the latest code, but we need to update Yii to use it.

yii-pdf wraps mpdf and makes it available via Yii->app()->ePdf->mpdf()

The yii-pdf config to get it functioning with Mpdf 7+ will look something like this:

'ePdf' => [
	'class' => 'application.extensions.yii-pdf.EYiiPdf',
	'params' => [
		'mpdf' => [
			'librarySourcePath' => 'vendor.mpdf.mpdf.src.*',
			'constants' => [
				'_MPDF_TEMP_PATH' => Yii::getPathOfAlias('application.runtime'),
			],
			'class'=>'\Mpdf\Mpdf',
			'defaultParams' => [
				'mode' => '',		//  This parameter specifies the mode of the new document.
				'format' => 'A4',	// format A4, A5, ...
			],
		],
	],
],

Note the librarySourcePath and class values. You can add your existing defaultParams and anything else which was in your preferences previously.

The last part is to update all places where you call the mpdf library. Previously it would have looks something like:

$mpdf = Yii::app()->ePdf->mpdf('UTF-8', '', 0, '', 15, 15, 15, 15, 8, 8);

We now convert the config to be an array of values:

$mpdf = Yii::app()->ePdf->mpdf(['UTF-8', '', 0, '', 15, 15, 15, 15, 8, 8]);

And that should be it. Update using composer, update your config, update all locations you instantiate mpdf. Then check your pdf generating code is still functioning.

Yii (and Yii2) wildcard / catch all url rules

Sometimes you might want to do various checks of the url in yii config main and then send every other request to a particular controller.

The rule you need to add last to the urlManager is…

'(.*)' => 'controller/action',

'<url:(.*)>' => 'controller/action',

… and now any rule that isn’t matched previously will end up being sent to your defined controller and action.

In Yii2 you can also do the same:

'<url:(.*)>' => 'controller/action',

Reordering Yii Results Without Another Select

fetchit-21

In case you weren’t aware, you can reorder the results you already have from a previous Yii call. For example…

 
$users = User::model()->findByPk(2);
$posts = $user->posts(array('order'=>' created Desc '));

There were just ordered our users posts by created date descending.

We can also do filtering…

 
$users = User::model()->findByPk(2);
$posts = $user->posts(array('condition'=>' status=1 '));

So now we only have active posts. We could also combine a condition and a status.

You can find out more here: http://www.yiiframework.com/doc/guide/1.1/en/database.arr#dynamic-relational-query-options

Yii (and Yii2) UpdateAll Examples

This is a simple example of how to use Yii’s updateAll():

In this example we want to set status = 1 WHERE type_id = 1 AND status = 0

Note this is a simple example where we are only updating one column and using a string for our condition. There are more complex options available.

$rows = Comment::model()->updateAll(array( 'status' => 1 ), 'type_id = 1 AND status = 0' );

So as you can see first comes an array of column => new_value pairs, then a condition string which is pretty much used as the WHERE clause.

An example of updating more than one column:

$rows = Comment::model()->updateAll(array( 'status' => 1, 'updated' => '2011-08-25 09:33:23' ), 'type_id = 1 AND status = 0 ' );

Update. Yii2 example:

Updating a single column:

$rows = Comment::updateAll(['status' => 1], 'type_id = 1 AND status = 0');

Updating multiple columns:

$rows = Comment::updateAll(['status' => 1, 'updated' => '2011-08-25 09:33:23'], 'type_id = 1 AND status = 0' );

Yii – “Model.id” not defined for CArrayDataProvider and CSqlDataProvider etc

fetchit-21

There is a Yii error I come across every now and again, and each time it stumps me.

If you ever get SomeModel.id not defined error when trying to put your dataprovider results into a cgridview or similar then it’s likely because

1) Your model doesn’t have an id column, it might use file_id or user_id etc instead and

2) You haven’t defined which other column should be used.

We do this using what’s known as keyField:


new CArrayDataProvider($users, array('keyField' => 'user_id'));
new CSqlDataProvider($users, array('keyField' => 'user_id'));