Thursday, November 30, 2017

How to Remix an Electronic Progressive XMAS Song

10 Best Free Mac Photo Apps

Build a Music App With an Android App Template

The Difference Between Typography & Hand Lettering: Typography in 60 Seconds

Inheritance and Extending Objects With JavaScript

How to Update Your App for iOS 11: Drag and Drop

How to Write an Effective Follow Up Email After No Response

Store Everything With Elixir and Mnesia

Store Everything With Elixir and Mnesia

In one of my previous articles I wrote about Erlang Term Storage tables (or simply ETS), which allow tuples of arbitrary data to be stored in memory. We also discussed disk-based ETS (DETS), which provide slightly more limited functionality, but allow you to save your contents to a file.

Sometimes, however, you may require an even more powerful solution to store the data. Meet Mnesia—a real-time distributed database management system initially introduced in Erlang. Mnesia has a relational/object hybrid data model and has lots of nice features, including replication and fast data searches.

In this article, you will learn:

  • How to create a Mnesia schema and start the whole system.
  • What table types are available and how to create them.
  • How to perform CRUD operations and what the difference is between "dirty" and "transactional" functions.
  • How to modify tables and add secondary indexes.
  • How to use the Amnesia package to simplify working with databases and tables.

Let's get started, shall we?

Introduction to Mnesia

So, as already mentioned above, Mnesia is an object and relational data model that scales really well. It has a DMBS query language and supports atomic transactions, just like any other popular solution (Postgres or MySQL, for example). Mnesia's tables may be stored on disk and in memory, but programs may be written without the knowledge of the actual data location. Moreover, you may replicate your data across multiple nodes. Also note that Mnesia runs in the same BEAM instance as all other code.

Since Mnesia is an Erlang module, you should access it using an atom:

Though it is possible to create an alias like this:

Data in Mnesia is organized into tables that have their own names represented as atoms (which is very similar to ETS). The tables can have one of the following types:

  • :set—the default type. You can't have multiple rows with exactly the same primary key (we'll see in a moment how to define a primary key). The rows are not being ordered in any particular manner.
  • :ordered_set—same as :set, but the data are ordered by the primary key. Later we will see that some read operations will behave differently with :ordered_set tables.
  • :bag—multiple rows may have the same key, but the rows still cannot be fully identical.

Tables have other properties that may be found in the official docs (we will discuss some of them in the next section). However, before starting to create tables, we need a schema, so let's proceed to the next section and add one.

Creating a Schema and Tables

To create a new schema, we will use a method with a quite unsurprising name: create_schema/1. Basically, it is going to create a new database for us on a disk. It accepts a node as an argument:

A node is an Erlang VM that handles its communications, memory, and other stuff. Nodes may connect to each other, and they are not limited to one PC—you can connect to other nodes via the Internet as well.

After you run the above code, a new directory named Mnesia.nonode@nohost will be created that is going to contain your database. nonode@nohost is the node's name here. Before we can create any tables, however, Mnesia has to be started. This is as simple as calling the start/0 function:

Mnesia should be started on all participating nodes, each of which normally has a folder to which the files will be written (in our case, this folder is named Mnesia.nonode@nohost). All the nodes that compose the Mnesia system are written to the schema, and later you may add or remove individual nodes. Moreover, upon starting, nodes exchange schema information to make sure that everything is okay.

If Mnesia started successfully, an :ok atom will be returned as a result. You may later stop the system by calling stop/0:

Now we can create a new table. At the very least, we should provide its name and a list of attributes for the records (think of them as columns):

If the system is not running, the table won't be created and an {:aborted, {:node_not_running, :nonode@nohost}} error will be returned instead. Also, if the table already exists, you will get an {:aborted, {:already_exists, :user}} error.

So our new table is called :user, and it has three attributes: :id, :name, and :surname. Note that the first attribute in the list is always used as the primary key, and we can utilize it to quickly search for a record. Later in the article, we'll see how to write complex queries and add secondary indexes.

Also, remember that the default type for the table is :set, but this may be changed quite easily:

You may even make your table read-only by setting the :access_mode to :read_only:

After the schema and the table are created, the directory is going to have a schema.DAT file as well as some .log files. Let's now proceed to the next section and insert some data to our new table!

Write Operations

To store some data in a table, you need to utilize a function write/1. For example, let's add a new user named John Doe:

Note that we've specified both the table's name and all the user's attributes to store. Try running the code... and it fails miserably with an {:aborted, :no_transaction} error. Why is this happening? Well, this is because the write/1 function should be executed in a transaction. If, for some reason, you do not want to stick with a transaction, the write operation may be done in a "dirty way" using dirty_write/1:

This approach is usually not recommended, so instead let's build a simple transaction with the help of the transaction function:

transaction accepts an anonymous function that has one or more grouped operations. Note that in this case the result is {:atomic, :ok}, not just :ok as it was with the dirty_write function. The main benefit here is that if something goes wrong during the transaction, all operations are rolled back.

Actually, that's an atomicity principle, which says that either all operations should occur or no operations should occur in case of an error. Suppose, for example, you are paying your employees their salaries, and suddenly something goes wrong. The operation stops, and you definitely do not want to end up in a situation when some employees got their salaries and some not. That's when atomic transactions are really handy.

The transaction function may have as many write operations as needed: 

Interestingly, data can be updated using the write function as well. Just provide the same key and new values for the other attributes:

Note, however, that this is not going to work for the tables of the :bag type. Because such tables allow multiple records to have the same key, you will simply end up with two records: [{:user, 2, "Kate", "Brown"}, {:user, 2, "Kate", "Smith"}]. Still, :bag tables do not allow fully identical records to exist.

Read Operations

All right, now that we have some data in our table, why don't we try to read them? Just as with write operations, you may perform read in either a "dirty" or "transactional" way. The "dirty way" is simpler of course (but that's the dark side of the Force, Luke!):

