Select2 library solution in Yii2 part 2 – database

To continue from the previous article …

http://www.jamesbarnsley.com/site/2016/10/24/select2-library-solution-in-yii2-part-1-introduction/

I will now talk about the database table needed to get my implementation of the Select2 library working. As mentioned earlier the original design for the database included a table for each set of Select2 relations. So if I wanted a Person to be able to select multiple Countries I would have a Select2 PersonCountries table, 1 table per relation.

The latest design for the database has just 1 table to store all of the Select2 relations used throughout the web software application. I find this easier as I can then use the Select2 like a module, whenever I want Select2 in my web software application I just drop in the code files along with the database table.

The database table I am using is as follows …

I will now run through what the columns in the database table are used for …

  1. id – unique integer for the record
  2. entityModel – the short name of the model class stored in lowercase characters, for example the “Person” model
  3. entityModelField – the name of the model property used on the form to select the related Select2 relations, for example “countries”
  4. entityModelID – the ID of the model, for example the ID of the “Person” model
  5. relationEntityModel – the short name of the related model class in lowercase characters, for example the “Country” model
  6. relationEntityModelID – the ID of the related model, for example the ID of the “Country” model
  7. deleted – a flag to determine if this record is deleted
  8. createdBy – the ID of the user this record was created by
  9. createdDate – the date this record was created
  10. updatedBy – the ID of the user who last updated this record
  11. updatedDate – the date this record was last updated

Please note that “id” is just a standard primary key and is not unique to this article also deleted, createdBy, createdDate, updatedBy and updatedDate are not unique to this article. These are just standard columns that I populate all of my tables with and are not really necessary for the purposes of this article.

The deleted column may be necessary if you are running the code exactly as explained in this article but the record could have just as easily have been hard deleted and hence the deleted column is just personal preference.

To know more about the standard columns I use and to auto populate these columns read the following article …

http://www.jamesbarnsley.com/site/2016/04/04/populating-standard-columns-in-a-database-table-using-yii-2/

The above database table is the table I use to power the Select2 library relations in my web software applications. An example use case for this can be described as follows …

You have a update Person form (entityModel) with a countries field (entityModelField) that allows the user to select various Countries that are related to the person (the ID of the Person is the entityModelID). You can select various Countries and save them to the Person. For each country saved a select2_library record will be created, the ID of the Country is the relationEntityModelID and the Country model itself is the relationEntityModel.

At this point a Select2Library model will need to be created for the “select2_library” table. In the example used in this article a relationship will need to be created between the Select2Library model and the Country model. This will need to be created using the “relationEntityModelID” like this …

All of the above will become clearer when actually running the code and seeing the results. The code to get this to run will be described in the follow up articles.

Select2 library solution in Yii2 part 1 – introduction

For those of you who do not know the Select2 library is a Javascript / JQuery replacement for select boxes. Although there are a few options to choose from in terms of using the Select2 field the configuration I will be looking at will be the multi select configuration.

The multi select configuration is useful for allowing the user to select things that require multiple choices, a typical example of this could be Tags but at a deeper level the multi select configuration is useful for allowing the user to create many to many relationships between models on forms.

An example Select2 field is shown below, allowing the selection of countries on a form …

Select2 Library

The above Select2 field could be on a add / edit person form allowing the many to many relation between People and Countries.

The solution I am providing in this article is all about saving and retrieving the Select2 data in a way that will streamline the process so a Select2 field can be attached to any of your forms within your web software application and it will just work out of the box.

The front-end part of the Select2 field is solved already as you can use the following Yii2 plugin for that …

http://demos.krajee.com/widget-details/select2

The above plugin displays the Select2 field on your Yii2 web forms. The above plugin passes the Select2 field data in the POST as an array. It is what to do with that data in a consistent and streamlined way that this article I am writing covers.

There are many ways the data could be handled for example the data could be JSON encoded and stored in a column in the database table then JSON decoded and displayed on the form when retrieving. Another way would be to have relationship tables for each relationship between models and store the data that way.

The way I have chosen is more like the later except that I do not have relationship tables for each relationship, I simply have 1 central Select2 relationship table that handles all Select2 relationships across the whole web software application.

What is the purpose of all this?

Most programmers would just use the Krajee Select2 plugin (link above) and leave it at that in terms of abstraction. The programmer would manually write the save / retrieve code specific to each instance of the Select2 plugin most likely in the Controller. The way I am using the Select2 plugin is to have methods that handle all of this.

If I want to use the Select2 plugin field in any of my forms, with just a few method calls the Select2 plugin field will be up and running, saving / retrieving data for any field / model. The way I am doing this also integrates better with Yii2 and makes use of the Yii2 relations to fetch associated Select2 data, so this way integrates deeper with Yii2.

Allowing the user to select items on a form and have the software application save those items as a many to many relationship is not always an easy task. This method takes away some of the complexity of that, so that I can have user defined many to many relationships between models / database tables.

Neptune – Web based lead management / tracking tool

So I am bored and I have spare time. How am I going to spend this spare time? I am going to re-introduce Neptune as an online Lead Tracking tool. As a freelancer I have had to store leads in TODO lists, Notes, Databases and free online CRM tools. None of these options where ideal. The CRM came close but it provides a ton of other features that I did not need and the other tools were too simple.

Neptune will be introduced as a lead tracking tool that can accessed through the web browser. It will be hosted by myself and will not be made available for download like the Neptune – Task Manager system was.

I aim to create a central area for the storage of leads. Leads will be added using a form. I aim to keep this project simple and straight to the point of storing leads. As the project has been stripped down, this will give me the opportunity to provide the tender loving care which a larger project like the Neptune Task Manager lacked. The ability to collect leads from external web forms is yet to be decided and may be included after the initial release.

The project will be released to the public through its own website. Neptune – Lead Tracker will be accessed through a single user account as I did not feel the need to allow people to create multiple user accounts under one company. The user login will be kept simple in that each company will have a single user account with which to access the software.

Look out for Neptune – Lead Tracker, expected release date is January 2017.

Update: Neptune – Lead Tracker has now been released, visit Neptune here … www.neptuneleadtracker.com

Transparent backgrounds using the Mac Preview tool

Downloading an image with a white background when you want the background to be transparent can be a pain. I have recently found a way of converting a colored background to a transparent background using nothing more than the standard Mac Preview tool. Before I found out this method I use to believe that I needed a proper graphics package to accomplish the task but now I realize I do not.

Follow the steps to turn a colored background into a transparent background. The way this process works is you are essentially just removing the colored background and re-saving the image …

  1. Click View -> Show Markup Toolbar, this will open the Markup Toolbar if it not already open.
  2. Click the Instant Alpha tool, image shown below.
  3. Mark a section of the colored background by using the mouse and dragging in the colored background area.
  4. Once the selection has been made click Edit -> Delete. This will remove the colored background.
  5. Save the image by clicking File -> Save.

Instant Alpha tool …

Your image will now be saved with the colored background removed. Thus having a transparent background.

Generating a unique random string for Model properties in Yii2

When building web software applications I sometimes need a way to generate unique random strings. Unique random strings can be used as character keys or tokens to identify database records without having to give away the database records ID number. I personally use unique random strings to produce clickable links in my “Request lost password” emails. The unique random string can be matched to a user record and the password can be re-created and sent to the user.

In this article I will show you a method of creating unique random strings. Yii2 already has a way of generating random strings but these will not always necessarily be unique, so in cases where they need to be, this method will come in use. The method I am about to show is named “generateUniqueRandomString”. I would recommend placing this method in a master Model as it is likely that you are going to want to use this method in more than 1 Model and want it exposed to many different Models.

I covered how to create master Models in a previous article which you can read here …

Create a master Model and Controller in Yii2

After you have created the master Model make sure you put the following “use” statement within it …

Now place the following “generateUniqueRandomString” method inside the master Model …

The above code can be explained as follows …

  1. Line 3 – Use the standard Yii2 “generateRandomString” method to generate a random string of characters
  2. Line 5 – IF statement to check whether the random string already exists for the Model, checked against the attribute (or DB column) passed in through the methods parameters
  3. Line 6 – If the random string does not exist already then return the random string
  4. Line 8 – If the random string does exist already, then recursively run the method again and try and generate a different random string that does not already exist

You can use the above method like follows …

The above code shows a book being found and a unique random string being generated for the books “characterKeyString” property. The book is then saved.

The length by default is set to 32 which means it will generate a 32 character unique random string. If you want to change the length just pass in the second parameter as the length you want to generate.

This method is very useful for when it is important that a random string is unique. I have personally used this method in my user creation, lost password request and file storage parts of my web software applications.

Creating a Utility class in Yii2

A Utility class is a place to put all common methods that will often need to be re-used in a web software application. During a previous article it was demonstrated how to create a master Model and Controller …

Create a master Model and Controller in Yii2

The master Model and Controller are good places to store a lot of re-used methods that relate to Models and Controllers. Sometimes though methods may not relate to Models and Controllers and need to re-used elsewhere in the web software application. This is where the Utility is useful. It is important to note that the Utility class is not designed to be instantiated as an object and should contain “static” methods that can act independently.

