{"id":706,"date":"2014-07-11T09:37:03","date_gmt":"2014-07-11T13:37:03","guid":{"rendered":"http:\/\/blogs.law.harvard.edu\/acts\/?p=706"},"modified":"2019-02-26T16:32:47","modified_gmt":"2019-02-26T21:32:47","slug":"basic-lti-workshop-using-php","status":"publish","type":"post","link":"https:\/\/archive.blogs.harvard.edu\/acts\/2014\/07\/11\/basic-lti-workshop-using-php\/","title":{"rendered":"Basic LTI Tutorial Using PHP"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>This tutorial will get you up and running with a development environment, complete with a virtual machine running an Apache 2 server with PHP, a basic LTI library written in PHP, and a simple basic LTI-compliant LMS. By the end of the tutorial, you will have written a simple &#8220;Hello, World!&#8221; LTI tool, and you will be ready to delve into the world of LTI coding. Please note that we assume you already have the following knowledge:<\/p>\n<ul>\n<li>An understanding of directories and files, and how to navigate through them using a terminal window on your operating system;<\/li>\n<li>How to install software packages on your operating system;<\/li>\n<li>An understanding of fundamental web concepts, such as HTML, CSS, HTTP requests, POST requests, etc.<\/li>\n<li>Some experience in setting up web servers;<\/li>\n<li>Basic knowledge of PHP;<\/li>\n<li>An understanding of <a href=\"http:\/\/www.edu-apps.org\/code.html#intro\">basic LTI concepts<\/a> and, in particular, the <a href=\"http:\/\/www.imsglobal.org\/lti\/blti\/bltiv1p0\/ltiBLTIimgv1p0.html\">Basic LTI (v1.0) specifications<\/a>.<\/li>\n<\/ul>\n<p>Ready to begin? No? Then grab some coffee or another refreshing beverage. We&#8217;ll wait. . .<\/p>\n<p>Ready now? We hope so! Because we&#8217;re getting started.<\/p>\n<p><!--more--><\/p>\n<h2>Install Pre-Requisites<\/h2>\n<p>In order to complete this tutorial, you will need to set up a development environment. Our tutorial uses a <a title=\"Git\" href=\"http:\/\/git-scm.com\/\">Git<\/a> client to download the code from our <a title=\"Harvard Academic Technology Group GitHub\" href=\"https:\/\/github.com\/harvard-atg\">Github repository<\/a>, <a title=\"VirtualBox\" href=\"https:\/\/www.virtualbox.org\/\">VirtualBox<\/a> to set up a virtual machine, and <a title=\"Vagrant\" href=\"https:\/\/www.vagrantup.com\/\">Vagrant<\/a> to manage the virtual machine. However, all you really need is 1) the code in our repository, and 2) a web server running PHP. If you don&#8217;t want to install VirtualBox or Vagrant, you don&#8217;t have to, but we highly recommend doing so in case you want to experiment with them.<\/p>\n<blockquote><p><strong>TIP!<\/strong> Already have a web server and PHP installed somewhere? Then just make certain to <a title=\"Install Git\" href=\"#installGit\">install Git<\/a>, then you can <a title=\"Download Our Code\" href=\"http:\/\/blogs.law.harvard.edu\/acts\/?p=706&amp;page=2\">download our code from the Github repository<\/a>. You can still follow along with the tutorial, but some URLs and file names may change. We trust that you know what you are doing!<\/p><\/blockquote>\n<h3><a id=\"installGit\"><\/a>Install Git<\/h3>\n<p>We will be using the Git command-line client in this tutorial, so head on over to the Git web site, <a title=\"Download Git\" href=\"http:\/\/git-scm.com\/downloads\">download the command-line client<\/a>, and follow the instructions for installation.<\/p>\n<blockquote><p><strong>TIP!<\/strong> If you prefer a GUI to the command line, you can also download the GitHub GUI client by visiting the <a title=\"GitHub Git setup page\" href=\"https:\/\/help.github.com\/articles\/set-up-git\">GitHub Git setup page<\/a>, but this tutorial only has instructions for the command line.<\/p><\/blockquote>\n<h3>Install VirtualBox<\/h3>\n<p>Oracle&#8217;s VirtualBox is a powerful environment for running all kinds of virtual machines on Windows, Mac, and Linux. It is very much like Parallels or VMWare, except VirtualBox is free. Visit the <a title=\"VirtualBox Downloads\" href=\"https:\/\/www.virtualbox.org\/wiki\/Downloads\">VirtualBox downloads page<\/a> to find the software appropriate for your system, download it, and install it.<\/p>\n<blockquote><p><strong>TIP!<\/strong> If you want, you can also download the Extension Pack, which provides additional functionality.<\/p><\/blockquote>\n<h3>Install Vagrant<\/h3>\n<p>Vagrant makes it easy to fire up and provision virtual machines with VirtualBox. Visit the <a title=\"Vagrant Downloads\" href=\"https:\/\/www.vagrantup.com\/downloads.html\">Vagrant downloads page<\/a> to find the software appropriate for your system, download it, and install it.<\/p>\n<blockquote><p><strong>TIP!<\/strong> To ensure the successful installation of Git, VirtualBox, and Vagrant, please make certain to visit the web sites listed above, and read through the documentation. Some people might call this <a href=\"http:\/\/en.wikipedia.org\/wiki\/RTFM\"><strong>RTFM<\/strong><\/a>, but we&#8217;re too polite to say that.<\/p><\/blockquote>\n<p>Once you have Git, VirtualBox, and Vagrant up and running on your system, you&#8217;re ready to start downloading code!<\/p>\n<p><!--nextpage--><\/p>\n<h2>Download Our Code<\/h2>\n<p>To get you up and running, we provide you with a Vagrant file and Puppet manifesto to set up your virtual machine (both were generated by the GUI at <a title=\"PuPHPet\" href=\"puphpet.com\">PuPHPet<\/a>), as well as a Basic LTI library written in PHP (originally found through the <a title=\"Writing LTI Stuff\" href=\"http:\/\/www.edu-apps.org\/code.html\">Edu Apps Writing LTI Stuff page<\/a>, but, apparently, no longer available). To download this code, you will need to <code>clone<\/code> it using Git. First, create and change into a directory where you want to stash the code. Once you do so, type in the following command:<\/p>\n<blockquote><p><code>git clone https:\/\/github.com\/Harvard-ATG\/workshop-lti-basic.git<br \/>\n<\/code><\/p><\/blockquote>\n<p>This will download everything from the Git repository and store it in a folder called <code>workshop-lti-basic<\/code>.<\/p>\n<h2>Start Up Your Virtual Environment<\/h2>\n<p>Once you have downloaded the code, change into the <code>workshop-lti-basic<\/code> folder:<\/p>\n<blockquote><p><code>cd path\/to\/workshop-lti-basic<\/code><\/p><\/blockquote>\n<p>In this directory, you should see several files and folders, including the <code>LICENSE<\/code> file, the <code>README.md<\/code> file, a <code>.git<\/code> folder, and a <code>demo<\/code> folder. Run the following commands:<\/p>\n<blockquote><p>\n<code>cd demo<br \/>\nvagrant up<br \/>\n<\/code><\/p><\/blockquote>\n<p>Now you wait. And wait some more. And continue waiting as your virtual environment downloads and fires up.<\/p>\n<blockquote><p><strong>ACK!<em>What&#8217;s all this waiting for? What the Heck is going on?<\/em><\/strong> If you are new to Vagrant and VirtualBox, the command <code>vagrant up<\/code> does the following things:<\/p>\n<ol>\n<li>Determines if you have the virtual machine that is specified by this tutorial; if not, Vagrant downloads the virtual machine for you and installs it.<\/li>\n<li>After the virtual machine is installed, Vagrant boots it up in the VirtualBox environment;<\/li>\n<li>During the bootup process, several scripts are run to see if your virtual machine has the appropriate software; if not, this software, including an Apache2 web server and PHP, are downloaded and installed in your virtual machine.<\/li>\n<\/ol>\n<p>All of this downloading and installing takes a great deal of time.<\/p><\/blockquote>\n<p>As your virtual environment downloads and installs, a tremendous number of log messages and warnings will fly by your screen. Monitor or ignore them as you see fit. Be patient, and the process will eventually return you to the command line. Maybe it&#8217;s time to get another cup of coffee or refreshing beverage. . .<\/p>\n<blockquote><p><strong>ACK! <em>I got a nasty error message, and my VM won&#8217;t install. What should I do?<\/em><\/strong> Good question. It really depends on what the error message is. Try Googling it using the keywords &#8220;Vagrant&#8221; and &#8220;VirtualBox&#8221; in the search parameters. That might give you a hint.<\/p><\/blockquote>\n<p>Once you are back on the command line, and no errors have occurred, this means that you have your virtual machine up and running, complete with a web server and PHP engine!<\/p>\n<h2>Test Your Virtual Environment<\/h2>\n<p>Open your favorite web browser and type the following into the address bar:<\/p>\n<blockquote><p><code>http:\/\/localhost:8080\/<\/code><\/p><\/blockquote>\n<p>You should see the following appear in your browser window:<\/p>\n<p><a href=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_index.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-754 size-large\" src=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_index-1024x465.png\" alt=\"tlt_lti_screenshot_index\" width=\"1024\" height=\"465\" srcset=\"https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_index-1024x465.png 1024w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_index-300x136.png 300w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_index.png 1193w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>Success! You are running your LTI web server. You can see a sample LTI-compliant LMS running here:<\/p>\n<blockquote><p><code>http:\/\/localhost:8080\/lms.php<\/code><\/p><\/blockquote>\n<p><a href=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_lms.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-756 size-full\" src=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_lms.png\" alt=\"tlt_lti_screenshot_lms\" width=\"994\" height=\"997\" srcset=\"https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_lms.png 994w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_lms-150x150.png 150w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_lms-300x300.png 300w\" sizes=\"auto, (max-width: 994px) 100vw, 994px\" \/><\/a><\/p>\n<p>Don&#8217;t fill out anything or press any buttons yet. It&#8217;s now time to review where you are and what you have.<\/p>\n<p><!--nextpage--><\/p>\n<h2>Exploring the Code<\/h2>\n<p>If you followed the instructions above, you should be located in your <code>demo<\/code> folder. List out its contents. At this point, you should see a file called <code>Vagrantfile<\/code> and a <code>puphpet<\/code> folder. You can ignore these for now&#8211;they are responsible for setting up and running your virtual environment. Instead, change into the <code>html<\/code> folder that is present.<\/p>\n<p>Within the <code>html<\/code> folder are several <code>.php<\/code> files, an <code>index.html<\/code> file, and several folders. You can ignore most of the folders&#8211;they contain images and css files&#8211;but note the <code>ims-blti<\/code> folder. Your Basic LTI libraries are stored in there.<\/p>\n<blockquote><p><strong>TIP!<\/strong> You might have noticed another <code>html<\/code> folder and a <code>default<\/code> folder among all those other files and folders. These folders were automatically created by your virtual machine and can be safely ignored.<\/p><\/blockquote>\n<p>The <code>.php<\/code> files include <code>lms.php<\/code> (the sample LMS you fired up earlier), <code>misc.php<\/code> (some miscellaneous code used by the sample LMS), and <code>tool-helloworld.php<\/code>. The latter file is the one you will be writing!<\/p>\n<h2>Let&#8217;s Write Some Code<\/h2>\n<p>Open up <code>tool-helloworld.php<\/code> in your favorite text editor. It should be beautifully blank, so type in the following:<\/p>\n<blockquote>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\nerror_reporting(E_ALL &amp; ~E_NOTICE);\r\nini_set(&quot;display_errors&quot;, 1);\r\n\r\n<\/pre>\n<\/blockquote>\n<p>The above is some bare bones PHP that sets some error reporting. Now add the following code:<\/p>\n<blockquote>\n<pre class=\"brush: php; first-line: 4; title: ; notranslate\" title=\"\">\r\nrequire_once 'ims-blti\/blti.php';\r\n$lti = new BLTI(&quot;secret&quot;, false, false);\r\n\r\n<\/pre>\n<\/blockquote>\n<p>The above code first loads the Basic LTI library, then instantiates a new LTI object. The parameters of the object indicate, respectively, to set its OAuth secret to &#8216;secret&#8217;, do not set a session, and do not redirect to another application. (If you want to know what all of this really means, it&#8217;s best to explore the PHP libraries and see what that code is up to; but it&#8217;s not important at the moment.)<\/p>\n<p>Now we will write some more standard PHP and HTML that will begin outputting the web page:<\/p>\n<blockquote>\n<pre class=\"brush: php; first-line: 8; title: ; notranslate\" title=\"\">\r\nsession_start();\r\nheader('Content-Type: text\/html; charset=utf-8');  \r\n?&gt;\r\n\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n  &lt;head&gt;\r\n    &lt;meta charset=&quot;UTF-8&quot; \/&gt;\r\n    &lt;title&gt;Building Tools With The Learning Tools Operability Specification&lt;\/title&gt;\r\n  &lt;\/head&gt;\r\n  \r\n  &lt;body&gt;\r\n<\/pre>\n<\/blockquote>\n<p>At this point, we want to check if the LTI launch is valid. If so, we print out all the POST parameters associated with this HTTP request:<\/p>\n<blockquote>\n<pre class=\"brush: php; first-line: 20; title: ; notranslate\" title=\"\">\r\n &lt;?php\r\n    if ($lti-&gt;valid) {\r\n  ?&gt;\r\n     &lt;h2&gt;Hello, World!&lt;\/h2&gt;\r\n     &lt;p&gt;We have implemented a basic LTI tool!&lt;\/p&gt;\r\n     &lt;h3&gt;A basic dump of POST parameters:&lt;\/h3&gt;\r\n     &lt;pre&gt;  \r\n  &lt;?php\r\n    foreach($_POST as $key =&gt; $value) {\r\n        print &quot;$key=$value\\n&quot;;\r\n    }\r\n  ?&gt;\r\n      &lt;\/pre&gt;\r\n<\/pre>\n<\/blockquote>\n<p>Finally, if the Basic LTI launch is not valid, we dump an error message. We then close out the HTML:<\/p>\n<blockquote>\n<pre class=\"brush: php; first-line: 33; title: ; notranslate\" title=\"\">\r\n &lt;?php\r\n    } else {\r\n  ?&gt;\r\n    &lt;h2&gt;This was not a valid LTI launch&lt;\/h2&gt;\r\n    &lt;p&gt;Error message: &lt;?= $lti-&gt;message ?&gt;&lt;\/p&gt;\r\n  &lt;?php\r\n    }\r\n  ?&gt;\r\n  &lt;\/body&gt;\r\n  \r\n&lt;\/html&gt;\r\n<\/pre>\n<\/blockquote>\n<p>Taken all together, our code should look like this:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\nerror_reporting(E_ALL &amp; ~E_NOTICE);\r\nini_set(&quot;display_errors&quot;, 1);\r\n \r\nrequire_once 'ims-blti\/blti.php';\r\n$lti = new BLTI(&quot;secret&quot;, false, false);\r\n\r\nsession_start();\r\nheader('Content-Type: text\/html; charset=utf-8'); \r\n?&gt;\r\n \r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n  &lt;head&gt;\r\n    &lt;meta charset=&quot;UTF-8&quot; \/&gt;\r\n    &lt;title&gt;Building Tools With The Learning Tools Operability Specification&lt;\/title&gt;\r\n  &lt;\/head&gt;\r\n   \r\n  &lt;body&gt;\r\n  &lt;?php\r\n   if ($lti-&gt;valid) {\r\n ?&gt;\r\n    &lt;h2&gt;Hello, World!&lt;\/h2&gt;\r\n    &lt;p&gt;We have implemented a basic LTI tool!&lt;\/p&gt;\r\n    &lt;h3&gt;A basic dump of POST parameters:&lt;\/h3&gt;\r\n    &lt;pre&gt; \r\n &lt;?php\r\n   foreach($_POST as $key =&gt; $value) {\r\n       print &quot;$key=$value\\n&quot;;\r\n   }\r\n ?&gt;\r\n     &lt;\/pre&gt;\r\n &lt;?php\r\n    } else {\r\n  ?&gt;\r\n    &lt;h2&gt;This was not a valid LTI launch&lt;\/h2&gt;\r\n    &lt;p&gt;Error message: &lt;?= $lti-&gt;message ?&gt;&lt;\/p&gt;\r\n  &lt;?php\r\n    }\r\n  ?&gt;\r\n  &lt;\/body&gt;\r\n   \r\n&lt;\/html&gt;\r\n<\/pre>\n<p><!--nextpage--><\/p>\n<h2>Let&#8217;s Run The Code<\/h2>\n<p>Open up your favorite browser, and type the following into the address bar:<\/p>\n<blockquote><p><code>http:\/\/localhost:8080\/tool-helloworld.php<\/code><\/p><\/blockquote>\n<p>You should see an error message, which makes sense, since you are not launching the tool with an LTI request (you are simply opening the tool in a web browser):<\/p>\n<p><a href=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_invalid_02.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-761\" src=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_invalid_02.png\" alt=\"tlt_lti_screenshot_invalid_02\" width=\"601\" height=\"386\" srcset=\"https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_invalid_02.png 601w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_invalid_02-300x192.png 300w\" sizes=\"auto, (max-width: 601px) 100vw, 601px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>To actually see the code in action, you need to &#8220;launch&#8221; it from an LTI-compliant LMS. Remember the sample LMS that you opened way, way back? Now you get a chance to actually use it. Open the following URL in your browser:<\/p>\n<blockquote><p><code>http:\/\/localhost:8080\/lms.php<\/code><\/p><\/blockquote>\n<p>Replace the field, &#8220;Launch URL&#8221;, with the URL to your tool:<\/p>\n<blockquote><p><code>http:\/\/localhost:8080\/tool-helloworld.php<\/code><\/p><\/blockquote>\n<p>Click the &#8220;Recompute Launch Data&#8221; button. Then press the &#8220;Press to Launch&#8221; button at the end of the form. In the iFrame below the sample LMS, you should see your tool in action:<\/p>\n<p><a href=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_success.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-757\" src=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_success.png\" alt=\"tlt_lti_screenshot_success\" width=\"994\" height=\"997\" srcset=\"https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_success.png 994w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_success-150x150.png 150w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2014\/07\/tlt_lti_screenshot_success-300x300.png 300w\" sizes=\"auto, (max-width: 994px) 100vw, 994px\" \/><\/a><\/p>\n<h2>You&#8217;re Done!<\/h2>\n<p>That&#8217;s it! Congratulations! You have successfully installed a development environment, web server, Basic LTI library, and sample LMS. You have also written your very own LTI tool, and launched it from a sample LMS. You should now be able to launch this tool from a commercial LMS, such as Canvas or Blackboard.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This tutorial will get you up and running with a development environment, complete with a virtual machine running an Apache 2 server with PHP, a basic LTI library written in PHP, and a simple basic LTI-compliant LMS. By the end of the tutorial, you will have written a simple &#8220;Hello, World!&#8221; LTI tool, and [&hellip;]<\/p>\n","protected":false},"author":4634,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[111265],"tags":[],"class_list":["post-706","post","type-post","status-publish","format-standard","hentry","category-lti"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/706","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/users\/4634"}],"replies":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/comments?post=706"}],"version-history":[{"count":67,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/706\/revisions"}],"predecessor-version":[{"id":779,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/706\/revisions\/779"}],"wp:attachment":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/media?parent=706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/categories?post=706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/tags?post=706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}