Support for the PHP syntax in patterns! Patch. Also some UI doc, a fix for DB prefix, and the user permissions pattern

dman - May 5, 2009 - 11:42
Project:Patterns
Version:6.x-1.x-dev
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:needs review
Description

I'm currently trying to knit together the deployment features I want from a combination of install profiles, macro,
Install Profile API, CRUD, and a hobnailed collection of my own pseudo-CRUD macro helpers.

I like the re-use and share vision I see in patterns, but I need logic in my macros, so YAML and XML won't do that for me. If I can't dynamically retrieve system variables and do a few limited lookups like variable_get('image_gallery_nav_vocabulary', ''); then my 'patterns' will not be portable enough for what I need to do.

So I'm keep to keep using the PHP syntax. Down that path I see convergence with macro.module. (my home-brew solution includes form submission arrays as part of an install profile, and a macro-runner that does drupal_execute() on them. )

But I can't see the examples of PHP patterns that I can build and tune.
Looking at the code, I'm sure they are basic, but...

I see patterns_load_yaml() and patterns_load_xml(), So I guess I can emulate that, but will it work? No patterns_load_php() ?

Is there somewhere I should be looking?

#1

dman - May 5, 2009 - 12:43
Status:active» needs review

I'm guessing it should go something like this:

///////////////////////////////////////
// Create a dummy page
///////////////////////////////////////

$pattern = array(
'info' => array(
    'title'   => 'Set up template contact page',
    'description' => 'Set up template contact page',
    'author'  => 'dman',
    'author_email' => 'dan@coders.co.nz',
    'version'  => '0.1',
    'category' => 'Examples',
    'core'     => '6.x',

  ),
  'modules' => array(
    'node',
  ),
  'actions' => array(
    // Actions is an array of smaller acts
    array(
      'tag'     => 'node', // 'tag'?
      'type'    => 'page',
      'title'   => 'Contact Us',
      'body'    => 'Put your contact details here',
    ),
  ),
);

.. and a bit of psychic coding gave me:
<?php
/**
* Read and evaluate a php file to return a 'pattern'
*/
function patterns_load_php($path, $local = TRUE) {
  if (
$local && !file_exists($path)) {
    return
FALSE;
  }
 
$pattern = array();

  if (!
$php = file_get_contents($path)) {
   
trigger_error("Failed to read PHP pattern file $path", E_USER_WARNING);
    return
FALSE;
  }

  eval(
$php);
 
// That should have declared a 'pattern' into current scope.

 
if (!patterns_validate_pattern($pattern)) {
   
trigger_error("Failed to evaluate a useful pattern from the input file $path. Pattern did not validate. May have been invalid syntax. ", E_USER_WARNING);
    return
FALSE;
  }
  return
$pattern;
}
?>

Am I right?

AttachmentSize
patterns-support_php.patch 1.78 KB
005-contact_page_setup.pattern.php_.txt 673 bytes

#2

dman - July 24, 2009 - 06:53
Title:Documentation for the PHP syntax?» Support for the PHP syntax in patterns! Patch. Also some UI doc, a fix for DB prefix, and the user permissions pattern
Component:Documentation» Code
Category:support request» feature request

Sorry for putting three things in one patch, but I didn't get any response to the first one, so needed to keep things moving forward.