To create a Utility class create a new file called “Utility.php” and place it inside your “components” folder. Inside the “Utility.php” file place the following code …

The above code shows a blank Utility class ready to be populated with re-usable methods. Below shows a Utility class with an example method …

Notice how the method is defined as “static”, this is because the Utility class will not be instantiated into an object when used in the web software application. The method within the Utlity class can be used in the web software application as follows …

Include the Utility class into the file the Utility class will be used in …

Now call the desired Utility class method …

I personally create a Utility class in all my web software applications and find it a useful place to store re-usable methods that do not relate to Models and Controllers. Re-usable methods that do relate to Models and Controllers I store in the master Model and Controller, re-usable methods that do not relate to Models and Controllers I store in the Utility class.

Defining array data in Models using Yii2

Array data can be used in many places in a web application but one aspect of using array data in a Yii2 web application is to populate dropdown lists. Yii2 dropdown lists are populated with array data, the array data defines the items that will appear in the dropdown list.

Yii2 has special helpers when it comes to populating a dropdown list with database data namely ArrayHelper::map and the standard Yii2 Models. Populating a dropdown list with database data will not be covered in this article. This article is about populating a dropdown list using hard coded data.

In the example below you are shown a way of storing the data in a magic property for a number of colour choices that are wanting to be used in a dropdown list within a add / edit book form. The method below would reside in the Model in this case a Book Model …

Now inside the form the dropdown list is rendered to use the data in the above method as follows …

If the standard “prompt” setting is needed for the dropdown list or there are some other specific items needed in the data they can be kept separate from the hard-coded data array in the Model like follows …

After this data has been saved the data can be displayed within your application by writing a method to format the selected “colourChoice” within your web application …

The above method can be used as follows …

If the data could be classified as being more global than a “books colour choice” for example a “yes or no” dropdown list, then it is possible to place the above methods inside a master Model which will mean that the dropdown list data will be accessible from any Model that extends the master Model …

Create a master Model and Controller in Yii2

I have used the above methods including placing the above methods in my master Model to store all the hardcoded data used for dropdown lists as well other purposes to great effect. The above methods are much better than hardcoding the data in the views as having the data in the Models is a more natural place for the data to reside as well as being accessible to multiple parts of the web application.

Populating standard columns in a database table using Yii 2

When creating web based software applications we sometimes want to have a standard way of populating a variety of database table columns which we intend to appear in multiple database tables within our software application. These columns may generally include the following …

  1. userID – for storing the user ID of the user who owns the record
  2. createdDate – for storing the date the record was created
  3. createdBy – for storing the ID of the user who created the record
  4. updatedDate – for storing the date the record was updated
  5. updatedBy – for storing the ID of the user who updated the record

The above are the standard columns I normally use within my database tables when creating web applications. I deliberately separate the userID from the createdBy and updatedBy. As I look at the createdBy and updatedBy as more of a audit trail and the userID as the actual owner of the record and the foreign key which connects that record to the users table.

In this article I am going to show you a method to populate these values automatically. These fields will be populated whenever you save a record within the web application.

As I presume you are going to want this method exposed to more than 1 Model within the web application I advise you first read the earlier article I wrote about creating master Models and Controllers …

Create a master Model and Controller in Yii2

Master Model and Controller classes are Model and Controller classes which are a parent class to all Model and Controller classes within your web application. All of the methods within the master Model and Controller classes are exposed to the Model and Controller classes within your web application that extend from those master Model and Controller classes.

Now that you have created a master Model make sure you have the following use statements within your master Model …

Now put the following method in your master Model …

The Yii2 beforeSave method will fire whenever a Model is saved within your web application. As the beforeSave method is used in our master Model, the beforeSave method will fire whenever a Model is saved providing that Model extends from our master Model.

The method above is made up of 5 IF statements each setting a variable on the Model. The variables on the Model are those 5 database table columns discussed at the beginning of the article. The above code can summarized as follows …

  1. Line 1 – beforeSave method, $insert variable is true or false depending on whether this is inserting a new record or updating an existing record. Yii2 sets the $insert automatically
  2. Line 3 – IF statement checks to see … userID column exists in table, this record is a new record being inserted, the user is logged in and hence has a userID, the userID variable has not already been set on the Model
  3. Line 4 – Set the userID variable on the Model to be the logged in users user ID
  4. Line 6 – IF statement checks to see … createdDate column exists in table, this record is a new record being inserted
  5. Line 7 – Set the createdDate variable on the Model to be the current datetime
  6. Line 9 – IF statement checks to see … createdBy column exists in table, this record is a new record being inserted, the user is logged in and hence has a userID
  7. Line 10 – Set the createdBy variable on the Model to be the logged in users user ID
  8. Line 12 – IF statement checks to see … updatedDate column exists in table
  9. Line 13 – Set the updatedDate variable on the Model to be the current datetime
  10. Line 15 – IF statement checks to see … updatedBy column exists in table, the user is logged in and hence has a userID
  11. Line 16 – Set the updatedBy variable on the Model to be the logged in users user ID
  12. Line 18 – beforeSave return true, the Model will not save unless this method returns true