So dirty_read returns a list of found records based on the provided key. If the table is a :set or an :ordered_set, the list will have only one element. For :bag tables, the list can, of course, have multiple elements. If no records were found, the list would be empty.

Now let's try to perform the same operation but using the transactional approach:

Great!

Are there are any other useful functions for reading data? But of course! For example, you may grab the first or the last record of the table:

Both dirty_first and dirty_last have their transactional counterparts, namely first and last, that should be wrapped in a transaction. All of these functions return the record's key, but note that in both cases we get 2 as a result even though we have two records with the keys 2 and 3. Why is this happening?

It appears that for the :set and :bag tables, the dirty_first and dirty_last (as well as first and last) functions are synonyms because the data are not sorted in any specific order. If, however, you have an :ordered_set table, the records will be sorted by their keys, and the result would be:

It is also possible to the grab the next or the previous key by using dirty_next and dirty_prev (or next and prev):

If there are no more records, a special atom :"$end_of_table" is returned. Also, if the table is a :set or :bag, dirty_next and dirty_prev are synonyms.

Lastly, you may get all the keys from a table by using dirty_all_keys/1 or all_keys/1:

Delete Operations

In order to delete a record from a table, use dirty_delete or delete:

This is going to remove all records with a given key.

Similarly, you can remove the whole table:

There is no "dirty" counterpart for this method. Obviously, after a table is deleted, you cannot write anything to it, and an {:aborted, {:no_exists, :user}} error will be returned instead.

Lastly, if you are really in a deleting mood, the whole schema can be removed by using delete_schema/1:

This operation will return a {:error, {'Mnesia is not stopped everywhere', [:nonode@nohost]}} error if Mnesia is not stopped, so don't forget to do so:

More Complex Read Operations

Now that we have seen the basics of working with Mnesia, let's dig a bit deeper and see how to write advanced queries. First, there are match_object and dirty_match_object functions that can be used to search for a record based on one of the provided attributes:

The attributes that you do not care for are marked with the :_ atom. You may set only the surname, for example:

You may also provide custom searching criteria using select and dirty_select. To see this in action, let's firstly populate the table with the following values:

Now what I want to do is find all the records that have Will as the name and whose keys are less than 5, meaning that the resulting list should contain only "Will Smith" and "Will Smoth". Here is the corresponding code:

Things are a bit more complex here, so let's discuss this snippet step by step.

  • Firstly, we have the {:user, :"$1", :"$2", :"$3"} part. Here we are providing the table name and a list of positional parameters. They should be written in this strange-looking form so that we can utilize them later. $1 corresponds to the :id, $2 is the name, and $3 is the surname.
  • Next, there is a list of guard functions that should be applied to the given parameters. {:<, :"$1", 5} means that we'd like to select only the records whose attribute marked as $1 (that is, :id) is less than 5{:==, :"$2", "Will"}, in turn, means that we are selecting the records with the :name set to "Will".
  • Lastly, [:"$$"] means that we'd like to include all the fields in the result. You may say [:"$2"] to display only the name. Note, by the way, that the result contains a list of lists: [[3, "Will", "Smith"], [4, "Will", "Smoth"]].

You may also mark some attributes as the ones you do not care for using the :_ atom. For example, let's ignore the surname:

In this case, however, the surname won't be included in the result.

Modifying the Tables

Performing Transformations

Suppose now that we would like to modify our table by adding a new field. This can be done by using the transform_table function, which accepts the table's name, a function to apply to all the records, and the list of new attributes:

In this example we are adding a new attribute named :salary (it is provided in the last argument). As for the transform function (the second argument), we are setting this new attribute to a random value. You may also modify any other attribute inside this transform function. This process of changing the data is known as a "migration", and this concept should be familiar to developers coming from the Rails world.

Now you may simply grab information about the table's attributes by using table_info:

The :salary attribute is there! And, of course, your data are also in place:

You can find a slightly more complex example of using both the create_table and transform_table functions at the ElixirSchool website.

Adding Indexes

Mnesia allows you to make any attribute indexed by using the add_table_index function. For example, let's make our :surname attribute indexed:

If the index already exists, you will get an error {:aborted, {:already_exists, :user, 4}}.

As the documentation for this function states, indexes do not come for free. Specifically, they occupy additional space (proportional to the table size) and make insert operations a bit slower. On the other hand, they allow you to search for the data faster, so that's a fair trade-off.

You may search by an indexed field using either the dirty_index_read or index_read function:

Here we are using the secondary index :surname to search for a user. 

Using Amnesia

It may be somewhat tedious to work with the Mnesia module directly, but luckily there is a third-party package called Amnesia (duh!) that allows you to perform trivial operations with greater ease.

For example, you may define your database and a table like this:

This is going to define a database called Demo with a table User. The user is going to name a name, a surname, an e-mail (an indexed field), and an id (primary key set to autoincrement).

Next, you may easily create the schema using the built-in mix task:

In this case, the database will be a disk-based, but there are some other available options that you may set. Also there is a drop task that will, obviously, destroy the database and all the data:

It is possible to destroy both the database and the schema:

Having the database and schema in place, it is possible to perform various operations against the table. For example, create a new record:

Or get a user by id:

Moreover, you may define a Message table while establishing a relation to the User table with a user_id as a foreign key:

The tables may have a bunch of helper functions inside, for example, to create a message or get all the messages:

You may now find the user, create a message for them, or list all their messages with ease:

Quite simple, isn't it? Some other usage examples may be found at the Amnesia official website.

Conclusion

In this article, we talked about the Mnesia database management system available for Erlang and Elixir. We have discussed the main concepts of this DBMS and have seen how to create a schema, database, and tables, as well as performing all major operations: create, read, update, and destroy. On top of that, you have learned how to work with indexes, how to transform tables, and how to use the Amnesia package to simplify working with databases.

I really hope this article was useful and you are eager to try Mnesia in action as well. As always, I thank you for staying with me, and until the next time!


10 Tools to Try With Your Next Web Project

New WordPress Course: Adding Hooks to Your Themes

Audio and Music in Final Cut Pro X: How to Import and Adjust

Wednesday, November 29, 2017

How to Create a Geometric 3D Adobe Photoshop Brush With Cinema 4D

Create the Perfect Carousel, Part 3

How to Create Bender From Futurama With the New Puppet Warp Tool in Adobe Illustrator

Create an Animated Movie in Blender: Part 2

How to Insert a PowerPoint Slide Into Word in 60 Seconds

Create an Animated Movie in Blender: Part 1

New Course: Animating Paint Strokes With Cinema 4D

20+ Best Minimal WordPress Themes: With Simple, Elegant Designs

60 Second How-to: Fix Photo Defects in Adobe Photoshop Lightroom

Tuesday, November 28, 2017

22+ Best Restaurant WordPress Themes: With Premium Responsive Designs

Typography in 60 Seconds: What Is Kerning, Tracking, and Leading?

Beginner's Guide to Android Layout

Optimize Your Website Without AMP: Optimization Checklist

How to Create a Color Font With Adobe Illustrator and Fontself Maker

How to Interview on the Fly

Create the Perfect Carousel, Part 2

How to Create a Realistic Coin Text Effect in Adobe Photoshop

How to Use PowerPoint Templates to Design Presentations

How to Use Sketch Libraries: Collaboration Made Easy

Make Your Go Programs Lightning Fast With Profiling

58 Best Lunar/Chinese New Year Templates and Graphics

How to Stretch Paper for Watercolour and Gouache and Avoid My Mistakes!

Monday, November 27, 2017

10 Easy Pieces: Fashion Video Packs, Assets and Templates

Create the Perfect Carousel, Part 1

Quick Tip: How to Create a Denim Pattern in Adobe Photoshop

Secure Coding With Concurrency in Swift 4

Secure Coding With Concurrency in Swift 4

In my previous article about secure coding in Swift, I discussed basic security vulnerabilities in Swift such as injection attacks. While injection attacks are common, there are other ways your app can be compromised. A common but sometimes-overlooked kind of vulnerability is race conditions. 

Swift 4 introduces Exclusive Access to Memory, which consists of a set of rules to prevent the same area of memory being accessed at the same time. For example, the inout argument in Swift tells a method that it can change the value of the parameter inside the method.

But what happens if we pass in the same variable to change at the same time?

Swift 4 has made improvements that prevent this from compiling. But while Swift can find these obvious scenarios at compile time, it is difficult, especially for performance reasons, to find memory access problems in concurrent code, and most of the security vulnerabilities exist in the form of race conditions.

Race Conditions

As soon as you have more than one thread that needs to write to the same data at the same time, a race condition can occur. Race conditions cause data corruption. For these types of attacks, the vulnerabilities are usually more subtle—and the exploits more creative. For instance, there might be the ability to alter a shared resource to change the flow of security code happening on another thread, or in the case of authentication status, an attacker might be able to take advantage of a time gap between the time of check and the time of use of a flag.

The way to avoid race conditions is to synchronize the data. Synchronizing data usually means to "lock" it so that only one thread can access that part of the code at a time (said to be a mutex—for mutual exclusion). While you can do this explicitly using the NSLock class, there is potential to miss places where the code should have been synchronized. Keeping track of the locks and whether they are already locked or not can be difficult.

Grand Central Dispatch

Instead of using primitive locks, you can use Grand Central Dispatch (GCD)—Apple's modern concurrency API designed for performance and security. You don't need to think about the locks yourself; it does the work for you behind the scenes. 

As you can see, it's quite a simple API, so use GCD as your first choice when designing your app for concurrency.

Swift's runtime security checks cannot be performed across GCD threads because it creates a significant performance hit. The solution is to use the Thread Sanitizer tool if you are working with multiple threads. The Thread Sanitizer tool is great at finding problems you might never find by looking at the code yourself. It can be enabled by going to Product > Scheme > Edit Scheme > Diagnostics, and checking the Thread Sanitizer option.

If the design of your app makes you work with multiple threads, another way to protect yourself from the security issues of concurrency is to try to design your classes to be lock free so that no synchronization code is necessary in the first place. This requires some real thought about the design of your interface, and can even be considered a separate art in and of itself!

The Main Thread Checker

It is important to mention that data corruption can also occur if you do UI updates on any thread other than the main thread (any other thread is referred to as a background thread). 

Sometimes it's not even obvious you are on a background thread. For example, NSURLSession's delegateQueue, when set to nil, will by default call back on a background thread. If you do UI updates or write to your data in that block, there is a good chance for race conditions. (Fix this by wrapping the UI updates in DispatchQueue.main.async {} or pass in OperationQueue.main as the delegate queue.) 

New in Xcode 9 and enabled by default is the Main Thread Checker (Product > Scheme > Edit Scheme > Diagnostics > Runtime API Checking > Main Thread Checker). If your code is not synchronized, issues will show up in the Runtime Issues on the left pane navigator of Xcode, so pay attention to it while testing your app. 

To code for security, any callbacks or completion handlers that you write should be documented whether they return on the main thread or not. Better yet, follow Apple's newer API design which lets you pass a completionQueue in the method so you can clearly decide and see what thread the completion block returns on.

A Real-World Example

Enough talk! Let's dive into an example.

Here we have no synchronization, but more than one thread accesses the data at the same time. The good thing about Thread Sanitizer is that it will detect a case like this. The modern GCD way to fix this is to associate your data with a serial dispatch queue.

Now the code is synchronized with the .async block. You might be wondering when to choose .async and when to use .sync. You can use .async when your app doesn't need to wait until the operation inside the block is finished. It might be better explained with an example.

In this example, the thread that asks the transaction array if it contains a specific transaction provides output, so it needs to wait. The other thread doesn't take any action after appending to the transaction array, so it doesn't need to wait until the block is completed.

These sync and async blocks can be wrapped in methods that return your internal data, such as getter methods.

