navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Up and Running with PHP CodeIgniter

Up and Running with PHP CodeIgniter

with Jon Peck

 


Speed up your development with CodeIgniter, a fast and powerful PHP web application framework. Author Jon Peck shows how to build a magazine cataloging system while describing how to use a MVC (Model-View-Controller) framework like CodeIgniter.

Starting with the what and why of CodeIgniter, Jon introduces key concepts such as the MVC pattern and libraries by demonstrating how to create static pages, then storing and displaying magazine info in a database. Advanced topics like classes and helpers are explored to validate user input, upload files, and much more. By creating a complete system, you'll have the foundation to build your own applications with CodeIgniter.
Topics include:
  • What is CodeIgniter?
  • Creating a static page controller
  • Generating output with a view
  • What is a model?
  • Saving data with Active Records
  • Creating forms
  • Validating user input
  • Listing records in tables
  • Uploading images
  • Viewing and deleting records

show more

author
Jon Peck
subject
Developer, Programming Languages, Web Development
software
PHP , CodeIgniter
level
Intermediate
duration
1h 30m
released
Jul 11, 2013

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:00 (music playing)
00:04 Hi, I'm John Peck, and welcome to Up and Running with CodeIgniter.
00:08 In this course, we'll look at CodeIgniter, the open source PHP web application framework.
00:13 I'll start by describing what CodeIgniter is and why it's useful, then demonstrate
00:17 how to install the framework. I'll model records in the database, add
00:22 functionality using libraries, and finally, show how to save time using helpers.
00:28 Throughout the course, we'll create a magazine catalog web application for
00:31 keeping track of a collection of back issues.
00:34 We'll be covering all of these features plus plenty of other tools and techniques
00:38 that a modern developer can use to quickly build PHP applications without having to
00:43 constantly reinvent the wheel. Now, let's get up and running with CodeIgniter.
00:47
Collapse this transcript
Exercise files
00:00 In this course, I'm going to be developing a Sandbox PHP environment using
00:04 CodeIgniter 2.1.3 as the framework, PHP 5.3 as server side language, MySQL 5.5 as
00:12 the database server and Apache 2 as the web server.
00:15 Other web servers, such as, nginx, IIS will not be covered in this course but
00:19 they should work. If you don't already have a server for
00:22 development, I recommend using a local development server running on your workstation.
00:26 In this course, I'm going to be demonstrating using a virtualized server
00:30 running in my existing operating system. If you'd like a server configured using
00:34 this technique, check out, Up and Running with Linux for PHP Developers here in the
00:38 lynda.com online training library. Alternatively, you can use a web server
00:42 solution stack package, in your native operating system.
00:45 XAMPP from apachefriends.org, has distributions for Linux, Windows, and Mac
00:50 OS X. WampServer from wampserver.com, is
00:53 explicitly for windows, and MAMP from mamp.info is for Mac only.
00:58 Each of these packages will allow you run the exercises found in this course.
01:02 Installing additional software within your native operating system is covered in the
01:05 course, Installing Apache, MySQL and PHP with David Gassner here in the lynda.com
01:11 online training library. Regardless of the location of your web
01:14 server you'll need access to the command line with administrative credentials in
01:18 order to install and configure server software.
01:20 For Mac and Linux, the Terminal allows you to access the command line which includes
01:24 access to the ssh command if the site is hosted remotely.
01:28 For Windows, you can use the free program PuTTY to connect via ssh to remote servers
01:32 available from the official Putty website. I'm going to demonstrate writing code
01:37 using the NetBeans 7.3 IDE bundle for PHP. NetBeans is a free open sourcing cross
01:43 platform integrated development environment from netbeans.org.
01:47 Keep in mind the goal of the course is to use CodeIgniter not how to use NetBeans
01:51 but with that said I'm only going to be editing code in NetBeans.
01:54 Any IDE or text editor will work. The exercise files for this course are
01:59 contained in folders by chapter and movie. On my work station I have them in a folder
02:03 named sandbox that my virtualized lending server can access.
02:07 Depending on your web server configuration you may need to store these files in a
02:10 different place, such as a remote web server or in a folder accessible by a
02:14 local Apache and PHP stack. There's some additional folders in the
02:18 exercise files that you should be aware of.
02:21 The first is Assets which contains images for testing uploading during the course.
02:25 Next is the Bootstrap folder, this is minimal modified version of Twitter
02:29 Bootstrap including a custom navigation system this would be copying during the course.
02:34 Along with the Bootstrap folder are css, js and image, these will be copied same
02:40 time as Bootstrap. Finally the Database folder contains a
02:43 single SQL file for import called Issue_publications.sql.
02:48 Please import the file now to prepare for database interactions.
02:52 A final note, as different web hosts in configurations serve content from
02:55 different URL's, the address you see in my browser may not exactly match what you see
03:00 on your work station. Additionally the location shown in the
03:03 command prompt demonstrations will differ depending upon the location of site files
03:07 and configurations on the server. The software configuration will be very
03:10 similar if not identical across platforms.
03:13
Collapse this transcript
What you should know
00:00 This course was designed with the assumption that you have a working
00:03 knowledge of the PHP language and have written a few scripts.
00:06 Without this background, you might not have enough contacts to follow along with
00:09 what I'm doing, which can be a bit frustrating.
00:12 For some background door refresher, I recommend PHP with MySQL essential
00:17 training with Kevin Skoglund, here in the Lynda.com online training library.
00:22 Additionally, the use of object-oriented PHP is required for this course.
00:26 If you're not familiar with it, check out Object-Oriented Programming with PHP here
00:30 in the lynda.com online training library. It'll include examples and explanations
00:35 that should make Codelgniter adoption much more seamless.
00:39 If you're unfamiliar with configuring web server components, check out the course,
00:43 Installing Apache, MySQL, and PHP with David Gassner here in the lynda.com online
00:48 training library, for comprehensive instructions on how to manage the solution stack.
00:53 If you're interested in MVC and Frameworks in general, take a look at MVC Frameworks
00:57 for Building PHP Web Applications with Drew Falkman, here in the lynda.com online
01:02 training library. it covers a number of key structures and
01:05 techniques, then goes into a brief survey of many different frameworks including
01:09 Codelgniter, which is the sole subject of this course.
01:13 Finally, it's always good to know where the manual is.
01:15 Codelgniter maintains a comprehensive user guide that provides both tutorials and
01:20 functional references. These can all be found at ellislab.com.
01:25 I recommend bookmarking this page and using it as a reference as we go along.
01:29
Collapse this transcript
1. First Steps with CodeIgniter
What is CodeIgniter and why should I use it?
00:00 Before I jump directly into describing what CodeIgniter is, let's take a step
00:04 back and look at how developers typically learn a new language.
00:08 I found that people tend to go though a number of common stages as their skills
00:11 grow and improve. The first stage is basic structure and
00:15 syntax, where a program can be written that can go from start to finish without
00:19 any major failures. Next comes in understanding of the
00:22 vocabulary and functionality of the language.
00:25 There's a lot less guess work and more certainty about what can and cannot be done.
00:30 Once they're comfortable with that foundation, it could be expanded with
00:32 knowledge of development techniques and relations of the language features.
00:36 The final stage, excluding actually developing the language itself, contains
00:40 scalable programming structures and architecture.
00:42 Including design patterns, libraries and knowledge of APIs and so forth.
00:47 This is where development speed really comes into play rather than reinventing
00:51 the wheel, a programmer can focus on building components that deliver value.
00:55 I personally place CodeIgniter at this final stage.
00:58 Why is that? CodeIgniter is an open-source PHP web
01:02 application framework which can be used for rapid development without the overhead
01:06 of having to constantly build reusable components.
01:10 Providing both a logical structure and a reusable interface to libraries written to
01:14 perform common tasks. CodeIgniter provides a fast extensible
01:18 foundation for writing complex software. Some of the key features include, a small
01:24 footprint meaning that its lightweight and has very little overhead.
01:27 Which lends itself towards fast performance especially when its compared
01:31 to other frameworks. It's also easy to get going requiring
01:34 almost no configuration to get started. Originally released in 2006, Codelgniter
01:40 has reached an adoption rate and a maturity that makes it a production-ready
01:44 candidate for the basis of your next project.
01:46 In 2008, PHP creator Rasmus Lerdorf praised Codelgniter because it's faster,
01:52 lighter, and least like a framework. But, why should I use somebody else's work?
01:58 Consider creating your own framework. While nobody will prevent you from writing
02:01 your own programming framework. Ask yourself, is this really the best use
02:05 of my time? Are you going to review your work with
02:08 thousands of other developers? What's your bug reporting process and
02:11 testing methodology? What about security and penetration testing?
02:15 Finally, do you want to have to build each new piece of functionality from scratch
02:19 every time you want to do something new? I could go on, but I'm trying to get to
02:23 three basic points. Why?
02:25 Reusability and modularity, where I'm avoiding copying and pasting code.
02:30 Components can be reused on multiple projects leveraging a common interface.
02:34 Next is maintainability, which is particularly important if you want others
02:38 to be able to easily build upon or extend your application.
02:41 If their familiar with Codelgniter and you've used the recommended structures,
02:45 they shouldn't have any problem understanding your code.
02:47 Finally is delegation. You want to focus on delivering value, not
02:51 creating the building blocks for repetitive or common tasks that others
02:55 have already completed. Codelgniter uses a loose MVC development
03:00 pattern for organizing code and logic. MVC stands for Model-View-Controller,
03:06 which looks great on a resume, but what does this really mean?
03:09
Collapse this transcript
Introducing the MVC development pattern
00:00 I'm going to explain MVC at only a very high level as this courses focus is on
00:05 CodeIgniter . For a more comprehensive description I
00:08 recommend MVC Frameworks for Building PHP Web Applications with Drew Falkman here in
00:14 the lynda.com online training library. MVC stands for Model-View-Controller.
00:20 It's a software design pattern that separates the representation of
00:24 information from user interaction. This explicit separation of components
00:29 allows for greater code reusability and logical separation of program responsibilities.
00:33 In short MVC keeps code organized, which in turn helps projects and teams.
00:39 CodeIgniter uses a loose approach to MVC which I'll get into more detail in a bit.
00:45 There are three components to MVC. The first, model is the representation of
00:50 data structures, business rules, and functions.
00:53 This is where really basic, create, read, update, and destroy or CRUD functionality
00:58 is defined. Next is a View, which is a representation
01:01 of the information that's presented to the user.
01:03 The View is where all HTML rendering takes place.
01:07 The most program logic that's in a View is a really simple if, then, like if
01:11 something exists then display it. Anything that takes more logic than that,
01:15 like deciding what to do based on user input, is delegated to the controller,
01:20 which serves as kind of an intermediary between the model and the view.
01:24 The controller sends commands to the other components like model, save yourself, then
01:29 view, show a message saying that the model was saved.
01:33 As a visual explanation of a regular interaction, a site user will send a
01:38 command to the controller which will in turn manipulate the model, like create
01:42 this record, for example. Through which the control updates the View
01:45 with a confirmation that the record has been updated.
01:48 The User sees the final HTML representation in the View.
01:52 Earlier, I mentioned that CodeIgniter uses a loose approach to MVC.
01:56 To be clear, CodeIgniter's use of models is unique and does not precisely fit in
02:01 traditional definition within a model MVC design patterns.
02:04 They're more like a domain object, which is a collection of properties.
02:08 Models in Codelgniter are optional. Depending on your project needs, you can
02:12 completely leave it out, leaving only a minimal application with just controllers
02:17 and views. I'm going to demonstrate Codelgniter's
02:19 implementation of models. Now that we've got this theory out of the
02:23 way, let's start building an application by installing the Codelgniter framework.
02:27
Collapse this transcript
Installing CodeIgniter
00:00 CodeIgniter installation is really straight forward.
00:03 I'm going to start by connecting to my local development server, SSH sandbox.
00:08 Next, I'm going to change directory to a temporary directory.
00:13 I prefer /var/tmp. I'm going to use wget to download the
00:18 archive containing CodeIgniter. I'm using version 2.1.3.
00:23 So, here's the current full path to that file.
00:26 Http://ellislab.com/asset/ci_download_files/reactor/codeigniter _2.1.3.zip.
00:45 Now that the archive has been downloaded, extract it.
00:48 I'm going to use unzip and then the name of the file.
00:52 Now that the archive has been extracted, change directory to your web root.
00:56 In my case, it's media/sf_sandbox. Make sure it's empty before preceding.
01:03 Good, I've got a clean slate. Copy the extracted files to the web root.
01:07 I'm going to recursively copy using CP -R, and the path for our temp, and then CodeIgniter.
01:16 And then the full contents of the directory to the current directory.
01:21 Now that it's been copied, a little configuration is needed.
01:24 I'm going to to switch to NetBeans. I'm going to create a new project with a
01:29 PHP application with existing sources, that is located on my desktop in the
01:34 sandbox folder. I will put NetBeans metadata into a
01:39 separate directory and click Finish. I don't need index.php, the front
01:45 controller, so, I'll just close it. All configuration files are contained in
01:50 application config. First thing I'm going to configure is the database.
01:55 I'm going to scroll down a little bit, I'm going to set the user name, in my case,
02:00 it'll be sandbox. The password, sandbox again, and the data
02:05 base name which is sandbox. When complete, save and close the database
02:11 configuration file. Finally, I'm going to configure an
02:14 automatic connection to the database, which will automatically load and
02:17 instantiate the database connection on every page load.
02:20 To do that I'll use an auto loader. Navigate to auto load.
02:24 I'm going to scroll downy to the bottom and down in libraries, I'm just going to
02:28 add the string database and save. I'll define libraries in much greater
02:34 detail later in the course. Save the changes, then close all open files.
02:40 To verify that the settings are working, switch to the browser.
02:42 I'm going to navigate to my web server root, which in my case is http://sandbox.dev:8080.
02:53 I see a welcome to Codeigniter message. Success, Codeigniter has been installed.
02:57 If you see any errors, verify that your database credentials have been set up correctly.
03:01 If there aren't any errors, then right now, this application isn't very useful,
03:05 it's only showing a stock message. That's not very fun.
03:08 Let's start by customizing Codeigniter to display something more useful than default text.
03:13
Collapse this transcript
Creating a static page controller
00:00 In CodeIgniter, and other MVC frameworks for that matter, a controller can be
00:04 practically thought of as a class that delegates work.
00:08 Each controller is named so it can be accessed via URL.
00:12 To determine what controller to use, CodeIgniter uses the following pattern for
00:16 routing a user's request to the right controller.
00:18 Index.php, followed by the controller class, then the controller method, and
00:24 then any optional arguments. Let's take a look at how this default
00:28 message is being rendered. From Netbeans, navigate to the application
00:33 route, and open the controllers directory. There are two files in here: index.html,
00:38 which, when I open, I can see is just a simple place holder denying access.
00:43 Close it, then open welcome.php. The first line is a safety mechanism that
00:48 prevents direct access to the controller. Then, a subclass declaration that extends
00:53 the codeIgniter controller class. The name of the class is Welcome, with a
00:58 capital W. This is different than the file name,
01:01 which is all in lower case. There's only one method within the class, index.
01:06 Index is a bit of a fail safe in that if the controller method is missing from the
01:10 URL, then index is the fall back. The method has only one line of executable
01:14 code loading the view named welcome message.
01:17 I'll discuss views in greater detail in a moment.
01:20 First, let's see how CodeIgniter parses URLs.
01:24 Switch back to your browser. You should be seeing the default page.
01:27 Now navigate to /index.php/welcome/index, the page should reload and look the same.
01:38 Let's trigger the default behavior as well without specifying the index method.
01:43 Again, the page looks the same. If I try to do something that doesn't
01:48 exist, however, like the puppies method, I get a default for our fore message.
01:54 That's enough playing around with the defaults.
01:55 Let's actually start writing code. I'm going to create a new controller for
01:59 the magazine database. Copy the first three lines of the welcome class.
02:04 Close the file and then create a new file in the controller called Magazine.php.
02:11 I'll paste the contents, close that out properly.
02:16 I'm going to change class welcome to class magazine with a capital M.
02:21 I'm going to create a public... Method called index which takes no arguements.
02:27 For now let's just echo a headline my magazines.
02:31 So echo h2 my magazines and then close the h2 .
02:37 Add a quick comment stating what this method does which in this case is just the
02:41 index page for magazine controller. That's all that's needed for the
02:48 controller for now. Save and go back to the browser.
02:50 Recall the URL structure with the class name.
02:53 Navigate to Index.PHP/magazine. My magazines is now displayed directly for
03:01 the controller. However, this is kind of an awkward URL.
03:04 Wouldn't it be easier if we didn't have to explicitly state magazine?
03:08 Let's change the default URL route to go to the magazine instead of Welcome.
03:12 To do that, I'm going to explicitly edit the route's configuration.
03:17 Return to Netbeans, open up Config, then open routes.php.
03:23 There's a lot of comments in here, in short, this file allows remapping of URI
03:27 requests to a specific controllers when you don't want the default behavior.
03:31 Scrolling to the bottom, there's actually only two routes and both are reserved by codeIgnitor.
03:37 The default, underscore controller, is actually what we want to specify.
03:41 Currently it's set to welcome which explains why the default welcome message
03:44 was shown when just navigating to the base URL.
03:47 Let's change it to magazine and save. Then close the router.
03:51 Switch back to the browser. Now, when I navigate to the server root, I
03:56 see my magazines instead of the default message.
03:58 If you recall how NBC Architecture separates logic from display, you're
04:02 probably thinking echoing isn't really a good idea, and you're right.
04:07 Echoing is terrible and I should feel bad for doing it.
04:09 Instead, I should feel bad for doing it. Instead, I should have a view.
04:13 All right. How can I do that?
04:14
Collapse this transcript
Generating output with a view
00:00 A view is a partial or complete webpage. Designers like views because it's most
00:05 HTML with a very bar minimum in PHP code, and what logic is there are four hs and so forth.
00:13 Views can be embedded in other views, which allows for hierarchies and cleaner,
00:17 more reusable code. Even though they're webpages, a view
00:21 cannot be called directly. It can be only loaded by controller.
00:24 So with this context, let's get that HTML out of the controller and into a view.
00:31 From NetBeans, I'm going to navigate to the Views directory.
00:34 Right now, there's only two files. The same placeholder index.html and
00:40 welcome message.php. Open welcome message.php to see what's inside.
00:45 Scrolling through, it's a complete html five page with no php whatsoever.
00:52 At the bottom there is one little anomaly. Page rendered in elapsed time in curly braces.
00:57 This is a pseudo variable from the benchmarking class...
01:01 I'll get into class libraries in a later chapter.
01:03 For the time being, just close welcome message.
01:07 Then create a new file in views called magazines, plural, .php.
01:14 And the magazine controller. Let's copy that HTML.
01:18 And paste it into magazines.php. Next, we'll need to load the view.
01:22 Take a look at the welcome controller for just a second, and see how it loads the
01:26 view using this. What is this?
01:30 This has a special meaning in CodeIgniter. It's a singleton CodeIgniter instance,
01:34 which means there can only be one copy of it throughout the entire application,
01:38 which prevents duplicates in overhead. When various functionality is loaded, it's
01:43 attached to the instance, in such a way, that it can be referenced, like a property
01:46 of the instance. I'll demonstate how this works in just a moment.
01:51 Close the Welcome controller and go back to the Magazine controller.
01:56 We'll replace the echo with this, load and we're going to load a view.
02:01 Named magazines. Followed by semicolon and save.
02:05 I'm going to go back to the browser and refresh.
02:08 Make sure that nothing has changed. It says, My magazines, again.
02:12 Now there's no limit to the number of views that are loaded.
02:14 If you chain them, they'll be appended. Let's experiment a little bit by going
02:18 back to the magazine controller. And copying and pasting this load view.
02:24 And doing it twice. Save, then in the browser, refresh.
02:29 Now there's two My magazines. If I view the page source.
02:33 I can see that the only markup that is shown is what was in my view.
02:36 See what I mean by coding neither having low overhead.
02:39 None of the (UNKNOWN) fully formatted HTML documents.
02:43 Wait a second. That's actually something I want.
02:45 I'm going to get into more detail about how to set up a proper template in an
02:48 outcoming chapter. Close the source, and go back to NetBeans.
02:53 Let's clean up the controller by removing that extra line, and then save.
02:58 In this chapter, I've defined what CodeIgniter is, and gave a number of
03:01 reasons why it should be used. I've introduced the Model View Controller
03:05 development pattern. Then I installed CodeIgniter and tested
03:09 the database configuration. Starting with some code and concepts, I
03:12 created a static page controller and finally generated output using a view.
03:16 At this point, we're ready to display content but we don't actually have
03:21 anything to show. No worries, we'll sort that in the next
03:24 chapter as we model magazines in the database.
03:26
Collapse this transcript
2. Modeling Magazines in the Database
What is a model and how is it used?
00:00 In the previous chapter, I discussed how CodeIgniter loosely implements the
00:04 Model-View-Controller pattern, then demonstrated both a View and a Controller.
00:08 The final component, the model, traditionally contains application data,
00:13 logic and business rules, and functions. Codelgniter defines models as PHP classes
00:19 that work with information in a database, which is pretty vague.
00:22 Out of the box, they're treated just as a collection of properties, which I
00:26 mentioned previously, is similar to a domain object.
00:29 These properties are named exactly the same as the database columns with a one to
00:34 one relationship. Codelgniter models contain no other
00:37 stand-alone functionality by default. Traditionally, the model is a class where
00:42 common functionality can be defined, including Create, where something like a
00:46 time stamp or other default values can be set.
00:49 Read, where a record is retrieved from the database and used to populate the model.
00:54 Update, where a record in the database is saved, and Destroy where the record and
00:59 the database is deleted. Create, Read, Update, Destroy is a common
01:03 collection of functionality referred to by the acronym CRUD.
01:07 In this chapter, I'm going to extend the Codelgniter model to define the database
01:11 table and primary key that's associated with it.
01:14 Then, I'll integrate Codelgniter's database functionality with CRUD methods
01:18 to allow models to save themselves similar to tradition MVC.
01:23 With this context, I'm going to create models that will allow me to represent
01:26 back issues of a magazine.
01:28
Collapse this transcript
Modeling a magazine
00:00 Magazine back issues have a number of common properties.
00:03 For the purposes of this course, I'm going to limit the domain to two models.
00:07 One for the publication as a unifying record and the second for the issues themselves.
00:13 Each publication has a unique identifier, the publication id and a publication name.
00:20 Magazine back issues are a little bit more complex.
00:24 They have a unique identifier, the issue id, then the unifying record to the
00:28 publication, publication id. As an issue number, which is the number
00:32 given by the publisher and the date of publication, and finally the path to the
00:37 file containing the cover. Let's switch to the IDE and start the
00:41 models for the publication and issue. Models are stored in application models,
00:48 navigate there now. There's currently nothing in there, except
00:51 for the index place holder. I'm going to create a new file for the publication.
00:58 Same as controller names, the file name will be all lower case.
01:01 Publication.php. In the empty file, let's start a new class.
01:07 The class name must be the same as the file name with the exception that it must
01:12 start with an uppercase letter. So publication and all remaining letters
01:17 must be lowercase. You can use an underscore as well.
01:20 Each model extends the coding nighter underscore model.
01:25 Class. Save the empty class, then right-click on
01:29 CI_Model and go to Navigate, Go To Declaration.
01:35 Let's see what it's actually doing. It's extremely minimal.
01:38 The parent constructor is just sending a log message and provides a magic get
01:43 method for allowing models to access loaded classes using the same syntax as controllers.
01:48 In short, I've got a pretty blank slate. But that's cool.
01:51 Close the CI model. I'm going to add two properties to the
01:56 publication to store both unique identifier and the name.
01:59 Remember to add proper documentation. Public publication_id then public
02:08 publication name. I'm going to add documentation, so this
02:13 will be an integer. This will be a string.
02:22 So this will be the location unique identifier, and this is a publication name.
02:30 Save because that's all that's needed for now.
02:31 I'll add persistence and other functionality in a moment.
02:35 Next, I'll create the model for the issues themselves.
02:38 Create a new file, called Issue.php. So, class issue, extends, ci_model.
02:51 I'll start off with a public issue id, which will be issue unique identifier,
03:01 which is an integer. Next will be a public publication id,
03:08 which is a publication unifying record, which is an integer.
03:18 Then the public issue number which is the publisher assigned issue number also an integer.
03:30 Public issue, date of publication. Date that the issue was published.
03:44 Let's try that as a string. And finally a public issue_cover, which is
03:52 the path to the file containing the cover image.
03:57 That will also be a string. Save the issue_model.
04:00 I now have two models, which is enough to keep track of a simple collection of magazines.
04:07 I built this wonderful place to put things in but how am I going to get the data?
04:10
Collapse this transcript
Saving magazines using active records
00:00 One of the convenient and time saving features of CodeIgniter is a loose
00:03 implementation of the active record design pattern.
00:06 When I use CodeIgniter's active records, I don't need to create classes to connect to
00:10 each database table, but I should create a model for each database table.
00:14 And I can use active records to make the models perform database operations.
00:18 This system is database agnostic, meaning all the query syntax is generated automatically.
00:24 I can access CodeIgniter's database using $this->db followed by commands such as
00:30 insert Update and delete. Rather than explicitly breaking down each
00:34 command, I will demonstrate by example, by updating the models to allow them to be persistent.
00:39 I am also going to extend the bare minimum of native CodeIgniter model class to be
00:43 more functional by adding generic CRUD functionality to it.
00:47 This approach will also demonstrate how to extend the CodeIgniter functionality.
00:51 If I wanted to generically extend a CodeIgniter class, a specific naming
00:55 convention is required. Instead of ci_, use my_.
01:02 I'll switch to NetBeans and navigate to the Core folder.
01:05 I'm going to extend the CI model class, so, I'll create a new file named, my_model.php.
01:14 Class, my_model extends CI_model. Now, your initial reaction may be to make
01:26 this class abstract. I'll be honest, that's what I wanted to do first.
01:30 But CodeIgniter instantiates these classes and abstract classes can't be instantiated.
01:35 Therefore, it'll just have generic functionality that won't work until it's extended.
01:40 I'll start by adding a constant containing the name of the database table that'll
01:46 store records of a given model. This is very helpful for organization and
01:49 documentation as well. I have to set a value, so, I'll just make
01:53 it abstract, and just override it. I will define a second constant containing
01:58 the primary key for the table, const DB_TABLE_PK equals abstract.
02:06 Next, I am to going to create the four CRUD methods.
02:09 I will start with create, which will be an insert method.
02:12 I will make it private as I'm going to have a more unifying save method that will
02:18 determine whether to call insert or update.
02:21 That's in documentation, create record. I'm going to use this DB to access active
02:27 record, then the method insert, which takes two arguments.
02:33 The name of the table then questioned as a string.
02:37 And then object containing the arguments that mapped to table columns that will be
02:41 written, which will just be this. The insert operation will not manually
02:45 populate anything, so, I will have to manually populate the model with the
02:49 insert ID. Fortunately there's a method for that.
02:52 This curly brace this DB_TABLE_PK equals this db, and then the method, insert_id.
03:02 That's all that' needed. And let's do a more complex one, which is
03:06 the update method, which I'll also make private, so, I can call it from the
03:09 unified save method. Private function update.
03:13 Then give a documentation, update record. This -> db -> update, takes three
03:23 arguments: the name of the table to update, which will be this db table, and
03:28 an array or object containing the columns or values to update, which will just be this.
03:34 And the primary key of the table that will be updated.
03:36 This DB_TABLE_ PK, I'll use the constants defined earlier to make a generic.
03:42 To prepare for a loading method, I'm going to make a helper that will populate
03:46 the model from an array or standard class. Which will take one argument, a mixed row.
03:50 So, public function populate. And I'll take a row.
03:58 So, populate from an array or standard class, param mixed row.
04:08 And then for each row as key value, this dollar sign key equals value.
04:19 Next, I'll implement a method for loading a single record from the database into a
04:23 model that takes one argument. I'll call it public function load,
04:28 which'll take one argument, the ID of the record.
04:33 (NOISE) Load from the database. Param will be an integer containing the
04:40 primary key. In this method, I will assign a variable
04:43 called query to the result of this -> db -> get_where, which retrieves a standard
04:51 object with a result. It takes two arguments, which is the table
04:54 name again, DB_TABLE followed by an array of the key value pairs that it will be
04:58 matched against. Which in this case will be just the
05:02 primary key and the ID I want to look up. This DB_TABLE_PK, assign to ID.
05:10 I'll use the previously created populate method to populate the object.
05:14 So, this -> populate with query -> row. The final method of CRUD is delete: public
05:26 function delete. Delete the current record, this -> db -> delete.
05:36 The delete method takes the name of the table, this DB_TABLE followed by an array
05:41 similar to the where statement I used in load.
05:46 This time, I'll specify the argument containing the primary key using the constant.
05:51 This DB_TABLE_PK, this, this DB_TABLE_PK. Finally, I'll unset this primary key once
06:07 the deletion operation has occurred, as the record won't exist anymore.
06:11 Now that I have the full CRUD functionality to find, let's make a public
06:14 method for saving that will decide whether to insert or update, public function save.
06:21 Save the record. If is set this primary key, use the update
06:32 method, this -> update. Otherwise, it's an insert.
06:42 The final piece of common funtionality that I'll impliment is an unfilter get
06:46 which will retrieve all records from the models database table.
06:50 I'll include optional support for a limit and off-set, which will be useful if I
06:53 ever implement impugnation. I'll start with documentation.
07:00 Get an array of models with an optional limit, offset.
07:07 Param, int, limit, which will be optional. Param, int, offset: optional, like if it's
07:15 set, requires limit. Return an array of models populated by
07:24 database, keyed by the primary key. Then, public function get, will limit
07:29 defaulting to 0 and an offset also defaulting to 0.
07:37 So, if there is a limit, I'm going to assign query to this -> db -> get.
07:46 Which takes the name of the table, this -> DB_TABLE, and an optional limit and offset.
07:53 Limit offset. So, if there is no limit query equals this
08:00 db -> get, and then just this DB_TABLE, which will return all rows.
08:08 Now that the query's been performed, let's build the return value.
08:11 I'll start with an empty array. Alright val equals array.
08:15 Then, get the class of the current model, get_class of this.
08:21 I can iterate over the query using the method result, which will return database
08:26 rows, for each query -> result as row. Create a new instance of the current class.
08:35 So, model equals new class. Populated with a helper function, so,
08:42 model -> populate with row. Then, added to the return value using the
08:48 primary key. Ret_val, row, and then this DB_TABLE_PK
08:57 equals model. The primary key is a nice shortcut if you
09:01 don't want to use the constant or try to remember what the key name is.
09:05 Finally, return the ret_val, save the file.
09:10 This seems like a lot of work, and in someways it is.
09:13 However, it also highlights how to extend native CodeIgniter classes, and it will
09:17 save me from writing returning code in returning my models.
09:19 Let's give the models' four CRUD functionality, open the publication model.
09:24 Instead of CI model, we'll extend my model instead.
09:30 Then I'll add the constants containing the table name, Const DB_TABLE equals publications.
09:40 And the primary key, const DB_TABLE_PK equals publication_id, save then open the
09:49 issue model. Again, I'll extend MY_MODEL const DB_TABLE
09:56 equals issues, and const DB_TABLE_PK equals issue id.
10:05 Save again. At this point the models have now four
10:08 CRUD functionality using CodeIgniter's active records.
10:11 Let's test it out. Open the magazine controller and navigate
10:15 to the index method. CodeIgniter requires that models be loaded
10:19 before they can be used by using load. I'll demonstrate two ways of working with methods.
10:25 One by using this and the other by instantiation.
10:29 I'll start by creating the publication. So, this -> load -> model, which has just
10:36 one argument, the name of the model, which will be Publication.
10:40 When a model is loaded, the model is made available through this using the class
10:44 name as the property name. I'm going to set the publication name
10:48 using, this. So, this -> publication ->
10:52 publication_name equals Sandy shore. That's all I need to create the record.
10:59 So, I will save it. This -> publication -> save.
11:05 Let's see the result by dumping the model. Echo tt pre, var_export, this ->
11:14 publication, True. Now close the pre and the tt.
11:21 After I've created the publication, I'll create a new issue.
11:25 Same as before, I'll use load to get the model.
11:27 This -> load -> model, the model's name is Issue.
11:33 However, this time I'll instantiate a new issue model and assign it to a variable.
11:37 If I didn't use this load, the class would not be found.
11:41 Issue equals new Issue. I'll set the publication id from the
11:47 publication model. Issue -> publication_id equals this ->
11:52 publication -> publication_id. I'm going to set the issue number to two.
12:01 Issue -> issue_number equals 2. And I'll set the date of the publication
12:07 using PHP's date for February 1st, 2013. Issue -> issue_date_publication equals
12:15 date, 2013-02-01. CodeIgniter is going to handle the
12:21 conversion of MySQL's date format, which is time saving.
12:24 When I'm done, I'll save the issue; issue -> save, and then debug the result.
12:31 I'm just going to copy and paste that from above, and var_export issue, TRUE.
12:38 Save the controller, then return to the browser and refresh.
12:44 I can see two models. The first containing publication id number
12:48 one named sandy shore, and then issue id number one with publication id number one,
12:53 an issue number set as two, and the date publication.
12:58 Note that the issue cover which I didn't set, is still null.
13:02 We'll set the cover later in the course. This way of looking at magazine back
13:06 issues works, technically I guess, but is this really nice to look at?
13:10 Instead of dumping the result, let's format it cleanly.
13:13
Collapse this transcript
Displaying a magazine
00:00 Earlier I created a view for presenting content to separate presentation from logic.
00:05 One of the key features of Codelgniter views is the ability to pass data to the
00:09 view for rendering in a standardized way. Data can be passed either as an array or
00:14 an object. I'm going to create a view that renders a
00:17 magazine, but firs tI'll need to pass data to the view.
00:20 When data is passed to the view the keys and array or the parameters of an object
00:24 are accessible as variables with the same name, which can be really handy.
00:29 Since an issue relates to a publication I'm going to pass both the issue and the
00:33 publication to the view. So, I'll just use an array.
00:36 A more complex implementation that I'm not going to demonstrate but something to keep
00:40 in mind would be to use lazy instantiation and actually load the publication from the
00:45 issue model. I'll keep it simple for now.
00:47 Switch the ID, and make sure that you have the magazine controller open.
00:52 In the index method, let's wipe everything out, and start fresh.
00:56 I'm going to start with the variable data containing an array that I'll pass to the view.
01:02 Then I'll load the publication model. I'll instatiate a new publication, and
01:14 load the first record by ID. Publication, load, by the ID.
01:20 Now that the publication has been populated, i'll put it into the data array.
01:24 Data, key named, publication, equals publication.
01:31 Next, we'll prepare the issue by loading the model.
01:34 This, load, model, issue. I'll instantiate, issue, equals new issue,
01:42 and load issue load one then I'll also put this issue into the data array, data issue
01:54 equals issue. Now that all the data has been prepared,
02:00 I'll render the magazine list field. This, load ,view magazines, then, a new
02:09 view that doesn't exist yet for rendering a magazine back issue.
02:12 For the second argument I'll pass the data array.
02:15 So, this load view, magazine, and then data.
02:22 Save the controller, then navigate to the views folder and create a new file for the
02:30 magazine view called magazine.php. Remember, a view is HTML with a little bit
02:37 of php, so I'll start off with a div with a class of magazine.
02:43 On a new line I'll create the container for the publication name and issue with a classname_issue.
02:48 Now for a little PHP I'm going to echo the publication name but as a developer I know
02:55 that I can't ever trust user input. To sanitize the display, I'll use a code
03:01 ignitor, common function. Common functions are available at any
03:05 point during execution. In this instance, I'll use HTML escape
03:10 which is a shortcut for HTML special chars.
03:13 HTML accepts either an array of input or just a string.
03:18 When I pass an array of data to the view, CodeIgniter makes each key available as
03:22 the variable with the same name. I want the publication name, so I'll
03:29 access publication and the property publication name.
03:34 Close parenthesis, add a semicolon, and close the PHP tag.
03:39 On a new line, I'm going to display the issue number.
03:42 So, I'll start with a hash tag, then I'll open a PHP tag, then echo, html, escape to
03:48 issue parameter issue number and semicolon and close out.
03:54 And then make sure the div is closed out as well.
03:58 Finally I'll create a div that'll contain the issues_data_publication, class date.
04:06 I'm just going to echo, HTML escape the issue, issue date publication for now.
04:16 Make sure that the date div is closed, and the magazine div is closed.
04:20 Save, then go back to the browser, and load the Sandbox page.
04:24 Now I see my magazines, and my one lonely back-issue of Sandy Shores.
04:30 It's not very pretty, but it's functional, and shows that I'm able to store and
04:34 retrieve persistent data, then render it in a standardized manner.
04:38 In this chapter, I've described what a model is and how it's used.
04:42 Then modelled the two components of a magazine, the publication and a back issue.
04:46 Then I demonstrated how to save a magazine using Active Record and added common
04:52 functionality to a base coding meta class. Then finally rendered a magazine by
04:56 passing data to a view where I escaped user input so it doesn't break HTML or
05:01 introduce security risks. In the next chapter, I'm going to use
05:05 another major feature of Coding Nyder, known as Libraries.
05:08
Collapse this transcript
3. Adding Functionality with Libraries
What are CodeIgniter libraries?
00:00 In computer science, a library is a collection of functionality that serves a
00:04 specific purpose with a well defined interface and logical structure.
00:07 CodeIgniter comes with several dozen libraries for common tasks.
00:11 Each implemented as a class. Examples of classes include the input
00:15 class, form validation class and HTML table class.
00:20 To use a library, it needs to be initialized within a controller using the
00:24 following initialization method: this -> load ->library, followed by a string
00:27 containing the machine name of the library.
00:30 For example, form_validation. Multiple libraries can be initialized at
00:36 once by passing an array of strings containing the names of the libraries to load.
00:40 Such as form validation and table. Each library has a dedicated page within
00:45 the CodeIgniter User Guide, which includes usage examples and a function reference.
00:50 In this chapter, I'm going to allow users to add magazines using a form, then
00:54 validate those forms including some custom validation.
00:58 After that, I'll use a number of CodeIgniter libraries to accept user input
01:02 and list magazines in a generated HTML table.
01:05 Let's get started.
01:06
Collapse this transcript
Creating a form to add magazines
00:00 In order to implement a validating form in CodeIgniter, I'll need three things.
00:04 First, a controller function that contains the form logic, like processing submitted data.
00:10 Second, a view that contains the form itself, including a place for displaying messages.
00:14 And finally, a view for a message that will be shown upon successful submission.
00:19 Once I have those pieces, I can then add the validation logic.
00:23 I'm going to create a forum to add magazines and I'll start with the controller.
00:27 Within Net beans open the magazine controller.
00:31 Let's add a new method for adding a magazine called add public function add,
00:38 give it a little bit of documentation. Add a magazine.
00:43 One of the parts of the magazine is the publication.
00:46 While it'd be great if users could remember data base identifiers, they tend
00:51 to get lazy and need all the help they can get.
00:54 Therefore, I'll populate the list of available publications on their behalf
00:57 using the publication model. Start by loading the model, populate publications.
01:05 This load model, and I'll give it the publication as the argument.
01:11 Then I'm going to use the get method, which returns an array of populated models.
01:16 Publications equal this, publication get. Now that I have the data, I'll populate
01:24 form options. Publication, form, options equals array,
01:31 foreach the publications, as ID, publication.
01:34 Assign the option by ID to the publication name.
01:41 So publication, form options, ID equals publication.
01:46 Publication_name. When complete, load a view using this,
01:55 load view. With a name of magazine_form, we'll create
02:01 the view in a moment. I'm going to pass it an array.
02:05 Containing one key, publication_form_options assigned to the $publication_form_options.
02:13 Remember to add the semicolon and save. I'll add the validation logic later.
02:19 Next I'll create the view for the form. So I'll navigate to the Views Folder and
02:24 create a new file called magazine_form. Clear out the content, then let's create a
02:32 form in good old fashioned HTML. Form, method equals post.
02:37 I'll start with a div, and then a label for publication, ID with a more human
02:47 readable publication name. Start a select tag with a name of
02:54 publication ID. Select, name equals publication ID.
03:00 Now for a little PHP. Let's iterate through the publication form
03:03 option, for each publication form options as publication id, publication name.
03:12 I'm going to echo an option with a value of the HTML.
03:22 Escaped publication ID. Followed by the html escape publication
03:33 name and close the option. Close out the PHP tag at the end.
03:39 Make sure that the select is closed and the DIV.
03:43 Hm, that seems like a lot of work for a lowly select list.
03:46 I wonder if there is a faster way. Anyway, let's continue with the input text
03:50 for the issue number. Div, then label for equals issue
03:57 underscore number. For the human readable name issue number.
04:04 So, for the input. Type equals text, name is issue number and
04:12 the value. Right now we don't need any default value,
04:16 so we'll just leave it blank. And close out the div.
04:20 The last bit of data that I'll need is the date that the issue was published.
04:24 So, div then label for issue date publication and then date published, human
04:35 readable label. Then again this will be input type equals
04:40 text, the name is issue date publication and the value is empty.
04:48 Was that the div? Finally I'll add a submit button.
04:51 Div input type equals submit, and the value, it's just going to say save.
05:01 Close out the div and the form. Save the magazine form.
05:03 One more piece is needed. The success message.
05:08 Create a new view named Magazine_form_success.php.
05:17 I'll just say div class equals alert and then alert-success say magazine created
05:26 and close the div. Save the success farm.
05:29 Let's see how it looks so far by switching to the browser and navigating to index.php
05:38 magazine add. I see a very bare bones form with a
05:43 publication name select list. Text input for issue number, and date
05:48 published, and a Save button. Type issue three into issue number, and
05:52 click Save. And the input has disappeared.
05:55 We have no logic yet, so it's actually performing perfectly well.
05:58 It's not very useful, on the other hand, so let's add some validation using the
06:02 Form Validation library.
06:03
Collapse this transcript
Validating user input with the form validation library
00:00 Now that the two views of the controller have been set up, I now have something
00:03 that I can use the Form Validation Library with.
00:06 Here's the control flow at a high level. First, I'll load the form_validation library.
00:11 Then, I'll set the validation rules for each form element.
00:15 When that's complete, I'll execute the validator to see if it passed or not.
00:19 With that answer, the application can decide what to do based on validation success.
00:23 I'm going to get started by returning to the IDE.
00:25 I'll open the magazine controller, and navigate to right before the view is displayed.
00:32 I'll start by loading the form validation library.
00:35 So, this, load, library, with a name, form, underscore, validation.
00:42 Next I'll call a method called set rules. Set rules takes an array of arrays that
00:48 contain three key value pairs. The field which is the form fields name, a
00:54 label which is a human readable label that will be shown on failures and rules.
00:58 A string containing the names of form validation call back functions.
01:02 There's a complete list of validators that ship with CodeIgniter at the following URL.
01:07 For the time being we'll start slow and build up.
01:10 This form validation set underscore rules. I'll pass an array.
01:18 The first array will be for publication Id.
01:23 Array, field, publication_id and then the label will just be publication.
01:30 The publication will be required. Fortunately there's a validator callback
01:35 named required which will just check to see if content has been set.
01:38 So, rules, required. That was pretty straightforward.
01:48 I'll add a validator for the issue_number as well.
01:53 Array, field, issue_number, label Issue number.
02:01 This time for the rules I'm going to chain two validators together using another
02:07 validator that ships with CodeIgniter that checks if input is numeric.
02:11 To specify multiple validators separate it with a pipe character, so required and
02:17 then a pipe and then is underscore numeric.
02:23 Finally, the publication date. Array, field, issue, date, publication.
02:26 The label is publication date. Now, there are no date validators that
02:29 ship with CodeIgniter, so I'll use a custom callback.
02:42 To do that, start with rules. The publication date is required, but for
02:49 the custom callback. I'll need to start the method name with a
02:52 callback_ followed by the name of the actual method, which I'll call date_validation.
02:59 The callback is a method in the current controller, which I'll create in a moment.
03:04 By default, the error messages are wrapped in a paragraph tag.
03:07 Let's spruce things up a little bit by setting the error message to limiters.
03:09 The method takes two arguments. The opening and the closing delimiter.
03:15 This form validation. Set_error_delimiters.
03:22 Have an opening DIV for the class of alert, and alert-error, then followed by a
03:32 closing DIV. Finally, I'll execute the form validator
03:36 using the method run. This, form, validation, run.
03:40 It returns Boolean, true or false, so I can use it with an if statement.
03:46 So we'll start off if the form does not validate.
03:54 We'll show the regular form else if the form did validate, this, load, view,
04:04 magazine form success. Now that we've completed the logic so far,
04:10 let's create a callback function to validate the date.
04:13 Within the controller, create a new public function called date validation that takes
04:22 a string input. Add a little bit of documentation.
04:28 This is a date validation call back, takes a string and it returns a Boolean value.
04:39 True if it passes, fault if it fails. I'm going to use the PHP function check
04:43 date for validation. To do that I'll explode the input on dash,
04:48 so test date equals explode and then input.
04:54 So if then not and I'm going to surpress errors and warnings from check eight.
05:00 Test date 1, test date 2, and then test date 0.
05:08 So if it fails that check I'm going to use one of the methods in form validation
05:14 known as sent message. So this form validation set message, which
05:21 takes two arguments. The first is a string containing the field
05:24 name, which in this case is, date validation, followed by a string
05:29 containing the message, itself. The, and I can use a percent, S, that will
05:34 be replaced with the human readable label set earlier.
05:37 So the percent S field must be in year, month, day, format.
05:45 Since it failed return Boolean false, otherwise it succeeded so return true.
05:50 Save the controller and switch to the browser.
05:55 For the issue number type A which won't validate and click save.
06:00 There's no message, because the form validation method doesn't produce any
06:04 automatic output. Which gives developer control over how the
06:07 application performs. Go back to the IDE, and open the Magazine
06:13 Form view. At the very top, above the form itself,
06:17 I'm going to Echo a function provided by the validation library that will render
06:23 the errors, validation errors. Save then return to the browser and try
06:31 filling validation again. This time I see the error messages I was expecting.
06:36 Lets try to pass validation, so, issue number three.
06:41 And it was published on 2013, March 1st. Click save.
06:47 Magazine created, success. Except it didn't actually create it,
06:52 because one more piece is needed. Persistence.
06:56
Collapse this transcript
Getting user input securely
00:00 The CodeIgniter input class, which is initialized automatically, serves two purposes.
00:05 Securely pre-processing global input data, and providing helper functions for getting
00:09 input data. Among other things, it destroys global
00:12 variables if register_globals is turned on.
00:15 Filters the GET, POST and COOKIE array keys, and provides optional cross site
00:20 scripting attack filtering. Let's go back to the magazine controller.
00:24 Before I show the success message, let's save a new magazine issue.
00:28 I'll start by loading the model. This -> load -> model issue.
00:36 Then, I'll create a new instance of the issue model.
00:39 Issue equals new issue. I'll set the publication ID, issue ->
00:45 publication id equals this, and I'm going to use the input class post method
00:51 with one argument. So input -> post, a string containing the
00:56 element I'm looking for, which is the publication id.
01:00 I'll do the same for the issue_number, equals this -> input -> post ->
01:09 issue_number, and the issue date of publication.
01:13 Issue -> issue -> date publication equals this -> input -> post Issue_date_publication.
01:25 Tell the issue to save itself. Let's make this success message a tiny bit
01:32 more verbose by passing the issue to the view.
01:34 So, comma array, set a key called issue, and assign it to the issue itself.
01:42 Save the controller, then open the magazine form success view.
01:45 I'm going to echo the HTML escaped issue, Issue ID.
01:50 So, magazine number PHP echo html_ escape issue -> issue_id.
01:59 Close it out, put in a space, and then save the view.
02:03 Let's go back to the browser and refresh. It'll ask me if I wish to confirm the
02:10 re-submission of the form. Say yes.
02:12 Now, I see a message saying that magazine number two has been created.
02:16 However, if I navigate back to the root page, I don't see a list containing the
02:22 magazines I created, I only see the one that is being loaded by ID.
02:25 Let's fix that.
02:27
Collapse this transcript
Listing magazines with tables
00:00 The HTML table class, generates HTML tables from arrays or database results sets.
00:06 The table class is initialized in the controller, using this load library table.
00:12 Once it's loaded it can be accessed using this table.
00:15 While I can technically call the library class from within the controller, it's
00:19 best practiced to keep display in the view.
00:23 Going back to the IDE, I'm going to take a look again at the magazine controller
00:27 index method. Right now there's a bunch of hard coded
00:30 stuff, instead I'm going to replace it with something a lot more flexible.
00:35 I'll start by loading the library for table.
00:36 This load, library, table. Next, I'm going to build an array of
00:44 magazines for table library to render, magazines equals array, I will load the
00:50 models for both the issue and the publication by passing in a array, this
00:55 load model then a array containing issue and publication.
01:03 Then I'll get all the issues that are known in the database.
01:05 Issues, equals, this, issue, get, foreach, issues as issue, instantiate a
01:16 publication, publication equals new (SOUND) .
01:21 Publication. Load it with a publication ID from the issue.
01:24 So, publication load, issue, location ID. Then, add an array to the magazine's array
01:33 with the values in the following order. So, magazines equals array, publication.
01:40 Publication name, the issue, issue number and issue, issue date publication.
01:53 Finally, pass the magazines view a variable with the magazines you can remove
01:58 all this data, and then pass magazines in array containing magazines and the
02:07 contents of magazines. We no longer need a single display of the
02:12 magazine so just delete it and save. Next, I'll go to the magazines view.
02:18 I don't have to do anything to initialize the table, it's already been done.
02:22 However, I do want to set a header row and I'll use a method called set heading to do that.
02:28 It just sets th elements with a string that I specified.
02:30 Open up, php, this table set heading Publication, issue, and date.
02:42 I'll pass the magazines variable to the table generation method and echo the result.
02:47 Echo, this, table, generate, magazines. That's all that's needed.
02:54 Save, and then go to the browser and refresh.
02:58 I see a nice table of issues listed. View the source.
03:03 Notice that it's even creating a proper t head and t body using th for the headers.
03:08 You can probably believe the number of times that I've written that markup by hand.
03:12 This is very convenient. Close the source.
03:16 The application is coming along nicely. And building it in some increasingly
03:20 usable functionality, but it's still looking kind of well, unstyled/g.
03:24 Lets add Twitter bootstrap to the mix to improve the look and feel.
03:28 To save time, I performed a little customization at Twitter bootstrap to
03:31 separate things out in implemented at bare bones navigation system.
03:35 Open up your exercise files, and copy the folder named bootstrap to sandbox, into
03:43 application, views. Then copy css, image, and js.
03:56 And put that in the web root. Going back to the IDE, let's take a look
04:01 at the magazine control. Note that since I put the bootstrap into a
04:04 folder, I'm going to start the view name with the name of the folder, slash, then
04:08 the name of the actual view. This, load, view, bootstrap slash header
04:17 and then add at the very end the footer. I'm going to do the same for the add method.
04:25 For the header and the footer. Save.
04:35 Then reload the browser. Things should look a lot better now with
04:39 standardized styling. If I go to add a magazine, the error
04:45 messages will look properly styled. I'll try adding a magazine.
04:48 Sandy Shore issue number 4, published in 2013, 04-01.
04:54 And save. Cool.
04:56 The success message is also properly assigned.
04:59 In this chapter I've defined what CodeIgniter libraries are and how to use them.
05:03 I then created a form to add magazines. With that form, I validated user input
05:08 using the form validation library. Then, securely took user input and saved
05:13 it in data base. Finally, i listed the saved magazines
05:18 using (INAUDIBLE) tables. libraries are useful collection of tools
05:21 in coding but they are not the only collection there are also helpers which
05:25 serve different purpose
05:26
Collapse this transcript
4. Saving Time with Helpers
Using a helper to perform tasks
00:00 Helper files are similar to libraries in that they're a collection of
00:03 functionality, but they're different in that they're not object oriented.
00:07 Instead, they're procedural functions that perform one specific task with no
00:11 dependence on any other function. Examples of helper function files include
00:16 a date helper, form helper and URL helper. Helper files aren't loaded by default.
00:21 So, if I wanted to use one, I'd have to explicitly load it from the controller
00:25 using the helper method. Similar to loading libraries, I can either
00:29 pass a string or an array as the argument. If I needed help getting a date, I just
00:34 use the string date, this -> load -> helper, date.
00:38 If I wanted to load multiple helpers at once, I'd pass it in an array of strings
00:42 like date, form, url. Now, let's revisit that form, but this
00:47 time I'm going to use helpers.
00:49
Collapse this transcript
Avoid reinventing the wheel with the Form Helper
00:00 The form helper is a great shortcut for quickly building forms.
00:03 Instead of writing raw HTML I can greatly simplify the view by using the form helper
00:08 functions to generate the markup. The form helper functions return html, so
00:13 they should be used in the view, not in the controller.
00:16 I will have to load the helper from the controller.
00:19 I'm going to switch back to Netbeans. And go to the add method if I'm not
00:23 already there. And add the method to load the form helper.
00:27 So, this, load, helper, form. Save the controller, then open the
00:34 magazine form the first line echoing the validation errors is good so let's leave
00:39 that alone. However I'm sorry to say that everything
00:42 else is going to get replaced. Its good to have perspective to know that
00:45 there's than one way to perform a task. I'm going to start with a new form using
00:51 the function form open PHP echo form open. I have the ability to specify a particular
00:58 action and attribute. But since it's posting to the same place I
01:00 can leave the action off and form open defaults to post so there's really nothing
01:05 else to do, and close the tag. We don't need the duplicate form so remove that.
01:11 Next the label for publication name, surely there's a better way.
01:14 Yes there is, using the echo form label, PHP, echo, form, label.
01:22 It takes two arguments, human readable name and the identifier, publication, id
01:29 and close the tag. Select lists are referred to as drop downs
01:35 with encoding data/g, which is a little funny.
01:37 PHP, echo, form dropdown. Which just takes the form element name,
01:43 publication ID, followed by an array of option labels keyed by value.
01:48 Just as I did before. So publication, Form options, the third
01:54 argument is the default value. I'm going to use another form helper
01:58 called set value, which grabs the value from the post array, great for failed
02:02 formula submissions. So set value and then the key publication
02:08 ID and close that out. I'll completely remove the redundant html
02:14 contents, so that's one, two, three, four, five, six, seven lines of code that have
02:19 been saved. Next, I'll replace the label for the issue
02:22 number, PHP echo form label issue number, followed by the identifier, issue number
02:34 and close the tag. I'll use form input which defaults the
02:37 text input for the issue number. Php echo form input.
02:43 The first argument takes the form element name, which is issue number, and the
02:47 second is the default value. I'll use set value again, passing it,
02:52 issue number. To populate it on failed submissions.
02:56 Close out the php tag, and remove the unnecessary HTML.
03:00 We'll do something very similar for the issue date publication.
03:11 And date published. Replace the label.
03:15 And remove the unnecessary html. The last element will be the submit
03:21 button, which we'll use form submit. PHP echo form submit, save with label, save.
03:31 Semi colon, and close the PHP tag. I'll close the form with php echo
03:38 form_close and save the viewing. Doesn't this look a lot cleaner?
03:44 Rather than a mix of loops and hard coded html.
03:47 There's some clean html for designer to do their magic to and some simple php
03:51 function calls. Go back to the browser and go to the add
03:55 form and intentionally fail validation by submitting issue number kitty.
04:01 This time the default value is set. Very cool.
04:04 Let's kick things up a notch with the ability to upload cover images.
04:09
Collapse this transcript
Uploading images with the File Uploading class
00:00 File uploads can be a pain, but CodeIgniter tries to eliminate some of the
00:03 more obnoxious parts using the file uploading class which is especially
00:08 helpful for images. File uploads consist of the following process.
00:12 First, the file form element is displayed to the user.
00:15 Then, the form is submitted and the file is uploaded.
00:19 Based on file upload preferences such as image height, width or maximum size, the
00:23 file is validated. When validation is past, the file metadata
00:28 is available for use. I'm going to allow users to upload cover
00:31 images of the back issues. First, switch to a terminal and navigate
00:37 to the root directory of your CodeIgniter installation, verify that you're in the
00:40 right place. Next, make a directory that you can use to
00:44 upload files to. Mkdir, space, upload.
00:49 Next, set the permissions on that directory.
00:51 Chmod 755 is a best practice. In a worst-case scenario, use 777 but this
00:58 is almost never necessary and not recommended, as it's a big security risk.
01:04 Now that the designation exists, I can go back to the IDE.
01:07 Open up the magazine controller, I'm going to create a configuration array for
01:12 file uploads. This also handles validation so, this part
01:15 is fairly important. There's a comprehensive list of all the
01:18 options in the user guide at ellislab.com. So, starting with configuration array,
01:24 config equals array. The first step is the upload
01:29 underscore_path which is just upload. Next, specify the allowed file extension types.
01:37 Allowed_types and we'll set that to gif, jpg and png.
01:43 Then, the maximum file size in kilobytes, max_size I'll set it to 250.
01:53 The maximum width and pixels max_width 1920 and maximum height max_height and
02:04 we'll set that to 1080. Finally, the upload library can be loaded
02:09 with a configuration, this, load, library, upload and pass it to config.
02:17 Then navigate to the form validation. The form validator doesn't actually check
02:26 file uploads, which is a bit goofy. Instead, I'm going to have to explicitly
02:30 specify a file upload check, using do_upload and the name of the form element.
02:35 If you're uploading multiple files, you will have to do multiple do_uploads.
02:40 If you leave out the name of the form element, it won't work.
02:44 Finally, I'm going to make file upload optional, by checking the files array,
02:48 then preforming validation. As ugly as this looks, this is the
02:51 recommended method. So, I'm going to navigate to the form
02:55 validation run. I'll start with check_file_upload equals false.
03:03 if is set, the FILES super global, issue_cover error and files issue_cover
03:13 error not equals 4, check_file_upload equals true.
03:20 Then, we'll change the if on the validation run.
03:26 If the form validation fails or check_file_upload and not this, upload,
03:36 do_upload using the key issue_cover, we'll wrap this whole section in parenthesis and save.
03:49 The last piece of the puzzler for the controller, is what to do with the
03:52 uploaded file. Just before issue_save, get the uploaded
03:58 file metadata, upload_data equals this, upload_data.
04:04 If it exists, set the issue_cover to the file name.
04:07 If is set, upload_data, key, file_name, issue, issue_cover equals upload_data, file_name.
04:21 Save the controller, then go to the magazine form view.
04:26 Immediately following the echoed validation errors, I'll need to explicitly
04:29 display the upload errors. Yes, it's separate from the form upload.
04:33 PHP echo, this, upload, display_errors. And it's going to take two arguments which
04:43 is the opening, div, class, equals alert, alert-error and close and followed by the
04:52 closed div. Close the PHP tag, and then I will need to
04:58 switch the form open to a form open multi part to handle the uploaded files.
05:05 Before the Submit button, let's create the form element for the file upload.
05:10 Div, PHP echo form_label, cover scan, then issue_cover is the name.
05:19 Close the PHP. And PHP echo.
05:23 Then I'm going to use the form helper, form_upload, with the name of the field as
05:28 an argument. form_upload, issue_cover.
05:34 Save, then go back to the browser. Let's click, Add, to see the new file form.
05:39 Let's create issue number five of Sandy Shores, with a publish date of 2013-06-01.
05:46 Click save and it should be successful as the file upload is optional.
05:51 Let's go back to Add, and add issue number two of Sandy Shores with a date
05:57 2013-02-01, but this time I'll upload. Go to Assets > NotAnImage.txt.
06:06 Click Open, and Save. It'll be correctly rejected as disallowed.
06:11 Finally upload the JPEG version of issue number two And that should work, success.
06:19 Check the upload directory as well. Now, if I go back to the magazine list, I
06:28 can see that there's a duplicate entry for issue number two and I can't see the covers.
06:32 Mm-hm, maybe I should do something about that.
06:35
Collapse this transcript
Viewing and deleting magazines
00:00 I've been making solid progress but it's time to focus, and put some final touches
00:04 on this application. There's two major pieces missing.
00:06 The ability to view magazines, and delete an individual magazine.
00:11 In some ways, the two pieces of functionality are very similar.
00:14 In that they both require something to get an issue_id then some kind of action on a
00:18 loaded model. I'm going to start by adding links to view
00:22 and delete from the magazine list. Edit the magazine controller and at the
00:26 top of the index function add a load helper to load the URL helper.
00:34 This load, helper, URL. It would be helpful to see whether a
00:39 magazine has a cover associated with it. So at the end of the 4H loop lets add a
00:44 column with a simple Y or N if there is a cover Issue issue_cover switch yes or no.
00:53 I'm going to use the anchor helper function to generate links based on the
00:58 local URL as a final column in the magaine table.
01:01 I'll make links to both view and edit. The first argument f anchor is the path
01:06 which will be magazine/view. And then I'm going to pass it the issue.
01:12 Issue_id. The second is the text view.
01:18 I'll separate them with a simple pipe. Anchor magazine/delete and then add the
01:26 issue, issue_id" then delete. Save the controller, then switch to the
01:34 magazine's view. Add the additional headings Cover and Actions.
01:38 Cover, Actions. Save the view.
01:43 Then let's take a look at the browser. Refresh the magazines list and it looks a
01:48 little bit more functional. Cool, I can see whether or not a cover is
01:52 associated with a magazine now. And there's links to delete and view.
01:55 Let's make those functional. Switch back to the id.
02:00 Go back to the magazine controller. I'm going to start with a new method for view.
02:06 Public function view. We'll take one argument, the issue_id.
02:12 And documentation, view a magazine. Type will be an integer.
02:23 The routing system will automatically pass the argument so I don't need to make any
02:27 additional changes on that side. I'll start by loading the HTML helper,
02:31 I'll need it in a moment, this->load->helper, html.
02:37 Then I'll load the header itself, this->load->view, bootstrap/header then
02:45 the models for issue and publication, this->load->model pass it an array
02:53 containing issue, publication. I'm going to try to load an issue by its id.
03:02 Issue equals new Issue. Then issue load issue_id.
03:13 if an issue can't be loaded show a 404 error using one of the common functions
03:17 show_404 which will does just that and exit.
03:20 If not, issue, issue_id, show_404. Otherwise, we have an issue so load the publication.
03:34 Publication equals new Publication, then publication->load the issue, publication_id.
03:46 I'm going to pass both to the magazine view created earlier.
03:50 This, load->view, magazine, pass in an array.
03:59 The key issue and publication. Finally show the footer, let me copy the
04:13 header, make a small change, footer. Save the controller then edit the magazine view.
04:23 Right before the closing div, I'm going to add some logic.
04:27 Php, if, issue as a issue_cover and we'll post the php, show a div with class cover,
04:44 close the div, indent, php. I'm going to use a function from the html
04:56 helper called image, which will generate an image tag based on a path.
05:01 So echo Image, upload/.and then issue->issue_cover.
05:08 Make sure the if is closed out, and save. I'm going to switch to the browser to see
05:17 the view in action. Click View on the item with the cover.
05:22 Neat, the cover is now rendered. Now to clean it up a bit, I'll implement
05:26 the last missing functionality, a delete. Go back to the magazine controller.
05:30 Start a new method called delete. Public function delete, which takes one
05:36 argument, an issue_id. Always remember the documentation.
05:42 Delete a magazine which takes an integer. I don't need any helpers so I'll just
05:49 start off with loading the header. This load->view bootstrap/header then the
05:58 model for the issue only. This->load model->array issue, instantiate
06:08 a new issue, issue equals new Issue and try to load it, issue load issue_id.
06:20 Again if the issue can't be found show 404, otherwise delete the issue using the
06:27 common method delete, issue delete. Show a success message by using a new view
06:34 magazine deleted which I will create it in just a moment passing just the issue_id,
06:40 this->load->view magazine deleted an array containing issue_id, issue_id.
06:53 Finally show the footer, save the controller then create a new view Named magazine_deleted.
07:06 This is going to be a one liner, div class equals alert, alert-success magazine
07:19 number then php echo html_escape Issue_id. Close that out and then the verb which
07:33 will be deleted. Save the new view and let's test it.
07:40 From the browser go back to the list of magazines.
07:43 And delete the first one without a cover. I get a message that the magazine one was deleted.
07:49 If I go to the home screen, there's one less magazine to show.
07:53 That wraps up the base functionality for the magazine catalog system.
07:57 In this chapter, I discussed how to use a helper to perform tasks, then demonstrated
08:02 how to use the form helper to save a lot of time by generating HTML forms.
08:07 I then delved into uploading images using the File Uploading class.
08:11 Then finally viewed and deleted magazines. That's a lot of functionality that I've
08:15 covered throughout this course. So, where to go from here?
08:18
Collapse this transcript
Conclusion
Where to go from here
00:00 Throughout this course, I've covered a lot of base functionality.
00:03 Starting with the what and why of CodeIgniter, then explored models, views,
00:08 controllers, libraries and helpers. I'll be honest.
00:11 It was kind of difficult to hold back and focus.
00:14 There's a lot that can be done in the magazine catalog system.
00:17 Here's some ideas that can be used to extend this application, in three categories.
00:21 Starting with, Usability Ideas, such as adding a validator that prevents duplicate
00:28 magazines and publications. Highlighting erroring fields, which is
00:31 supported by Twitter bootstrap. Adding a confirmation step to deletion and
00:36 sorting magazines. Then, you could do some changes to the
00:40 look and feel, including adding pagination using the pagination library.
00:46 Making a thumbnail upon upload, maybe for inclusion in the list of magazines.
00:50 Formatting dates using the date helper so, it excludes the day.
00:54 Styling magazine covers and lists, maybe using a Hero header or three abreast
00:58 instead of a table. And then finally, configuring the url
01:02 without index.php with web server rewrites to make it much cleaner.
01:07 Then I have a few functional ideas, including a comprehensive much more
01:11 flexible navigation system that's configurable.
01:14 A less manual templating system, which will save code and make it harder to forget.
01:18 Editing magazines instead of deleting and creating them manually.
01:21 Publication management, because currently there's no interface for it.
01:25 Summary reports, such as, you have 13 issues of Sandy Shore magazine.
01:29 And users sessions and security. Because it would be optimal if access
01:34 could be controlled. This might seem like a lot, but code
01:37 igniter is a very flexible framework. And each of these thing I know, can be done.
01:41 And these are real world tasks that I'd like to see in an application for a client.
01:45
Collapse this transcript
Farewell
00:00 Codelgniter is an exciting framework, that I've enjoyed working with.
00:03 Of course, it's not the only framework out there, but it's one of the fastest ones available.
00:08 Codelgniter's ease of use is bolstered by it's flexibility.
00:11 While I will admit I was a little frustrated by it's approach to models, I
00:15 got around it in moments and bent the framework to my will without breaking it.
00:18 That's fantastic and that's really what developers need.
00:21 There's no one right path, and if our framework will get you most of the way,
00:25 use it. I appreciate your time and your interest
00:28 in this subject. I'd also like to thank the fantastic
00:30 production team at lynda.com, for all their hard work behind the scenes.
00:34 Please take a moment to give feedback through the course home page.
00:37 It'll help make future courses better. Thanks for watching.
00:40
Collapse this transcript


Suggested courses to watch next:


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked