Posts tagged eecms

EE, MSM and Datagrab

Over the weekend, twitter user @audiopleb ran into issues importing data to Expression Engine MSM sites via Datagrab. This is something we have a huge amount of experience in back at the office. That is to say, migrating data between sites (Non-EE -> EE and EE -> EE) is something of a specialty of mine.

One of the issues I’ve noticed with Datagrab (indeed, other add-ons as well) is how they deal with MSM sites. Datagrab for example uses this parameter to do a lot of it’s internal MSM handling:

    $this->EE->config->item('site_id')

This seems to mean that if you are accessing the control panel via http://site_1/system, then site_id will always be 1. For some reason, possible depending not the version of EE/MSM/Datagrab, changing the site via the CP drop down does NOT update the site_id value (at least according to Datagrab). My workaround has been to access the CP via the secondary sites URL. For example, use http://site_2/system. This seems to get things where they want to be.

All you really need to do to make this happen is put a copy of /admin.php somewhere under site_2. I use this structure for my sites:

  • /ee_system/ - site_1 system
  • /html/ - site_1 web root
    • /html/sites/
      • /html/sites/site_2/
        • /html/sites/site_2/dashboard/index.php - site_2 version of admin.php

Edit the site_2 version of admin.php to point all the way back to your main EE System folder via the $system_path variable. Mine looks like this:

    $system_path = '../../../../ee_system';

This keeps things nice and relative for easy migrations. I’m sure there is a solid explanation for this occasional behavior, but every the I’ve hit it I have been deep into a time-sensitive work. Some day I would love to understand why this happens, and why my work-around (aka, dirty hack) seems to work so consistently.


• • •

MSM and the mysterious Logout issue

On the #EECMS zone of the Twitterz today, Matt Everson of Astuteo was having a problem with MSM and mysterious logout issues. His reasoning was that this cropped up with EE 2.3.x, but I have seen it as far back as 2.1.0. The solution is simple enough. Via the control panel visit Admin -> Security and Privacy -> Cookie Settings. You need to set the Cookie Domain as appropriate. For me I wildcard it out a bit, like this:

.mydomain.com

Repeat this once for each MSM site under the install. Problem solved? Good. Now, why is this the solution? When a cookie is issued to the client browser, it is tied to that Cookie Domain value. That is really the root of identity for each cookie. After the domain, you then have the Cookie Path and the Cookie Name.

The next bit of knowledge that helps build on the understanding here is that EE manages your login based on a Session ID number. That Session ID number is stored in a cookie named exp_sessionid. This is a simplified way to think of the cookie that results from a control panel login:

[cookie domain].[cookie path].[cookie name] = [cookie value]

If we login to Site_1 of an MSM install, we might get something like this:

[.mydomain.com].[/].[exp_sessionid] = 123456789

It is important to note that EE will use the domain for the FIRST of the MSM sites if no configured value is set for Cookie Domain across all sites. That means if you then logged in to Site_2, you get a new cookie with the new Session ID. That cookie would have the EXACT SAME identity tree, and would then overwrite the cookie set by Site_1. Now there is no longer a way for Site_1 and your browser to track the session you are with on the server and you are logged out.

Setting that unique Cookie Domain will allow you to have multiple cookies with differing domains but the same name (exp_sessionid). Since nothing gets overwritten once this is setup you are able to keep your login working.


• • •

Looping through the Matrix

Anyone out there use ExpressionEngine? Okay, settle down. Anyone use Pixel & Tonic’s Matrix field type? Likely that the same number of people just raised their hands. Now, how many of you custom-dashboard-matrix-using-expression-engine developers also use jQuery?

That should have been everyone as well.

One of the challenges we run into at the office is looking at the values of a Matrix field to compute, compare or validate on. For example, one might have a matrix with this format column format:

Item Description | Price

Very simple data entry example. Item and Price. At any time you might want to get an updated Total Price number to the end user. Looping over the entire Matrix is the pain point we found a nice solution to. Take this jQuery snippet as our reference bit:

    $('div#field_id_106 textarea.matrix-textarea[name^="field_id_106[row_"]').filter('[name*="[col_id_38]"]').each(function() {
        // Do some cool stuff here with the data. Access the local cell with
        // $(this).val()
    });

The jQuery warriors among us are saying “Well, yeah, duh!”. The rest of us are looking at Sanskrit. The magic are the name^= and the name*= selectors. First, we select down to the Matrix we care about. In my example, it is contained inside of div#field_id_106. Next I select down to the textarea stuff, since the fields I care about here happen to be textarea fields. Now for some magic.

[name^="field_id_106[row_"]

The operator ^ after the name attribute tells us that the selector we are isolating down to must START with the string field_id_106[row_ in order to be included. Stopping at the row_ is a trick that really made this useful for us. Both NEW matrix rows as well as UPDATE matrix rows (existing values in place) will contain this. You won’t need to know anything about the matrix you are looking at in order for this selector to work.

Last I add the .filter() to our object. This filters further to look at a specific column in the Matrix. I take advantage of the * operator here (can contain ANYWHERE), and I look for the [col_id_38] string in the name attribute. We wrap it up with the .each() call, and now we have a nicely set loop. Within the loop we can get to our cell values with:

$(this).val()

There are going to be a lot of ways to slice this turkey, and I would love to hear from anyone else that has faced this issue. Are there even cleaner ways to get into the Matrix cells via jQuery?


• • •