Scattering GCD blocks all over the areas of your code that access shared data is not a good practice as it is harder to keep track of all the places that need to be synchronized. It’s much better to try and keep all this functionality in one place. 

Good design using accessor methods is one way to solve this problem. Using getter and setter methods and only using these methods to access the data means that you can synchronize in one place. This avoids having to update many parts of your code if you are changing or refactoring the GCD area of your code.

Structs

While single stored properties can be synchronized in a class, changing properties on a struct will actually affect the entire struct. Swift 4 now includes protection for methods that mutate the structs. 

Let's first look at what a struct corruption (called a "Swift access race") looks like.

The two methods in the example change the stored properties, so they are marked mutating. Lets say thread 1 calls begin() and thread 2 calls finish(). Even if begin() only changes id and finish() only changes timestamp, it's still an access race. While normally it's better to lock inside accessor methods, this doesn't apply to structs as the entire struct needs to be exclusive. 

One solution is to change the struct to a class when implementing your concurrent code. If you needed the struct for some reason, you could, in this example, create a Bank class which stores Transaction structs. Then the callers of the structs inside the class can be synchronized. 

Here is an example:

Access Control

It would be pointless to have all this protection when your interface exposes a mutating object or an UnsafeMutablePointer to the shared data, because now any user of your class can do whatever they want with the data without the protection of GCD. Instead, return copies to the data in the getter. Careful interface design and data encapsulation are important, especially when designing concurrent programs, to make sure that the shared data is really protected.

Make sure the synchronized variables are marked private, as opposed to open or public, which would allow members from any source file to access it. One interesting change in Swift 4 is that the private access level scope is expanded to be available in extensions. Previously it could only be used within the enclosing declaration, but in Swift 4, a private variable can be accessed in an extension, as long as the extension of that declaration is in the same source file.

Not only are variables at risk for data corruption but files as well. Use the FileManager Foundation class, which is thread-safe, and check the result flags of its file operations before continuing in your code.

Interfacing With Objective-C

Many Objective-C objects have a mutable counterpart depicted by their title. NSString's mutable version is named NSMutableString, NSArray's is NSMutableArray, and so on. Besides the fact that these objects can be mutated outside of synchronization, pointer types coming from Objective-C also subvert Swift optionals. There is a good chance that you could be expecting an object in Swift, but from Objective-C it is returned as nil. 

If the app crashes, it gives valuable insight into the internal logic. In this case, it could be that user input was not properly checked and that area of the app flow is worth looking at to try and exploit.

The solution here is to update your Objective-C code to include nullability annotations. We can take a slight diversion here as this advice applies to safe interoperability in general, whether between Swift and Objective-C or between two other programming languages. 

Preface your Objective-C variables with nullable when nil can be returned, and nonnull when it shouldn't.

You can also add nullable and nonnull to the attribute list of Objective-C properties.

The Static Analyzer tool in Xcode has always been great for finding Objective-C bugs. Now with nullability annotations, in Xcode 9 you can use the Static Analyzer on your Objective-C code and it will find nullability inconsistencies in your file. Do this by navigating to Product > Perform Action > Analyze.

While it's enabled by default, you can also control the nullability checks in LLVM with -Wnullability* flags.

Nullability checks are good for finding issues at compile time, but they don't find runtime issues. For example, sometimes we assume in a part of our code that an optional value will always exist and use the force unwrap ! on it. This is an implicitly unwrapped optional, but there is really no guarantee that it will always exist. After all, if it were marked optional, it's likely to be nil at some point. Therefore, it's a good idea to avoid force unwrapping with !. Instead, an elegant solution is to check at runtime like so:

To further help you out, there is a new feature added in Xcode 9 to perform nullability checks at runtime. It is part of the Undefined Behavior Sanitizer, and while it's not enabled by default, you can enable it by going to Build Settings > Undefined Behavior Sanitizer and setting Yes for Enable Nullability Annotation Checks.

Readability

It’s good practice to write your methods with only one entry and one exit point. Not only is this good for readability, but also for advanced multithreading support. 

Let's say a class was designed without concurrency in mind. Later the requirements changed so that it must now support the .lock() and .unlock() methods of NSLock. When it comes time to place locks around parts of your code, you may need to rewrite a lot of your methods just to be thread-safe. It's easy to miss a return hidden in the middle of a method that was later supposed to lock your NSLock instance, which can then cause a race condition. Also, statements such as return will not automatically unlock the lock. Another part of your code that assumes the lock is unlocked and tries to lock again will deadlock the app (the app will freeze and eventually be terminated by the system). Crashes can also be security vulnerabilities in multithreaded code if temporary work files are never cleaned up before the thread terminates. If your code has this structure:

You can instead store the Boolean, update it along the way and then return it at the end of the method. Then synchronization code can easily be wrapped in the method without much work.

The .unlock() method must be called from the same thread that called .lock(),  otherwise it results in undefined behavior.

Testing

Often, finding and fixing vulnerabilities in concurrent code comes down to bug hunting. When you find a bug, it's like holding a mirror up to yourself—a great learning opportunity. If you forgot to synchronize in one place, it's likely that the same mistake is elsewhere in the code. Taking the time to check the rest of your code for the same mistake when you encounter a bug is a very efficient way of preventing security vulnerabilities that would keep appearing over and over again in future app releases. 

In fact, many of the recent iOS jailbreaks have been because of repeated coding mistakes found in Apple's IOKit. Once you know the developer's style, you can check other parts of the code for similar bugs.

Bug finding is good motivation for code reuse. Knowing that you fixed a problem in one place and don't have to go find all the same occurrences in copy/paste code can be a big relief.

Race conditions can be complicated to find during testing because memory might have to be corrupted in just the “right way” in order to see the problem, and sometimes the problems appear a long time later in the app's execution. 

When you are testing, cover all your code. Go through each flow and case and test each line of code at least once. Sometimes it helps to input random data (fuzzing the inputs), or choose extreme values in hopes of finding an edge case that would not be obvious from looking at the code or using the app in a normal way. This, along with the new Xcode tools available, can go a long way towards preventing security vulnerabilities. While no code is 100% secure, following a routine, such as early-on functional tests, unit tests, system test, stress and regression tests, will really pay off.

Beyond debugging your app, one thing that is different for the release configuration (the configuration for apps published on the store) is that code optimizations are included. For example, what the compiler thinks is an unused operation can get optimized out, or a variable may not stick around longer than necessary in a concurrent block. For your published app, your code is actually changed, or different from the one that you tested. This means that bugs can be introduced that only exist once you release your app. 

If you are not using a test configuration, make sure you test your app on release mode by navigating to Product > Scheme > Edit Scheme. Select Run from the list on the left, and in the Info pane on the right, change Build Configuration to Release. While it's good to cover your entire app in this mode, know that because of optimizations, the breakpoints and the debugger will not behave as expected. For example, variable descriptions might not be available even though the code is executing correctly.

Conclusion

In this post, we looked at race conditions and how to avoid them by coding securely and using tools like the Thread Sanitizer. We also talked about Exclusive Access to Memory, which is a great addition to Swift 4. Make sure it's set to Full Enforcement in Build Settings > Exclusive Access to Memory

Remember that these enforcements are only on for debug mode, and if you are still using Swift 3.2, many of the enforcements discussed come in the form of warnings only. So take the warnings seriously, or better yet, make use of all the new features available by adopting Swift 4 today!

And while you're here, check out some of my other posts on secure coding for iOS and Swift!

  • iOS SDK
    Securing Communications on iOS
    Collin Stuart
  • iOS SDK
    Securing iOS Data at Rest: Protecting the User's Data
    Collin Stuart
  • Security
    Creating Digital Signatures With Swift
    Collin Stuart
  • Security
    Secure Coding in Swift 4
    Collin Stuart


How to Make Your Own Google Slides Presentation Template

How to Manage Multiple Applications in CodeIgniter

How to Manage Multiple Applications in CodeIgniter

Today, we’re going to explore how you can manage multiple applications in the CodeIgniter web framework using a single codebase. In the course of that, we’ll go ahead and create two different CodeIgniter applications that will share the core CodeIgniter codebase.

Sharing the core codebase across different applications is not something new as it’s already practiced by different frameworks and open-source systems, and CodeIgniter is no different. It easily allows you to manage multiple applications that share the core CodeIgniter library and API files, and at the same time you could use different databases and site-specific configurations.

To start with, we’ll go through the benefits of the multisite setup, and as we move on we’ll go through a practical demonstration of what it takes to set up multiple applications in the CodeIgniter framework.

Benefits of the Multisite Setup

In this section, we’ll highlight a couple of benefits of having a multisite setup.

One of the most obvious benefits that I could straightaway point out is that the multisite setup shares a common codebase, and that should make the upgrade and maintenance processes of your application much easier.

For example, let’s imagine that you have ten different CodeIgniter applications running under your belt. And you just came to know that a new version of the CodeIgniter framework is available for upgrade and you would like to upgrade it as soon as possible to make sure that the code remains secure and stable.

If you had a separate codebase for each of your applications, it would definitely be a tedious process to go through each and every site and upgrade it in turn. With the multisite setup, you just need to do it once as the core codebase is shared across all the sites!

Next, it allows you use a different database for each application even though they share a common codebase. In fact, it’s one of the most popular use cases of setting up multisite!

Apart from using a different database for each application, you could create a setup that uses the same database but a different theme or layout in the front-end.

If you are still using the FTP-based approach to move your site files across the different servers, I would say you’re going to love the multisite approach as it minimizes your work to a great extent!

How to Create Multiple Applications

In this section, we’ll set up the basic directory structure in order to implement a multisite setup.

At the root of your CodeIgniter application, create an applications directory. This is the main directory that will hold our different applications.

Next, go ahead and create two new directories—applications/app_one and applications/app_two. Of course, you could name it the way you want it to be, but I’ll keep things simple for now.

So, as you can see, we’re going to set up two different applications that will use the single codebase of the CodeIgniter framework. Although the multisite setup will reuse most of the CodeIgniter framework files, we still need to duplicate a couple of files and directories to each and every application we create.

Let me quickly list the files and directories that you should copy from the default application in the first place.

Copy the following directories from the default application directory to applications/app_one and applications/app_two:

  • cache
  • config
  • logs

As you can see, it’s obvious to have separate directories for cache and logs for each application. And the config directory is a must have for the working of your CodeIgniter application, so we are going to copy it anyway.

Next, let’s copy a couple of files along with the necessary directories that allow us to test our multisite application.

Copy the following files to our app_one and app_two applications from the default CodeIgniter application:

  • controllers/welcome.php
  • views/errors
  • views/welcome_message.php

For your quick reference, the controllers/welcome.php file should look like:

And the views/welcome_message.php file should look like.

Of course, you should change the following message in the view file so that we could differentiate the application during the testing.

For applications/app_one/views/welcome_message.php, it should look like:

And for applications/app_two/views/welcome_message.php, it should look like:

Now, we have everything done as far as our multisite setup is concerned. However, it won’t work out of the box yet as we still need to inform CodeIgniter about our multisite setup since it always loads the default application located in the application directory.

Finishing Touches

Let’s have a quick look at the setting that configures the default application directory. Go ahead and open the index.php file at the root of your application and look for the following code snippet.

It’s pretty clear from the above snippet that it allows you to set the path of your default application. So this is the place where we can make changes so that it picks up the default application from a directory other than the default one.

Of course, you could go ahead and straight away do something like this, and that should run the app_one application.

On the other hand, what would you do if you want to run app_two? As a quickie, you could copy the index.php file to index_app_one.php and index_app_two.php for each application. In your virtual host, make sure that you make the changes accordingly.

On the other hand, I prefer a slightly different approach, and I would like to rely on the ENV variable to choose between the different applications at run time.

For example, you can set up the custom ENV variable in NGINX as shown in the following snippet.