OK.

  1. Support for PHP patterns! Works well for me. You can convert from either scripts recorded by macro.module, or by inspection of $_POST pretty easy. I've attached a sample from my experimental suite of setup actions.
    This involved touching a few places to ensure that *.php files could be used the same as *.xml files. Does not yet save in php, but does read it.
  2. Also, some UI help to make patterns more intuative to first-timers. On the patterns screen, I've used hook_help to tell me the search paths eg:

    Patterns will be looked for in files under the following locations:
    * sites/prototype.kiwischools_2009.gadget/files/patterns
    * sites/prototype.kiwischools_2009.gadget/patterns
    * profiles/kiwischools/patterns
    * sites/all/patterns
    * sites/all/modules/kiwischools-admin/patterns/patterns

    (This involved a tiny refactoring of patterns_get_patterns() to abstract the search algorithm into a smaller function)

  3. Patterns was currently NOT DATABASE-PREFIX safe, in the place where it did db_query('SHOW TABLES LIKE "cache_%"'); and it threw errors when I tried on a prefixed site that had a different set of tables than the 'default' site.
    A small fix for this is attached.
    <?php
    function patterns_execute_action($form_id, &$form_state, $params) {
     
    // Make sure we always have a clear cache for everything
      // Beware - this direct database access needs to be db-prefix-safe!
     
    global $db_prefix;
     
    $result = db_query('SHOW TABLES LIKE "{cache}_%"');

      while (
    $table = db_fetch_array($result)) {
       
    // Remove the db prefix if any. cache_clear_all() will put it back again.
       
    $table = substr(current($table), strlen($db_prefix));
       
    cache_clear_all(null, $table);
      }
    ...
    ?>
  4. I got PHP warnings from user_patterns()
    <?php
                $data
    [$data['rid']] = array_merge($perms, $data[$data['rid']]);
    ?>

    when 'rid' was not an array. The code indicates that 'rid' is never expected to be an array, so I cast it into one to suppress the error. You'd only see it if running PHP_STRICT warnings - which I do.

AttachmentSize
patterns-php_support_and_bits.20070724.patch 8.57 KB
011-editor_role_setup.pattern.php.txt 1.72 KB

#3

sarvab - July 24, 2009 - 07:30

Hi dman, sorry for not getting around to look at these much earlier. The patch looks great and my initial tests were fine so I just committed it. Will leave it open for review for a bit longer.

Thanks!

#4

dman - July 24, 2009 - 08:10

Cool, thanks.
I'm doing a bit of intensive cookie-cutter-site install-profile wizarding this week, so more tweaks may be forthcoming. I may even experiment with 'publishing' patterns...
The next one I need to do is one that auto-configures FCK Editor the way I want it ...
... after the one that creates a handful of boilerplate pages and content types...

Good fun, but slow going for me.

#5

sarvab - July 24, 2009 - 08:14

Sounds fun! Just why we have all these various solutions for doing just that. Hope things work out for you :)

#6

ChrisBryant - July 24, 2009 - 18:12

Nice work dman! It would be nice to also expose a permission for "Use PHP patterns" or something to that effect. I guess it's generally not that important since most of the time Patterns are run as user 1 or a fully privileged user anyways.

Also, it would be interesting to support PHP snippets that could be evaluated in XML or YAMP patterns. I'm not sure if that's a good idea technically but if possible and security considerations taken into place, it would be useful.

#7

dman - July 25, 2009 - 00:31

Well, there certainly is a potential security issue with PHP evaluation anywhere.
I once cracked a system that had inadvertently left cck import open :-)

OTOH, I am really not in favor of Yet Another configuration language, when clearly a PHP array is as obvious, flexible, dynamic, portable and powerful enough for any set of configs I need.

So yeah, the thing to do is tie the ability to use eval() to the php filter permission, or something like that.
I guess you can embed ?php? tags directly into XML ... and have the processor eval them on the fly? ... Nah, I want to be able to use the full power, maybe a foreach. "A pattern that creates a node for each registered user". I'm treating patterns as bundled PHP 'snippets' that perform admin actions I guess...

#8

sarvab - July 28, 2009 - 09:15

One important aspect of using ?php? tags directly in XML/YAML ect is that you can have context available to you at that time. For instance if you're creating nodes, you won't know the node ids of what you're trying to create if you have a straight php pattern. If there was a tag, you could put that in the right points in the pattern where you'll have context and access to all info from all actions completed up until that point.

One thing on the list of todos. Should really be an easy one too :)

#9

brianjhoffman - October 20, 2009 - 18:40

I have encountered a problem with part 3 of the above patch when using patterns on a multi-site installation.

On our site, $db_prefix is an array, and so I need to hack line 1720 of patterns.module:

WAS:
$table = substr(current($table), strlen($db_prefix));
NOW:
$table = substr(current($table), strlen($db_prefix['default']));

I'm sure there would be a nice way to do this to support various configurations.

Here is our db_prefix array in the site settings file for reference:

$db_prefix = array(
'default' => 'mc_',
'users' => 'shared_',
'sessions' => 'shared_',
'role' => 'shared_',
'authmap' => 'shared_',
'sequences' => 'shared_',
'profile_fields' => 'shared_',
'profile_values' => 'shared_',
'blocks' => 'shared_',
'filters' => 'shared_',
'users_roles' => 'shared_',
);

#10

dman - October 20, 2009 - 23:51

Ah.
I've not worked with shared tables and prefix arrays yet. Must remember to consider those.
I don't know if there is a quick fix, could be tricky.

#11

brianjhoffman - October 21, 2009 - 20:12

Well, thanks for reviewing. I'm glad it's on your radar at least. Let me know if you want any assistance when the time comes to revisit it.

Brian

 
 

Drupal is a registered trademark of Dries Buytaert.