If you need to use the beforeSave method in a Model that extends from the master Model and you want to retain the functionality of the beforeSave in the parent model you will need to call the parent beforeSave as follows …

Please note you do not have to use the beforeSave method in a Model that extends from the master Model for the beforeSave method in the Master Model to work. The above example is only shown in case you want to run further code in the extended Model that happens on the beforeSave whilst still retaining the functionality in the master Model. If the extended Model has no beforeSave method that is fine, the code will still run in the master Model and populate the database columns with the data.

It is also worth noting that you can also use the afterFind to format the data when finding Model records …

The above example shows the automatic formatting of the created and updated dates for user interface display purposes within our web application. The examples in this article can be extended to include any data or code you like in the beforeSave and afterFind methods. I personally use these methods in the web software applications to save and format general data that is used through many of the database tables within the web software application.

This method reduces code duplication, reduces chance for errors as the code is not in multiple places, keeps the code neat and tidy by only being in one place. This method frees you up to concentrate on other areas of the web software application.

Recursive deletion in Yii2 using Yii2 Models and Model relations

Sometimes when creating delete functionality within a web application we want to delete more than the record the user is trying to delete. Some records relate to other records and when a record is deleted we want to delete the records that are related to that record because those records no longer serve a purpose.

Some developers like to do recursive deletion at the SQL level using Cascading Deletion, however I and some other developers prefer to do it at the code level. In this case that would be PHP using the Yii2 framework.

To develop the recursive deletion in Yii2 it would be best to create a master Model, as the method I am about to explain to you is more than likely going to be used in more than 1 Model. As most likely you will want all of your Models to have this functionality exposed to them.

A master Model is a Model in which all other Models extend from, the extended Models have access to the methods within the parent Model, in this case the deleteRecursive method. To learn how to build this you can read my previous article …

Create a master Model and Controller in Yii2

After you have created your master Model you can place the following deleteRecursive method within it …

The recursiveDelete above can be explained as follows …

  1. Line 3 – foreach to loop around each item in the relations array
  2. Line 5 – check whether the relation for the Model is an array, this checks whether the relation is a ONE (not array) or a MANY (array). It uses the name provided in the relations array to call the relation
  3. Line 7 – foreach to loop through all of records returned by the relation. In this case that would handle a MANY relation.
  4. Line 8 – call the deleteRecursive function recursively. This will then use the deleteRecursive method of the related Model and delete the record and related records within that Model as well
  5. Line 12 – check to see whether this Model has a related Model, this would be a ONE relation
  6. Line 13 – call the deleteRecursive function recursively. This will then use the deleteRecursive method of the related Model and delete the record and related records within that Model as well
  7. Line 19 – delete the current record

In the extended Models you can call the deleteRecursive method as follows, make sure you setup your relations as you normally would in Yii2 using the Model relations, in the relations array put the names of the relations you have set up …

The “authors”, “pages”, “prices” are the relations / relation names used in this example.

This method is then called as follows …

The above will delete the Book record as well as “authors”, “pages”, “prices” related records and if those Models contain a deleteRecursive method those Models relations will also be deleted.

The deleteRecursive method above can be also be called as follows …

Due to the way the deleteRecursive method was set up you can override the relation / relation names at the time of deletion. This method has proved very useful for me and is a neat and tidy way of deleting Model records along with their related Model records.

animate.css

I use animate.css to power the left side menu animation on this website, when the page loads you will see the left side menu zoom into the website. The animate.css library was recommended to me by a colleague as quite often emails are sent sent around which include links to interesting code libraries and tools.

You can download animate.css at its website …

https://daneden.github.io/animate.css/

Using animate.css all you have to do is drop in a CSS class into the HTML element you want to animate and hey presto you have an animated HTML element. The animate.css is easy to setup, you just include the “animate.css” stylesheet and you are good to go. The animate.css library includes around 75 different animations to choose from.

You can choose to have the animation in a infinite loop by adding a further CSS class “infinite” to the HTML element. Further settings can be customized by extending the CSS file including duration, delay and a specific iteration count.

If you are looking for a quick way to add animations to your website give animate.css a try.