If you’re using the Apache web server, the same could be achieved with:

Next, let’s revise the code in the index.php file that takes advantage of the ENV variable to decide the default application to run.

So, as you can see, we check the existence of the CI_DEFAULT_APP ENV variable in the first place, and if it’s not available then we’ll fall back to the default application.

More often than not, you want to run your different applications on different domains. Ideally, I would like to use two different virtual hosts for each application. A quick example of each virtual host should look something like this in the context of NGINX.

The www.ci-app-one.com domain points to app_one:

Similarly, the www.ci-app-two.com domain points to app_two:

Of course, you could go ahead now and test your changes to see if it really works or not! Don’t hesitate to shoot me any queries if you face any issues.

And that was the pretty simple way in which you can set up multiple applications in the CodeIgniter framework using a single codebase.

Conclusion

Today, we went through an interesting aspect of the CodeIgniter framework that allows you to manage multiple applications using a single codebase. The obvious benefits of that are easy upgrading and maintenance of your existing codebase.

CodeIgniter is a powerful PHP platform. Whether or not you're just getting started or you're starting with the next version, don't forget to check out what we have available for you, as well.

Share your thoughts if you’ve already implemented something similar or you would have approached it in a slightly different way. Either way, I would love to hear your thoughts!


How to Create a Space Illustration Using Omber

New Course: Introduction to Figma

Understanding Particles and Dynamics in Maya—Part 12

Friday, November 24, 2017

International Artist Feature: Bulgaria

15 Important HR Basics for Every Small Business Owner

10 Best iOS Photo App Templates

Performant Animations Using KUTE.js: Part 5, Easing Functions and Attributes

Performant Animations Using KUTE.js: Part 5, Easing Functions and Attributes

So far in this series, you have learned how to animate the CSS properties of different elements, how to create different SVG-related animations, and how to animate the text content of different elements on a webpage. There is one more way in which you can animate the elements on a webpage using KUTE.js, and that is by changing the values of different attributes. This requires you to include the attributes plugin in your project.

In this tutorial, you will learn how to use the attributes plugin to animate the value of different kinds of attributes in KUTE.js. We will also discuss different easing functions that you can use to control the pace of different animations.

Easing Functions

Objects in real life very rarely move linearly. They are either accelerating or decelerating. Even the acceleration and deceleration occur at different magnitudes. Up to this point, all our animations have progressed linearly. This doesn't feel natural at all. In this section, you will learn about all the easing functions that KUTE.js provides for controlling the pace of different animations.

The core easing functions in the library are included in the core engine out of the box. Let's say you want to apply the QuadraticInOut easing to an animation. This can be achieved in two ways:

Each of the easing functions has a unique curve that determines how the elements will accelerate during the animation. A sinusoidal curve implies linear acceleration. Keep in mind that this is different from the linear easing function. The linear function implies a linear speed of animation, while a sinusoidal curve implies a linear speed of acceleration for the animation. In other words, the speed of the animation will increase or decrease linearly. Similarly, quadratic implies acceleration with a power of two, cubic implies a power of three, quartic implies a power of four, and quintic implies a power of five. There are also circular and exponential easing functions.

You can append In, Out, or InOut to any of the easing functions. The value In implies that the animation will start very slowly and keep accelerating until the end. The value Out implies that the animation will start at the maximum speed and then decelerate slowly until it comes to a halt at the end. The value InOut means that the animation will speed up at the beginning and slow down at the end.

You can also use bounce and elastic easing functions in your animations and append In, Out, or InOut to any of them. In the following demo, I have applied all these easing functions on different circles so that you can see how they affect the pace of the animation.

It is possible that none of the core easing functions provide the animation pace that you are looking for. In such cases, you can include the Cubic Bezier functions in your project from the experiments branch and start using those easing functions. 

Similarly, KUTE.js also provides some physics-based easing functions imported from the Dynamics.js library. You can read more about all these easing functions and how to properly use them on the easing function page of the library.

Animating Attributes

Attributes in SVG can accept numbers as well as strings as their value. The strings can be color values or numbers suffixed with a unit like px, em, or %. The names of the attributes themselves can also consist of two words joined by a hyphen. Keeping these differences in mind, KUTE.js provides us different methods that can be used to specify the values of different attributes.

As you can see, suffixed values need to be enclosed within quotes. Similarly, attributes which contain a hyphen in their name need to be enclosed inside quotes or specified in camelCase form.

Unitless Attributes

A lot of attributes accept unitless values. For example, the stroke-width of a path could be unitless. Similarly, you don't have to specify a unit for the r, cx, and cy attributes of a circle element. You can animate all these attributes from one value to another using the attributes plugin. 

Now that you know how to use different easing functions, you will be able to animate different attributes at different paces. Here is an example:

The first tween animates the radius of both circles at once using the allTo() method we discussed in the first tutorial. If set to true, the yoyo attribute plays the animation in the reverse direction. 

The cx attribute of both the circles is animated individually. However, they are both triggered by the same button click. Finally, the cy attribute of both the circles is animated at once with an offset of 1000 milliseconds.

Color Attributes

Starting from version 1.5.7, the attribute plugin in KUTE.js also allows you to animate the fill, stroke, and stopColor attributes. You can use valid color names or hex values for the colors. You can also provide the color values in RGB or HSL format. 

One important thing that you have to keep in mind is that the animations will only seem to work if you are not setting the value of these properties in CSS. In the following demo, the fill color wouldn't have animated at all if I had added the following CSS in our demo.

The demo I created is very basic, but you can make it more interesting by applying transforms and using more colors.

Suffixed Attributes

A lot of SVG attributes like r and stroke-width can work with and without suffixes. For example, you can set the value of r to be a number like 10 or in terms of em units like 10em. There are some attributes like offset attribute for color stops that always require you to add a suffix. While specifying a value for suffixed attributes in KUTE.js, always make sure that you enclose the value within quotes.

