Skip Navigation

The Admin Page Class

The admin page is the monster class that controls every page of the reason admin site. If you look at the page “admin/index.php”, there isn’t really much there. It pretty much just instantiates a new admin page, then loads parameters and runs it. The guts of the page are found in the AdminPage class found in REASON_INC/classes/admin/admin_page.php.

For the sake of brevity, I won’t go into some of the more trivial functions of the page such as banner() or title(), which are pretty obvious when you look at them. Rather, I will try and give an accurate description of how the page works. The whole admin scheme works on a rather lazy concept. For example, in the init() function of the AdminPage, the class instantiates some variables and then calls the init() function of its module. The module will then instantiate some of its own variables and then might call the init() function of another class (i.e. a Disco or Viewer class). In this way, the admin page is able to take care of all of its things and not worry about what the modules are doing. The run function works in a similar fashion.

Class Variables

There are a few class variables that are integrated into the AdminPage in order to make changes for these things easier.

$title – this is the title of the page, and will show up in multiple places on the page.

$show – this variable defines what sections of the admin page will get shown. It is initialized in the constructor function and is often altered by modules.

$breadcrumbs – used for breadcrumbs. Not really in use anymore since we got rid of them, but left in just in case we ever decide to go back to them.

$user_id, $site_id, etc. – these are the most important variables of the page, so they’re stored in their own variables, rather than having to access them through the request array the entire time.

$module – this variable contains the actual module object.

$style_sheet – this variable defines style sheets for given modules. If a new module is created and you want specialized css, just add an element of the form {module name} => {css link}.

$default_args – this variable is used in the make_link() function. Whenever the function is called to make a link, these variables are always included in the url string, even if they have no value.

Flow of the class

The first thing the class does even before the run function is to call the load_params() function, which takes a user id and the request variables as arguments. The majority of this function is spent setting up the class variables which are defined in the $params variable. After this, the function select_user() is called. This function was one of the last additions made to reason3 before it went live. The purpose was to let the admin users log in as other users so that they can test for problems as that user. The implementation of this is tricky since we need to make sure that the actual user is an admin so that any user cannot simply become a different user and destroy the system by simply typing in a user_id into the url string. Thus we check the user_id that is currently stored in the class variable $user_id to see if its an admin. If it is, then the user id is successfully changed, otherwise, we simply skip over this part and ignore the user_id from the url string. At the end of this function the verify_user() function is called, which simply checks to see if the user has access to the current site before displaying any information about the site.

After the load_params() function, the run() function is called. The run function itself is pretty simple. It calls init() and head(). Then, if show[ ‘leftbar’ ] and/or show[ ‘main’ ] are true, it shows those sections respectively. Finally the foot() function is called. Just as a side note here, there is no good reason that show[ ‘main’ ] should ever be false. If it is, then the module itself never gets run, so all we see is navigation. Still, the logic is there in case a good reason ever does come up.

The init() function pretty much has three purposes here. First, it figures out what the current module is supposed to be. If it is explicitly told, it tries to grab that one. If it isn’t told, it picks one based on the class variables that are set. Second, it instantiates the new module, passing itself as a parameter (I know, it’s weird to be passing itself as a parameter, but it’s the only way to make sure that the modules have access to all the variables as well as some functions like make_link()). Third, it runs the init() function of the module.

The head() function is called next, which is pretty simple. Most of it is just basic html, with the class variables plopped in as appropriate. There are also references to the functions banner() and sitebar(), which are fairly simple functions as well. There are only a few things worth saying about those two functions. In banner(), there is a reference to a function show_user(). If the user is an admin, a drop down menu is displayed with a list of all users in the system. If not, something comes up that just simply says “You are {name}”. It is important that this logic is based on the original user and not the user_id, otherwise an admin who has chosen to be someone else will be stuck as that person unless the change something in the url string. In the sitebar() function there is some extra logic as well. Usually there is a drop down menu there with a list of all the sites. However, if the user is editing an entity (the $id variable is set), we don’t want them jumping out of the site to another site, so we change it to plain text. Also, we recently added some extra text there telling the user the name of the type and name of the entity that is being edited.

The leftbar function is really a beast. In order to simplify things somewhat, we split it into two parts. If an id is present, we call leftbar_item(), otherwise, we call leftbar_normal().

