Internal system – Toolkit

I have been using a web based product called ActiveCollab for sometime now …

https://activecollab.com

I have been using ActiveCollab since version 4. When ActiveCollab 5 was introduced it had a complete redesign, less features and a more slick user interface.

More features have been introduced to ActiveCollab 5 though since it was first released.

ActiveCollab is a project management system that also handles Time Tracking and Invoicing plus more.

I will continue using ActiveCollab for projects / task management however for other areas of my business I have created my own internal tool which I have named “Toolkit”.

I built my own system because I wanted a system that would do the following …

Estimate earnings
Fixed fee and retainer projects are entered into the Toolkit. The Toolkit can then estimate monthly and yearly earnings based on the projects entered. The projects also includes a way for me to manage all the projects I am working on.

Incomings
The Toolkit has an area in which all incomings can be entered. The incomings can then be exported in a format appropriate for my accountant.

Outgoings
The Toolkit has an area in which all outgoings can be entered. The outgoings can then be exported in a format appropriate for my accountant.

Mileage
The Toolkit has an area in which all mileages can be entered. The mileages can then be exported in a format appropriate for my accountant.

Leads
The Toolkit has an area in which leads can be managed. I actually pulled this area out of the Neptune – Lead Tracker – http://www.neptuneleadtracker.com software system.

CRM
The Toolkit includes an area in which all the companies and people I have worked for can be managed. ActiveCollab does actually include this feature but the Toolkit version allows more advanced search features and has fields on the create / update forms to match my exact needs.

Timetracking
The Toolkit includes an area in which all time entries can be tracked. ActiveCollab does have this feature.

Invoicing
The Toolkit includes an area in which invoices can be created. Invoices can also be generated from time entries. ActiveCollab does include this feature but the Toolkit version matches my exact needs precisely.

Notes
The Toolkit includes an area to keep notes. ActiveCollab does include this feature.

Files
The Toolkit includes an area to upload files. ActiveCollab does include this feature.

ActiveCollab has a more slick, beautiful user interface but in terms of functionality built specifically for myself obviously the Toolkit wins.

The Toolkit is primarily made up of CRUD screens, no fancy UI / Ajax heavy screens here. Just datagrids and buttons.

I am in the process of live testing the Toolkit I have built and will be moving various functions of my business over to the Toolkit.

King of Adem – progress update – building queue

Progress has been made on the King of Adem project. For those of you not familiar with this project please read the original King of Adem post at …

http://www.jamesbarnsley.com/site/2017/08/13/king-of-adem/

Since the update I have been primarily working on the building queue. The building queue is the queue which buildings get inserted into when a player wishes to construct a building in one of his / her regions.

To get to the construct building screen the user has to be in one of his / her regions so those areas to get to that screen had to be part built.

The areas part built are namely user, game, region and building. Once on the construct building screen the user can select from a list of buildings that can be constructed.

Each building is validated on a case by case basis and if it does not pass the validations the building cannot be constructed, here are some of the validations so far …

Check fund available
The player must have the correct amount of fund available to construct the building. The amount of funds available is the players start of turn funds subtracting any funds that have been used in the current turn.

For example player may have started with 1000 coins, if a player constructs a building for 300 coins then the program gets the players start of turn funds but substracts 300 coins because it knows a building worth 300 coins was requested to be constructed this current turn.

Check building queue full
The building queue may only allow so many buildings to be in the queue at any one time for each region. Currently this number is set at 5 and the number is stored in a config file.

Check building already built
Check if the building has already been constructed in the region. Each building has a “constructionLimitPerRegion” variable which stores the number of times that particular building may be constructed in each region.

Check dependent buildings constructed
Each building can have what are called dependent buildings. These are buildings which need to be constructed first before you can build the current building.

Also the validation knows whether a building is an upgrade of an existing building or a completely different building that just happens to depend on another building being constructed.

All kinds of checking had to be implemented for this validation, whether building is an upgrade / dependant or just dependant, whether advanced tier buildings already exist for lower dependant buildings, whether lower dependant buildings already exist etc.

Check advanced tier building exists
Check if an advanced tier building already exists for the current building wanting to be constructed. If the advanced tier building already exists then there is no reason to build the current building.

Again this needs to take into account that some buildings can be constructed more than once so in some instances it may need to allow the building to be constructed even though the lower building has already been constructed.

The above validations are run everytime a user issues the command to insert a building into the building queue for a particular region. These validations are run from the “Building” Model. Each building is also given its own Model, the hierachy is like as follows …

\yii\db\ActiveRecord -> \app\components\ActiveRecord -> \app\models\Building -> \app\models\BuildingTownBarracks

Or …

\yii\db\ActiveRecord -> \app\components\ActiveRecord -> \app\models\Building -> \app\models\BuildingPort

etc.

I can run special validations for specific buildings by placing those validations in the specific building class. Those validations will only run for the specific building and not all buildings.

That is as far as I have got so far. Still a long, long way to go, more updates to come soon.

King of Adem

The latest personal project I am working on which also happens to be the largest personal project I have worked on so far.

King of Adem is a game for tabletop minature wargamers. Players manage their kingdom through the app. Kingdoms consist of a number of a territories, each player starts with one.

In each territory there is a capital city in which buildings can be constructed. Buildings provide benefits like more money or the ability to recruit armies.

When 2 armies collide by moving into each other the players can then resolve the battle as normal by playing their normal game of tabletop minatures.

The game takes place on an island called Adem. Adem is a recently discovered island where each player is fighting for control. You fight to become the “King of Adem” by conquering the whole island.

Although Adem is stated as “recently” discovered, this only means “recently” in the grand scheme of things. Adem actually has a number of Kings / Factions already on the island and each Kingdom has some infrastructure.

The project is currently divided into 3 parts …

King of Adem Diagram

Part 1 – Game Server
The Game Server is currently in construction and is being developed using the Yii 2 framework written in PHP. The database is MySQL. The server takes view requests and command requests from the client application.

View requests provide data to the client in JSON format. This data has everything needed to render views for the game for example, building, army, territory data.

Command requests provide data to the server about interactions happening in the client application. For example move commands, construct building commands etc.

The decision to use View / Command requests was chosen instead of opening the server up entirely.

Essentially one option could have been for each Data model on the server to have a view, insert, update, delete request to use for either commands, views or both.

This would give the client more freedom at the cost of putting more logic onto the client.

As the first client is being developed using IOS and IOS uses a view per screen type of structure then View requests make sense. Giving the client the exact data the client needs in order to render the view.

Part 2 – Game Test Client
The Game Test Client is currently being developed alongside the Game Server and serves as a testing ground for the development of the server.

The Game Test Client can send View requests to the server and read / present the data from the server in a user friendly way. The Game Test Client can send command requests to the server.

The Game Test Client is being developed using the Yii 2 framework written in PHP. The Game Test Client is my own personal client for testing the server and is not the actual client the end user / player will be using.

Part 3 – IOS Game Client
The IOS Game Client is the actual client the end user / player will be using to play King of Adem. The IOS Game Client as you might have guessed will be an IPhone application. There may also be the ability to run the application on the IPad as well.

I decided to develop the IOS Game Client because I wanted the game to be portable and it cannot get much more portable than having the game on your phone.

I also choose the game to be an IOS application because I want to improve my IOS skills and offer IOS development as part of the everyday services I offer to my clients.

Once these 3 parts are complete the game will be playable and released to the public. Part 1 and 2 are already in construction, Part 3 will be constructed after parts 1 and 2 and completed.

After the game has been released to the public, a number of other client applications could potentially be developed including an Android version and a full game client developed in Unity3D or similar.

The IOS client will be more management like as opposed to a graphical game. The IOS application could include graphics etc, but it will not be at the level of a full game like experience. This is why I suggest a later developed Unity3D or similar game engine development.

I will be keeping everyone informed of the development of this game through the blog so keep checking back for further updates.

Solution for using DatePickers on forms in Yii2

Sometimes in web software applications we need to collect dates such as a start date or end date using forms. In this article I will be using the Kartik DatePicker widget which can be found here …

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

For the purposes of this article a master Model will need to be created. I discussed how to create master Models and Controllers in the following article …

Create a master Model and Controller in Yii2

So based on the master Model now being created the article can continue. Add the field to the form using code similar to this. Include the plugin in the form …

Add the field to the form …

In the master Model 2 methods needed to be created …

And …

These methods can be called to save the “date” data to the database from any of the child Models. The best place to call the methods would be in the “beforeSave” and “afterFind” methods as follows …

And …

Depending on how you have setup the validations for the “date” attribute you may need to run the “saveDateFormat” and “dateFormat” methods in the “beforeValidate” and “afterValidate” methods as well as the “beforeSave” and “afterFind”.

This depends on whether your validations are formatting the date as the date would be saved to the database or validating against the format the date appears on the form.

If your validations validate against the format the date saves to the database then calling “saveDateFormat” and “dateFormat” methods in the “beforeValidate” and “afterValidate” methods will not be needed.

I generally setup my validations so I do not need to run the “saveDateFormat” and “dateFormat” methods in the “beforeValidate” and “afterValidate” methods only through the “beforeSave” and “afterFind” methods.

Using the above code you can implement multiple datepickers on the same form or across different forms. Follow the same logic, add the field or fields to the form and call the “saveDateFormat” and “dateFormat” methods from the child Model.

Select2 library solution in Yii2 part 4 – retrieving the data

To continue on from the previous article I wrote about saving the Select2 data …

http://www.jamesbarnsley.com/site/2016/11/07/select2-library-solution-in-yii2-part-3-saving-the-data/

I will now talk about how to the retrieve the stored Select2 data so that the data can be displayed on the front-end Select2 field. Following on from the Task / Countries example, place the following “loadSelect2Items” method inside the Master model or Task model if you did not create a Master model …

