Skip to main content


7 min read

I have recently reevaluated my goals related to the LMS.  The start of the semester was a stressful time and I realized I was trying to accomplish too much, too fast, in a high-stakes environment.

 A Little Background

The system I inherited dates back over 15 years.  It is written in php, and php has evolved a lot over the time the system has been in use.  The legay code uses no OOP, and no organizational framework, most of the work is done by several very large (1000s of lines) include files containing many, many functions, most without any kind of documentation.  Functions such as user authentication, page authorization, view logging, and page rendering are all done more-or-less inline via an included header file.  Globals are used extensively to provide services such as database connections and the current user to variouse functions.  Most -- but not all -- content files are flat php files in the webserver's public path. There are several discrete, semi-integrated subsystems that proide the current set of functionality:

  • A low level filesystem browse/edit system to author certain pages as raw HTML or markdown
  • A frame-based editing environment to author "learning pages" that make up the most of our content. Editing itself is still raw HTML and markdown with bunch of php functions for content that interacts with the data store, such as embedded assignments.
  • A quiz system that has it's own, separate raw authoring and rendering environment.  Embedding quizzes on learning pages is done through iframes. The quiz system can only handle numeric, multiple choice, and MATLAB code responses, hense the need for
  • A file upload system with a tightly coupled rubric authoring/grading system and
  • A survey form system for authoring, rendering and viewing results of form-based input
  • A PDF annotator and grading interface primarily used to grade scanned exams.

The quiz, file upload, and survey systems all use their own slightly different method for specifying due dates.  Most non-content authoring editing is done through direct database table edits via a very light-weight wrapper around table based CRUD operations.

The system is used to run separate class sites for each of our classes. As an added complication, many of the class sites use several local PHP files for certain features, such as certain student submitted forms and other pages making their own local database connections and queries.

First Attempts

My original goal was to replace the massive included header file and jumble of associated logic with a standard router-middleware-emitter pattern using the the Slim microframework. In theory this would move things like establishing database connections, user authentication, session managment, page view logging, etc. to more recognizable services and middleware, decoupling the page loading and rendering making it easier to provide a consistent API to all pages.  By pushing in this direction, I figured I would learn the different parts of the legacy codebase to gain a better understanding of how the pieces fit together, while defining more clear boundaries between them. The problem was that the existing codebase was in such a tangled form that trying to separate even a sliver out required multiple changes across multiple files and even then things seemignly unrelated would break. I had been reading some development blogs about refactoring legacy code bases and even their "you might have a code base that looks like this..." example of poorly organized structure still had more of a structure than what I was dealing with.

Over the summer, I spent a lot of time building up a middleware pipeline that would hopefully load and emitt legacy page content. I wanted the pipeline established so that any new features and functionaly could be written in a clean, organized fashion from the start. Ultimately though, there were too many edge cases to deal with trying to take content pages that had been written as stand-along PHP applications handling them with a consistent pipeline. I made enough progress to gain optimisim but as the summer came to an end it became clear that this was not something that would be ready for the Fall semester.  The last week before classes started, continuing into the first week, I shifted gears to just trying to integrate a somewhat parallel middleware structure for new features into the legacy code base so that I at least had one git repository to work with.  This eventually did come together, with the old legacy pages still being handled with the legacy code with new pages being handled by the new code, but not without some breakage due to missing or moved include files that I hadn't know about until various pages and subpages were accessed by colleagues trying to get class pages setup.  This is what lead to the stress, doign last-minute fixes to now-live code when frustrated colleagues would bring a broken page to my attention. I worried that all the time and effort I had put into the codebase over the summer was esentially out the window with not much to show for it and that all my colleagues saw were broken features that had been working before.  

Attainable Goals

On top of the general stress that came from feeling like I was failing the people that depended on me, the frustration also had the effect of taking something that I had enjoyed, the tinkering with and implementing data pipelines and modeling data transformations, and coupled that with negative emotions.  It started to feel not only like a job, but a job I hadn't really signed up for (because I hadn't) and was not fining at all fun. This as troublesome because since I've remembered I had always had an intrinsic interest with web development and data processing. It had been a passion that was now being choked to submission by external demands. It was keeping me up at night and I only was getting a few hours of sleep each night the first week of classes.  When the major broken pieces were finally functional again and I had a moment to breath I realized my approach had to change.  I realized a system-wide overhaul was never an atainable goal for a one person team over the course of a summer.  Instead, though it hurt my head to read through and patch up the tangled mass of spagetti code instead of re-write it, that was the more reasonable approach to maintaining the existing system while narrowing my focus for the new pipeline to specific features that would get rewritten piece by piece. This would allow me to have fun with the development again working on upcoming features that did not have any particular timeline for going live, while performing minor maintenance to the existing code base.

So that's where I'm at now.  As a unit we are set to have a discussion soon about the future of our LMS and whether it makese sense to move our course content over to Canvas, the University's choice of LMS.  Even if we do that, we know that the assessment system is one thing that we depend on, so I am looking into extracting it out as a LTI 1.3 tool that can be integrated into cavas.  This gives me a focused project to work on, that still has all the pieces of the full web application: a content managment system, data management, user submission handling, etc. but with more well defined boundaries.  I have been sleeping much better since this shift in expectations.