We’ll start with leftbar_normal() since it is a bit simpler. There are 5 functions (sites(), types(), sharing(), leftbar_other(), and admin_tools()) which are called here, based on logic. The sites() function is pretty simple. It just lists out all the sites. Also, if site_bar() has already been called, it sets show[ ‘sites’ ] to false, so it won’t be shown. The types() function is pretty similar to the sites() function, except for a couple things. For one, it shows the list of types that a site can access, there needs to be a site_id to show this, and it searches through the session variables to try and find the appropriate links. The sharing() function is about the same as types(). The only difference here is the query has to be more complicated to figure out what to list. You need the current site to have access to the type, as well as making sure that some other site shares the type. This logic can be found in get_sharable_relationships(). The leftbar_other() function is also similar to the above functions, selecting all admin_links that are associated with the current site. Finally we call admin_tools(). If the user is an admin user, we list out a few extra links, which are defined in the function.

The other case is leftbar_item(). This case is much more complicated since there are many more variables that we have to worry about. Originally, this stuff was going to fall on the right side of the page, but it was decided that we should instead replace the standard navigation with the item’s navigation. This way, users will be forced to finish an item before moving on to something else, rather than clicking on a different site or type while an item has not been finished.

We start off with two different cases. First, we can be dealing with an entity that the current site owns, in which case the show_owns_links() function is called, otherwise if we’re dealing with a borrowed item, the show_borrows_links() function is called.

The show_borrows_links() function is fairly simple as well. Since we are only dealing with a borrowed item, we just need to create a few simple links. The first is a preview link. This can be shown for all entities, since you cannot change anything about the entity from the preview page. Next, if the entity is sharable (which it probably should be since we in the show_borrows_links() function) we make a link to borrow or unborrow this entity, depending on whether or not its already being borrowed. The next link is a return to either the sharing page or the associate page. We can tell if we came from an associate page because we’ll be in the second level, otherwise we came from the sharing page. After all these links are found, we just print them all out and are done.

Back to the show_owns_links() function. We have two cases again here. We can be on the first level, or we can be on the second level. We call either show_owns_links_no_second_level() or show_owns_links_second_level() respectively.

The show_owns_links_no_second_level() function is actually pretty simple. We get the links using the get_main_links() function and then print them all out. The show_owns_links_second_level() is pretty simple as well. We get all the links using get_second_level_links() and get_main_links(). Then we loop through the outside links printing them all out as we go. When we get to the assoc link which is the one we can from, we call show_owns_links_no_second_level().

So those two functions are pretty simple. The guts of what they do is found in the get_main_links() function. The first two links are Preview and Edit, which are always present. Next, if the function is passed a parameter (The get_second_level_links() function does this), it uses that parameter as the relationship array, otherwise, the get_rels() function is used. Next we loop through all the relationships, setting session variables if necessary, and using those session variable as links. After that, we add a finish button, and if the entity is a new entity, we add a Cancel button, which basically does the same thing as a delete button.

The second_level_links() function pretty much just calls get_rels() with the parameter second, and then calls get_main_links() function, passing the second level rels as the parameter. I’m not exactly sure why I chose to do this in such an obscure fashion. I apologize.

Going all the way back to leftbar_item() again. If you look at the code, in the same “if” statement that contains show_owns_links(), there is another function called show_other_links_item(). This function just makes a couple additional links. These are separated out from the main links because they’re not always links. First we have the delete part. The first if statement contains a function called is_deletable(). Right now, our definition of something being deletable is that if it’s on the right side of a required, one-to-many relationship, it is not deletable. If it’s deletable, then there is a link created to the Delete module. If it isn’t deletable, We have text that says “Deletion Not Available” and a link that says “Explain”. The Explain link only shows up when you’re not on the NoDelete page, and links to the NoDelete page. Second, we have the archiving options. If the item has archive items, it tells you how many previous versions are stored and creates a link to the archive page, otherwise, it just says “No Edits”.

That pretty much wraps up the leftbar. Not all the details are there, but hopefully its descriptive enough to figure out. The only thing we have left in the admin page are the main_area() and foot() functions. The main_area() function is really simple. It just shows the title if show[ ‘title’ ] is set to true and then runs the current module. The foot() function simply closes out the table.