George Mason University Antonin Scalia Law School

CASifying MODX

Implemented phpCAS to MODX manager for an extra layer of security.

These codes are placed at the top of manager/index.php

This log out link goes in manager/frames/menu.php
<a href="?logout=" target="_top" style="color:#fc0">Sign off CAS</a>

The default setting for these files are chmod 444. Change to chmod 644 when making the edits. Once done, change back to chmod 444.

Remember: When upgrading MODX, make sure to put these codes back in.

LRWA Online Document Submission

URL: http://www.law.gmu.edu/academics/lrwa

  1. In MODX tree menu, browse to: Academics > LRWA Online Document Submission
  2. Duplicate an existing form. Example: 2012 Fall Law 097 LRWA II and rename to the new semester.
  3. Edit instructors’ email
  4. update this chunk name: &tpl=`eForm.lrwa2012fall097.form` (Also pay attention to these chunks: &report=`eForm.lrwa.email` &thankyou=`eForm.lrwa.thankyou`
  5. Navigate to “Chunks” under “Manage Elements” and duplicate an existing chunk. Example: eForm.lrwa2012fall097.form
  6. Update faculty names in the drop down box.

Validation messages lives in english.inc.php. Update validation message via command lines:
cd /home/lawdevlaw/public_html/assets/snippets/eform/lang/
chmod 755 english.inc.php
vi english.inc.php
chmod 444 english.inc.php (read only)

Course Schedule Import Script

Make sure the csv file is properly formatted. Use the csv files from the previous semesters as example, strictly apply the same format for name, time, date, etc.

1. ssh into the masonlaw main server

2. su into root

3. cd /home/lawdevlaw/public_html/assets/snippets/

4. change permissions: chmod -R 755 csv_new/

5. cd csv_new

6. upload the csv file (make sure the uploaded csv file is readable).
cd /home/lawdevlaw/public_html/assets/snippets/csv_new
touch zz-spring-2012.csv (new csv file)
vi zz-spring-2012.csv (paste CSV file from TextEdit)
:wq (save file)

7. Copy a convert_schedule_201?_????.php to a file name appropriate for the school year and semester, e.g., convert_schedule_2012_spring.php (Make sure to do this via command line and not upload through MODX).

8. Edit convert_schedule_2012_spring.php. Make sure all the parameters shown below are correct:

$SITE = 'LIVE'; // 'LIVE' OR 'DEV'

$csv_file = ‘./zz.csv’; // CSV files
$xml_file = ‘./schedule2.xml’; // XML definition files
$data_year = 2012;
$data_semester = 1; // 1-spring 2-summer 3-fall
$data_semester_name = ‘Spring’;
$data_instructor_parent = 1812; //this value stays the same
if($SITE==’LIVE’) {
$data_course_parent = 7714; //change this value according to the parent container

Note 7714 is the object id in modx, for which all the course instances will be created. Check the other convert files for examples.

9. From your browser, visit the php file you just edited, e.g.: http://law.gmu.edu/assets/snippets/csv_new/convert_schedule_2012_spring.php

10. Note all red lines are errors or warnings. Make sure they are properly dealt with. If the script says it will create a new instructor for you, make sure the newly created instructor does not already exist in the system. Even small typo can trigger the script into thinking we need to add another instructor.

11. Submit the form, until the page shows no error and there is nothing more to do.

12. IMPORTANT! Now you must change back the script permission:
chmod -R 000 csv_new/


Update course descriptions to point to the new semester

Edit “2012_course_info.html” template in (elements/manage files/templates) change the header and the &parent code.

Update course container

1. Inside MODX: Academics -> Course Schedules and Assignments -> Pick the newest course schedules (example: 2013 Course Schedules) –> Pick the newest semester (example: 2013 Summer)

2. Edit the parent. Add URL alias.

3. Edit resource content: [!course_instances? &semester=`2` &year=`2013` &updated_threshold=`0`!] (1-spring 2-summer 3-fall)

4. In setting tab, check “published” and “container”

5. Hit “save.”

Notes On MODX For Main Site

Notes from Paul Bohman

  • I added some system event names (in the database table modx_system_eventnames) to make up for the fact that they were not part of the base code. I needed these events to make the shadowmaker plugin work
  • I altered the default sort order for the webpage tree in manager/frames/nodes.php. I set it up so that it uses library-style alphabetization by default (so it ignores “The “, “A “, “An “ etc at the beginning of pagetitle names). This modification will need to be done every time you upgrade MODx, because it’s not part of the core code.
  • I had to modify document.parser.class.inc.php in a few places to make the shadowmaker plugin work correctly. This modification will need to be done every time you upgrade MODx, as long as the shadowmaker plugin is being used.

Templates

Templates cannot have raw PHP code, but they can call snippets, chunks, and template variables.

The main files for the templates of the current site are found in assets/templates. The files for the current site have a “2010” prefix. I’m using the “inc” snippet to call them in.  In that same folder are files for more involved templates, such as course_info, course_instance_info, and faculty_profile. If you update any of these files, you’ll need to clear the cache to see a change. You can clear the cache by using the Site > Clear Cache option or by saving any page (or snippet or chunk) in MODx.

Template Variables

Template variables are assigned to templates. If a template variable is not assigned to a given template, you can’t call that template variable. To call a template variable in a template, use the following syntax:

[*templateVariableName*]

To use PHx with a template variable, refer to the documentation at http://wiki.modxcms.com/index.php/PHx

Chunks

Snippets are bits of HTML code. Raw PHP code is not allowed, but chunks can call snippets, template variables, and other chunks.

To call a chunk in MODx, use the following syntax:
{{chunkName}}

MODx Plugins

Plugins can potentially run on all the pages, based on a chosen trigger.

New Document Default Values

This plugin sets a few default values for new documents, which can be modified and customized.  I set the default value of “menuindex” to 990, which was an arbitrary high number, allowing for up to 989 other documents to be listed before the default documents in menus, using the “Navigation” script (which is a modified version of the Wayfinder script that comes with MODx).

TO DO: It would be good to modify the script so that it always sets the template to “blank” when creating a new weblink. Right now it inherits the parent template, which is good for documents, but which breaks weblinks.

Page TOC Generator

This plugin creates a page-specific table of contents based on the headings on that page. It’s somewhat configurable. It’s usually best to put the starting code in the pre-content field and the ending code in the post-content field because otherwise the code can be accidentally deleted or altered in the TinyMCE WYSIWYG interface, which will ruin the output.

Shadowmaker (“NEW ShadowMaker LEAVE ON ALWAYS”)

This is a plugin that I created to make querying template-based data easier and more straightforward. Unfortunately it also complicates MODx upgrades, because I had to modify the source code, and it does slow down the save/edit/delete/publish process slightly, though its effect there is minimal. The one that really slows down that process is the old ShadowMaker plugin, which really needs to be abandoned, but can’t be until some scripts are updated.

The basic idea behind this plugin is to take all of the template variables, which are in the modx_site_tmplvar_contentvalues table and put them in a single table for each template, so that each template essentially acts as it’s own database table. That way, you can do queries like “select * from [faculty table] where lname = “smith”. That kind of query isn’t possible to do directly in the native MODx table structure. It reduces the need for joins, and makes joining more straightforward. At least that was the goal.

The way that ShadowMaker works is that it intercepts all save/edit/delete/undelete/publish/unpublish actions, using the System Event Names in the modx_system_eventnames table, and updates the derivative tables accordingly. These tables use “sm_” as the prefix, followed by the id number (sm_4, sm_5, sm_7, etc.).

In addition, I created some shadowmaker join tables which are also automatically updated in the sm_relationships table.

Basically, it’s PHP-based database trigger system. The code isn’t perfect. It can be refined quite a bit, and I hope you do that… or that you find an alternative that you think is better, but it seems to be working. It does it’s job.

Several scripts query the derivative tables directly, rather than the MODx native tables, so if you do update or eliminate the ShadowMaker plugin, you’ll have to also update those scripts.

ShadowMaker (the old one, entitled “ShadowMaker TURN ON FOR COURSES ONLY”).

This was the first attempt at creating a trigger-like system. It’s horribly inefficient, it slows down the save/edit process in the MODx manager considerabley, and really needs to be eliminated, but it can’t be eliminated yet because the course schedule script uses the tables that this plugin creates (shadow_course_instances), and so do the working paper scripts  (shadow_working_papers). You’ll have to first rewrite those scripts before you can get rid of this plugin.

If I were going to do this, I would probably rewrite those scripts to use the ShadowMaker tables created by the new ShadowMaker script. It would require joining them in several ways, especially for the course schedule script, but I think this would be more efficient than trying to query the native MODx tables. I might be wrong on that point. You’ll have to take a closer look at the database setup and decide for yourself what kind of query would be the most efficient.

Replacements

This plugin runs on the rendered content right before it is served out to the browser. It does miscellaneous things like rewrite same-page links so that they work properly (when using MODx it’s best to use the <base> tag, which then messes up same-page links, and this plugin fixes that problem), and also attempts to put all list items on the same line to avoid CSS display problems in IE6 when there are spaces or line breaks between list items when the CSS is set to display:block for these items. This part of the script doesn’t work perfectly, but it mostly works. You can add other replacements to this script as necessary to correct issues as you discover them. It does add an extra layer to the PHP code, which probably slows it down somewhat, but I don’t think it makes a huge difference. I think other factors slow down page rendering more than this plugin.

PHx

I didn’t write this one, but it’s quite useful. It extends the functionality of MODx placeholders, allowing for various kinds of logic. It’s not as powerful as something like Smarty templates, but it’s based on the same type of idea. I used the phx plugin extensively on the main law school web site, so you’ll have to learn how it works. See http://wiki.modxcms.com/index.php/PHx.  I’ll admit that the if/then logic of phx can get really messy. Some of my templates are hard to read because phx is not as clean as PHP code, but it does work. It probably slows the rendering down somewhat too. I didn’t use it on the last iteration of the site. I used plain PHP instead, and to be honest, I didn’t see much of a difference in rendering time. I think the biggest factor in rendering time is the site cache system, in particular the siteCache.idx.php file, which is 1.66MB last time I checked. That’s a problem with the way MODx is written, and you really can’t do anything about that unless you invent your own caching system.

Snippets

Snippets are bits of PHP code. You can’t insert raw PHP code in a template or document in MODx, so you have to do this through snippets.

To call a snippet in MODx, use a syntax like this:
[[snippetName? &parameter1=`foo` &parameter2=`bar`]]

To call a snippet that should NOT be cached, used this syntax:
[!snippetName? &parameter1=`foo` &parameter2=`bar`!]

alphaSort

This script allows you to sort a list of items using library alphabetization style. It can be used within other scripts. I employed the same sorting technique in my modification to the MODx source code.

antiSpam

This snippet is used in conjunction with the eForm snippet. It has some basic features intended to block a few common spam techniques with online forms. This snippet could be greatly expanded upon and improved, but we haven’t had too much trouble with form spam, so I haven’t touched it in quite a while.

breadcrumbs

This is a reasonably flexible script that creates a breadcrumb trail. I use it on the current site.

classInterface

The purpose of this script is to allow access to PHP classes from within MODx without having to create a new snippet for each one. I don’t think this is currently being used on the site, but it could potentially be used to call PEAR classes, or other custom classes. The benefit of using this script, besides not having to create a new snippet every time, is that it keeps the site cache file smaller by eliminating all the extra snippets that would be in there otherwise. I haven’t taken advantage of this script recently, and it probably needs to be looked at again to make it more robust, but the idea is still a good one.

Ditto

Ditto is the fastest, easiest way to pull data from MODx. I use it extensively on the site to pull in information from various sources. Spend some time reading over the information at http://ditto.modxcms.com/, especially http://ditto.modxcms.com/files/snippet-ditto-php.html and http://ditto.modxcms.com/tutorials/basic_filtering.html

DittoPlus

This is a script that I wrote to extend Ditto. I don’t remember at the moment where this is being used, but I’m pretty sure it’s being used somewhere within the code, possibly in the course schedule script.

eForm

This script allows you to create a submission form in a web page. It’s quite configurable. You create a chunk for the form, a chunk for the email that it sends, and a chunk for the “thank you” message that displays on the screen after the user submits the form. It has some validation functionality built into it, though it’s not the most flexible script in how it handles validation errors. The script is used in places like http://www.law.gmu.edu/contact and on the forms available at http://www.law.gmu.edu/academics/lrwa/

NOTE: You will have to update those forms every semester. You may come up with a better way of handling those forms, because I admit it’s a little cumbersome to match up the email addresses with the names of the form fields, but it does work if you’re careful.

NOTE 2: If you ever need to allow for multiple document submissions, there should be an example in the list of eForm forms still from a previous semester that you can look at.

ErroneousRex

I wrote this script to help with 404 errors. It is activated when a user arrives at the 404 page. The script first replaces certain strings in the url and tries to redirect based on those replacements. If those don’t work, it tries some regex replacements. If those don’t work, it goes to the “redirect” table in the database and looks for replacements there. The redirect table has two kinds of replacements:

  1. Old url -> new url
  2. Old url -> MODx id

When entering data into this table, it is definitely much better to use the MODx id method than the new url method, because that will help ensure that the redirect will still work even if the page is moved again later. But in some cases it makes sense to use the new url, so that method is available too.

IMPORTANT NOTE: If the ErroneousRex script is not successful in redirecting to an active page, it creates an entry in the “log_errors” table. You should check this table frequently to see if there are bad links on the site that need to be fixed.

TO DO: It would be great to update the ErroneousRex script so that it sends an email when certain kinds of errors are logged, such as bad links that aren’t flagged as malicious. We get quite a few hacking attempts on the site that are logged in the log_errors table, but which I flag with a “1” in the malicious field. Usually those have no effect, but I do look at them from time to time to see if there is a pattern that I should be aware of.

TO DO: It would be great to create an admin front end for this script so that Deborah and other people could add or edit redirects without having to log in to the phpMyAdmin database interface.

The replacements and regex replacements are in the snippet itself, and have to be modified there, at least as the snippet is currently written.

eval_get_subject_category_id, etc.

The snippets that start with “eval_” are generally scripts that are used to generate drop down lists or other similar features related to template variables within the manager interface. This particular script, for example, gets the ids of the subject categories, then converts those ids into human readable words, based on the pagetitles of the documents. In the database, the id is stored, making it easier to keep track of things if the pagetitle changes in the future. See the course_subject_category template variable to understand how the snippet is used.

FlexibleSiteIndex

I wrote this snippet so that we could create a site index by entering in terms on the pages themselves. It takes into account page deletions, unpublished pages, etc. It’s pretty robust, and can create a single page, as the law school site does currently, or it can create separate pages for each letter of the alphabet.  See http://www.law.gmu.edu/assets/snippets/flexiblesiteindex/docs/instructions for instructions. Also, the code is available at http://modxcms.com/extras/package/152 I may never update it again, but if I do, it will be available there.

ifMu

This script checks to see if the current user is a member of a given group. It can be used to grant or exclude access behind password protected areas. It’s not currently being used on the site.

inc

This is a simple script (in fact, I suppose it could/should be simplified even more) that simply includes a file. It acts like the “include” function in PHP, but since MODx doesn’t allow raw PHP code in documents (it only allows it in snippets), the only way to include something in MODx is to create a chunk. That’s fine, except that every time you create a chunk it increases the size of the main site cache file, which slows down the site. So I created the “inc” snippet to add “include” functionality without bloating the site cache. I’m not using this script a whole lot on the site right now, but it would probably be a good idea to take some of the chunks that are currently there and move them to files, then use the “inc” snippet to call them. That will streamline the main site cache file a bit.

LastUpdated

Displays the date of when a page was last updated. The date format is configurable. See the snippet for details.

NOTE: It cannot determine when data within the page from snippets was last updated (e.g. if you use Ditto to call other pages, some of those pages may have been updated more recently than the page you’re currently on). It only checks the date that the page itself was last updated.

Navigation

This is a modified version of the Wayfinder script that comes with MODx. I had to put in some customizations for our site’s needs, but it’s essentially the same thing. NOTE: you can’t use both Navigation and Wayfinder on the same page. You can only use one or the other, or else it will cause a PHP error.

phx:convert_course_attributes etc.

All of the snippets that start with “phx:” are written as extensions to the PHx plugin. They allow for data manipulation within the template variables. I’ve used these snippets for relatively simple data conversions for the most part, but I imagine it could be written to do some more powerful things if necessary, though if it gets too complex, it is probably better to write a separate PHP snippet instead.

randomizer

This snippet isn’t being used at all on the current site, but it could be used in place of the static banner images that we currently have on each page. In fact, that was my original intention—to have these be randomly chosen images from a list—but I ran out of time and didn’t get that done.

random_banners (random content)

Even though the script is called “random_banners” it could really be renamed random_content. I used this script on the previous site, but it’s not currently being used, though it could be in the future. You supply it with a comma-delimited list of pagetitles or ids, the script picks one of them at random, and displays the “content” field from that page. The advantage of this script is that it allows you to include any content that you like, so you can include not only the image, but also its alt text, a link around it… or even paragraphs and whatever else you want.

Script

I wrote this plugin so that I could include any PHP script I wanted to without having to create a new snippet every time. With this snippet, all you do is say which script you want to run, include whatever parameters you need in the call to the script, and you’re good to go. I also included a few hacks so that the parameters could include a standard SQL statement. MODx does not allow the equals sign (“=”) or the greater than (>) or less than (<) signs in snippet calls, so I wrote some strings that will be replaced during script execution. So you would write something like this: “select * from sm_4 where id ((EQUALS)) 5”. The “((EQUALS)” text will be replaced with an “=” sign.