In the following example, I have animated the offset value of the first stop in a gradient and the color of the second stop. Since offset requires a suffix, I have enclosed the value inside quotes.

There are three different gradients in the demo, and each of these gradients has two color stops with the class names stop1 and stop2. I have also applied a scale transform using the svgTransform attribute, which we discussed in the third tutorial of the series.

Final Thoughts

In this tutorial, you learned about different easing functions available in KUTE.js and how you can use them to control the pace of your own animations. You also learned how to animate different kinds of attributes.

I have tried to cover all the important aspects of KUTE.js in this series. This should be enough to help you use KUTE.js confidently in your own projects. You can also read the documentation in order to learn more about the library. 

I would also recommend that you go through the source code and see how the library actually works. If you have any questions or tips related to this tutorial, feel free to share them in the comments.


How to Draw a Winter Christmas Landscape With a Wooden Sign in Adobe Illustrator

How to Create Flat Profession Avatars in Adobe Illustrator

Easy Pieces: 10 Local News Video Templates and Assets for Adobe After Effects

Thursday, November 23, 2017

How to Create a GTA Text Effect Action in Adobe Photoshop

How to Build an Awesome Band Website With WordPress (For Musicians)

Performant Animations Using KUTE.js: Part 4, Animating Text

Performant Animations Using KUTE.js: Part 4, Animating Text

In the second tutorial of this series, you learned how to animate different CSS properties of the elements on a webpage using KUTE.js. You learned how to animate all the transform properties as well as properties like border-radius and border-color. You can also use the CSS plugin to animate CSS properties like font-size, line-height, letter-spacing, and word-spacing.

KUTE.js also has a Text plugin which allows you to animate the text inside different elements, either by increasing or decreasing a number like in a countdown or by writing a string character by character.

In this tutorial, you will learn how to animate the text inside different elements on a webpage using the CSS and Text plugins in KUTE.js.

Animating CSS Text Properties

As I mentioned earlier, you can use the KUTE.js CSS plugin to animate four different text-related CSS properties. These properties are font-size, line-height, letter-spacing, and word-spacing. We will also use some properties from the core engine discussed in the first tutorial to animate individual letters. Let's see how we can use all these concepts together to create the vibrating HELLO text in the following demo.

Here is the code that was used to create the above animation:

Each letter of the word is wrapped inside a span tag and has its own unique class. The first tween animates the color of all the letters from white to red with an offset of 200ms. This is also the first animation that is played after clicking on Start Animation. The animateFontSize tween has been chained to animateColor. This way, the font-size animation begins as soon as the color animation ends. 

You might have noticed that I have used two attributes called repeat and yoyo to control the behavior of the animation. The yoyo attribute is used to reverse the animation that is currently being played repeatedly. This can avoid sudden jumps in the values of different properties during the animation and make it appear smooth.

The font-size animation has been chained with animateSkewing, which skews all the letters by -15 degrees. The skewX and skewY properties are available within the core engine itself.

All the tweens for animating the color of different letters have been chained to animateSkewing at once. This way, you can make sure that all the chained color animations start playing as soon as the skew animation ends. Finally, the lettersSqueezed tween reduces the spacing between different letters by 15 px.

You can create more interesting effects by using different combinations of properties.

Animating Numbers

You can also animate numbers in KUTE.js. However, you will have to include an additional text plugin to create the animation. 

The process of animating numbers is actually very simple. You just need to specify the selector where the animating numbers should be shown as well as the final number at which the animation should end. 

Here is a basic example that shows the total number of airports in the USA in 2016 using animation.

You can also apply the usual tween options like duration, repeat, and delay to customize the behavior of the animation. The code we just wrote will result in the following animation:

Writing Text Character by Character

This is a very popular effect that you can find on quite a few websites. The KUTE.js text plugin allows you to specify the new sentence that should replace the original sentence one character at a time. 

Before replacing the initial characters with their final value, random characters are animated like the numbers example you just saw. The embedded CodePen demo should make it clearer:

Here is the code that you need to write in order to create the above animation:

The character animation for the whole sentence is finished within 5 seconds. As you might have noticed, the initial and final sentences don't need to have the same number of characters. This gives us a lot of liberty when setting the value of the text parameter.

You can also include HTML tags inside the value of the text parameter and then use CSS to change the appearance of the text that you just animated.

There will be a delay in the appearance of Earth after of has already appeared. This happens because the plugin also writes <span class="earth"> using the same character animation, but none of those characters are actually visible to the user. The delay may or may not be desirable based on your preferences.

The intermediate characters that are shown during the animation are lowercase alphabetical values by default. This can be an issue when the characters that you want to animate are all uppercase letters or numbers. Which intermediate characters are used for the animation is determined by the value of the textChars parameter. It accepts six different values:

  • alpha: In this case, the intermediate characters will be lowercase letters.
  • upper: In this case, the intermediate characters will be uppercase letters.
  • numeric: In this case, numerical characters are used for the animation. This is different from animating a number as the values won't increase sequentially.
  • symbols: In this case, the plugin will use characters like #, %, and $ for the animations.
  • all: You can use this value if you want the intermediate characters to be a mix of alphabetic, numeric, and symbols.
  • If nothing else works for you, KUTE.js gives you the option of specifying your own custom list of characters that should be used during the animation.

The following example shows how you can animate text inside a heading using uppercase intermediate characters.

Final Thoughts

In this tutorial, you learned how to use the CSS and Text plugins in KUTE.js to animate the text inside an element. When you want to animate the appearance of the text, you need to use the CSS plugin. This will allow you to use properties like font-size, letter-spacing, etc. When you want to change the actual characters inside any element, you need to use the text plugin.

If you’re looking for additional JavaScript resources to study or to use in your work, check out what we have available on Envato Market.

I hope you learned something new in this tutorial. If you have any questions, please let me know in the comments.


Why You Need More Integration Between Design and Development

Get Interviewing: Practical Exercises for Aspiring Documentary Filmmakers

How to Draw a Fox Step by Step