The code above can be explained as follows …

  1. Line 3 – return the array of Select2 data using the “array_map” function
  2. Line 4 – store the related entity models name into a variable, in this case that would be the Country models name. This uses the Country relationship that was created in “Part 2” of this article series
  3. Line 5 – store the IDs of the related relationship entity model in the return data, in this case that would be the IDs of the Country model records
  4. Line 6 – find all the records for the model / model property in the “select2_data” table, in this case that would be the Task model and “countries” property

The next step is use the “loadSelect2Items” in the Task model to the load the Select2 data into the “countries” property, place the following inside the “afterFind” method of the Task model …

So that concludes the Select2 library solution for Yii2. I have covered the creation of the necessary database table and the read / write methods for reading / writing the data.

After the initial methods have been setup this solution will provide you with a way of easily putting a Select2 field on your forms that allows for many to many relationships between models with just a couple of line of code.

Select2 library solution in Yii2 part 3 – saving the data

To continue from the previous article …

http://www.jamesbarnsley.com/site/2016/10/31/select2-library-solution-in-yii2-part-2-database/

Once the database table has been created the code can now be written to display the Select2 field on the form and save the Select2 data to the database table.

In this article I will demonstrate the Select2 functionality as though we are wanting to add “Tags” to a Task model. When I say “Tags” I mean the standard web term for Tags. Essentially these are words that you can tag to an entity for example a WordPress article that categorizes the WordPress article using the tags allowing a user to search by those words.

When I say Task model, this is a fictional model in a Yii2 application that will allow the user to create and update tasks. For the purposes of this article it is assumed you will create your own Task model along with the controller and views. Create a standard CRUD for tasks possibly giving each task a name and a description.

You will need to create a Tag database table to store the Tag data along with its associated model. Create a database table with “id” field for the primary key and a “name” field to store the Tag name. Create a standard Yii2 model for the Tag table, this model does not need any methods inside it, it is a blank Yii2 model that extends ActiveRecord.

After you have created your task CRUD functionality and the Tag database table with associated model the Select2 functionality can be integrated.

First the field is added to the form using the Kartik Select2 plugin. The plugin can be found here …

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

Add the field to the form using code similar to this. Include the plugin in the form …

Add the field to the form …

Create a “tags” property in the Task model, this will be used to store the tags field data on both saving and retrieving …

Now the field is added to the form and you have a property in which to store the array of data which the Select2 library needs in order to function. Next you need to use the “saveSelect2Items” items method as shown below to save the array data in the “tags” property to the database.

The “saveSelect2Items” method can be placed inside the Task model but it would be better in some kind of global area such as a Master model as is it likely that you will want to use the functionality in more than one model / form. I wrote an article on how to create Master models which can be read here …

http://www.jamesbarnsley.com/site/2016/03/14/create-a-master-model-and-controller-in-yii2/

The “saveSelect2Items” method is as follows …

The code above can be explained as follows …

  1. Line 3 – get the class name of the model object in this case that would be the Task model and convert it to lowercase characters
  2. Line 4 – get the class name of the store model object in this case that would be the Tag model and convert it to lowercase characters
  3. Line 5 – get the Select2 array data of the model object in this case that would be the “tags” property in the Task model
  4. Line 7 – if the model object Select2 property is not empty, in this case that would be the “tag” property
  5. Line 9 – get the current stored records in relation to the model and model properties we are using. In this case the Task model, Tag model and “tag” property
  6. Line 11 – loop through the currently stored records
  7. Line 13 – if the related model object ID is not in the model object property array data. In this case that is if the Tag ID is not in the “tag” property array data
  8. Line 15 – set the deleted flag to 1, which indicates deleted
  9. Line 16 – save the record
  10. Line 22 – loop through the array data in the model object property, in this case that is the Task model “tags” property
  11. Line 24 – check to see whether a record already exists in relation to the model and model properties we are using. In this case the Task model, Tag model and “tag” property
  12. Line 26 – if no existing record can be found
  13. Line 28 to 33 – create a new Select2 record and set the properties
  14. Line 35 and 36 – save the new Select2 record but if it does not save then return false
  15. Line 42 – the else part of the original if statement, if there is no array data in the “tags” property
  16. Line 44 – delete all the existing records for the model we are dealing with. In this case that is the Task model

As mentioned in the database article the “saveSelect2Items” method soft deletes the unwanted Select2 records with a little adaptation this could be altered to hard delete the records.

Now that the “saveSelect2Items” has been created you can call it in your Task model by placing the following code in the “beforeSave” method of the Task model …

The first parameter of the “saveSelect2Items” is the property used to store the Select2 array data, the second parameter is the original model that uses the Select2 field on the form in this case that is the Task model. The third parameter is the relation model in this case that is the Tag model.

The code up to this point puts a Select2 field on a form and saves the Select2 data when the form is saved. If you go back to the form the Select2 field will not be populated with the saved data yet as that is covered in the next article which talks about retrieving the Select2 data.

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.

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.