Wednesday, November 22, 2017

How to Create a Scribble Sketch Effect Action in Adobe Photoshop

How to Change PowerPoint Orientation From Landscape to Portrait

Performant Animations Using KUTE.js: Part 3, Animating SVG

Performant Animations Using KUTE.js: Part 3, Animating SVG

The previous tutorial of the series showed you how to animate different CSS properties of any element using KUTE.js. However, the core engine does not allow you to animate properties that are specific to SVG elements. Similarly, you can't animate the SVG morphing of different path shapes or the drawing of different SVG elements using strokes. You will have to use the KUTE.js SVG plugin to achieve any of these tasks.

Before we begin, keep in mind that you will have to include both the KUTE.js core engine and the SVG plugin for the examples in this tutorial to work.

Morphing SVG Shapes

Morphing one SVG shape into another is a very common feature that you will come across. The KUTE.js SVG plugin gives us everything that we need to create our own morphing animations with ease. 

There are three ways to morph SVG shapes using this library:

  1. You can use the fromTo() method to specify both the initial and the final SVG path for your element. 
  2. You can also use the to() method and avoid specifying the initial path. In this case, the start value for the morphing will be determined based on the value of the d attribute of the selected element that you want to morph. 
  3. One more option that you have is to pass the final path as a string directly to the tween. This way, you can avoid having two different paths in your SVG.

During initialization, the library samples some points based on the paths that we provided. These points are then stored in two different arrays. Finally, these arrays are used for the interpolation. There are a number of options that you can configure to control the morphing behavior for different paths.

  • morphPrecision: As you might have guessed, this option allows you to specify the precision or accuracy of the morphing. It is specified as a number, and a lower value means higher precision. Keep in mind that higher precision will result in more accuracy, but it will also be detrimental to the performance. This option does not apply when you are dealing with polygonal shapes or paths where the d attribute consists only of hl, and v. In such cases, the original polygon paths are used instead of sampling new ones.
  • reverseFirstPath: You can set the value of this option to true in order to reverse the drawing path for your first shape. Its default value is false.
  • reverseSecondPath: You can set the value of this option to true in order to reverse the drawing path for your second shape. Its default value is also false.
  • morphIndex: Sometimes, the points on a path might have to cover a lot of distance during morphing. You can control this behavior using the morphIndex parameter. When specified, this parameter allows you to rotate the final path in such a way that all the points travel the least distance possible.

Let's use what we have learned so far to morph a battery icon into a bookmark icon. You should note that I have used lowercase l in order to specify the path in relative terms. This is the required markup:

The following JavaScript creates the tween object and starts the animation on button click:

Here is a demo that shows the above code in action. I have also added an extra element where the morph animation sets reverseFirstPath to true. This will help you understand the overall impact of different configuration options on the morphing. The animation duration has been set to 5 seconds so that you can closely observe both the animations and spot the differences.

In the previous example, the main path did not have any subpaths. This made the morphing very straightforward. However, this might not always be the case. 

Let's add an extra subpath to our bookmark as well as the battery icon. If you morph the icons now, you will see that only the first subpath animates. The second subpath just disappears at the beginning of the animation and reappears at the end. The only way to animate all the subpaths in such cases is by changing the subpaths into individual paths. Here is an example:

Animating SVG Strokes

Another popular SVG-related animation effect includes starting from nothing and then drawing a predefined shape using SVG strokes. This can be used to animate the drawing of logos or other objects. In this section, you will learn how to use KUTE.js to create a stroking animation for the Font Awesome bicycle icon

There are three ways to animate SVG strokes in KUTE.js. You can animate from 0% to 100% by setting the fromTo values as 0% 0% and 0% 100%. You can also draw a part of the SVG shape by setting the values to something like 0% 5% and 95% 100%. Finally, you can set the ending value to 0% 0% in order to create an erasing effect instead of a drawing effect.

Here is the JavaScript code that I have used to animate our bicycle:

As you can see in the example below, you don't need to worry about multiple subpaths inside a path. KUTE.js animates all of these subpaths individually without any issues. The animation duration is used to determine the time for the animation of the longest path. The stroke duration for the rest of the subpaths is then determined based on their length.

Animating SVG Transforms

We have already learned how to animate CSS transform values in the second tutorial of the series. The KUTE.js SVG plugin also allows you to use the svgTransform attribute in order to rotate, translate, scale, or skew different SVG elements on a webpage.

The rotate attribute accepts a single value that determines the angle of rotation. By default, the rotation happens around the center point of the element, but you can specify a new center of rotation using the transformOrigin attribute.

The translate attribute accepts the values in the format translate: [x, y] or translate: x. When provided with a single value, the value of y is assumed to be zero.

When skewing elements, you will have to use skewX and skewY. There is no support for skew[x, y] in SVG. Similarly, the scale attribute also accepts only one value. The same value is used to scale the elements in both x and y directions.

Here is a code snippet that applies all these transformations on a rectangle and a circle.

I have set the yoyo parameter to true so that after playing the animation in reverse, the transform properties are set to their initial value. This way, we can replay the animations again and again by clicking on the buttons.

If you press the Rotate button in the demo, you will notice that it does not seem to have any effect on the circle. To observe the rotation of circle, you will have to apply a skew transform on it in order to change its shape and then click on rotate immediately.

Final Thoughts

We began this tutorial by covering the basics of SVG morphing and stroke animations. You learned how to properly morph complex paths that have subpaths and how we can create an erasing stroke effect instead of a drawing one by choosing the right values for the draw attribute. After that, we discussed how we can use the svgTransform attribute in order to animate different transforms.

In various tutorials, we've seen just how powerful JavaScript has become. It’s not without its learning curves, and there are plenty of frameworks and libraries to keep you busy, as well. If you’re looking for additional resources to study or to use in your work, check out what we have available on Envato Market.

The tutorial was meant to introduce you to all the features of the KUTE.js SVG plugin and help you get started quickly. You can learn more about the SVG plugin by reading the documentation.