]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Pulled ECML regex into a constant.
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 8 Jul 2010 18:51:34 +0000 (18:51 +0000)
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>
Thu, 8 Jul 2010 18:51:34 +0000 (18:51 +0000)
Added ecml_get_keywords(), ecml_parse_string(), ecml_extract_keywords(), ecml_get_keyword_info().
Added callback for resolving ECML given an embed code / URL.
Removed unused page setup hook.
Added web services support.
Updated docs.

git-svn-id: http://code.elgg.org/elgg/trunk@6664 36083f99-b078-4883-b0ff-0f9b5a30f544

mod/ecml/README.txt
mod/ecml/ecml_functions.php
mod/ecml/start.php

index 7d59d6dbcdcd41b912373e6ccc5f6852caa155d0..3c18998ccaa7ed3ac06d7f6bae12d5e9ffbc0a5c 100644 (file)
@@ -7,7 +7,8 @@ CONTENTS:
                3.1  Utility keywords 'entity' and 'view'
                3.2  Embedded 3rd party media
        4.  Custom ECML Keywords
-       5.  Hints and Quirks
+       5.  Embed support
+       6.  Hints and Quirks
 
 
 1.  OVERVIEW
@@ -116,6 +117,7 @@ CONTENTS:
 
                        function buttonizer_ecml_keywords($hook, $type, $value, $params) {
                                $value['buttonizer'] = array(
+                                       'name' => 'Buttonizer',
                                        'view' => 'buttonizer/ecml/buttonizer',
                                        'description' => 'Makes your text a button!  What could be better?',
                                        'usage' => 'Use [buttonizer text="My text"] to make "My text" a button!'
@@ -143,7 +145,31 @@ CONTENTS:
        but is much simpler for the user.
 
 
-5.  HINTS AND QUIRKS
+5.  EMBED SUPPORT
+
+       ECML and the Embed plugin are closely related in that Embed serves
+       as a sort of front end for ECML.  Especially with 3rd party web
+       services, where URLs and embed codes vary greatly, having a system
+       in place that allows a user to easily generate and insert ECML
+       is benificial.
+       
+       Currently, only web services ECML keywords are supported in the
+       embed plugin.  Registering a web service keyword looks like this:
+       
+               $value[youtube] = array(
+                       'name' => 'Youtube',
+                       'view' => "ecml/keywords/youtube",
+                       'description' => 'Embed YouTube videos',
+                       'usage' => 'Use src="URL".',
+                       
+                       // important bits
+                       'type' => 'web_service',
+                       'params' => array('src', 'width', 'height') // a list of supported params
+                       'embed' => 'src="%s"' // a sprintf string of the require param format. Added automatically to [keyword $here]
+               ); 
+
+
+6.  HINTS AND QUIRKS
 
        * A custom keyword is slightly more complicated to implement, but is
        much simpler for the end user to use.
index eba8460b2613d1ffc294636af1bbfec6fccb0518..a4ec8be4f02e3fc1a74fd9dc3e3dfd0fb5c08f9b 100644 (file)
@@ -9,6 +9,39 @@
  * @link http://elgg.org/
  */
 
+/**
+ * Parses a string for ECML.
+ * 
+ * @param string $string
+ * @return string $string with ECML replaced by HTML.
+ */
+function ecml_parse_string($string, $view = NULL) {
+       global $CONFIG;
+       
+       $CONFIG->ecml_current_view = $view;
+       
+       return preg_replace_callback(ECML_KEYWORD_REGEX, 'ecml_parse_view_match', $string);
+}
+
+/**
+ * Returns ECML-style keywords found in $string.
+ * Doesn't validate them.
+ * Returns an array of keyword => arguments
+ * 
+ * @param string $string
+ * @return array
+ */
+function ecml_extract_keywords($string) {
+       $return = array();
+               
+       if (preg_match_all(ECML_KEYWORD_REGEX, $string, $matches)) {
+               foreach ($matches[1] as $i => $keyword) {
+                       $return[] = array('keyword' => $keyword, 'params' => $matches[2][$i]);
+               }
+       }
+       
+       return $return;
+}
 
 /**
  * Parse ECML keywords
@@ -204,6 +237,11 @@ function ecml_is_valid_keyword($keyword, $view = NULL) {
        if (!isset($CONFIG->ecml_keywords[$keyword])) {
                return FALSE;
        }
+       
+       // don't check against views. Already know it's a real one.
+       if (!$view) {
+               return TRUE;
+       }
 
        // this keyword is restricted to certain views
        if (isset($CONFIG->ecml_keywords[$keyword]['restricted'])
@@ -222,3 +260,34 @@ function ecml_is_valid_keyword($keyword, $view = NULL) {
 
        return $r;
 }
+
+/**
+ * Grab the ECML keywords as saved in $CONFIG or regenerate.
+ */
+function ecml_get_keywords($recache = FALSE) {
+       global $CONFIG;
+       
+       if (isset($CONFIG->ecml_keywords) && !$recache) {
+               return $CONFIG->ecml_keywords;
+       }
+       
+       $keywords = trigger_plugin_hook('get_keywords', 'ecml', NULL, array());
+       $CONFIG->ecml_keywords = $keywords;
+       return $keywords;
+}
+
+/**
+ * Return basic info about the keyword.
+ * 
+ * @param string $keyword
+ * @return array
+ */
+function ecml_get_keyword_info($keyword) {
+       global $CONFIG;
+       
+       if (isset($CONFIG->ecml_keywords[$keyword])) {
+               return $CONFIG->ecml_keywords[$keyword];
+       }
+       
+       return FALSE;
+}
\ No newline at end of file
index 598af0185f7e42c0854f1445dbff34b1c4c4eef6..1c1bbd3fd1abca5d141d89c8bf5958a3fcc79663 100644 (file)
@@ -24,13 +24,18 @@ function ecml_init() {
 
        define('ECML_ATTR_SEPARATOR', ' ');
        define('ECML_ATTR_OPERATOR', '=');
+       
+       // find alphanumerics (keywords) possibly followed by everything that is not a ] (args) and all surrounded by [ ]s
+       define('ECML_KEYWORD_REGEX', '/\[([a-z0-9\.]+)([^\]]+)?\]/');
 
        // help page
        register_page_handler('ecml', 'ecml_help_page_handler');
 
        // admin access page
        register_page_handler('ecml_admin', 'ecml_admin_page_handler');
-       register_elgg_event_handler('pagesetup', 'system', 'ecml_pagesetup');
+       
+       // ecml validator for embed
+       register_page_handler('ecml_generate', 'ecml_generate_page_handler');
 
        // CSS for admin access
        elgg_extend_view('css', 'ecml/admin/css');
@@ -70,16 +75,9 @@ function ecml_init() {
        // but probably makes more sense from a UI perspective as a whitelist.
        // uses [views][view_name] = array(keywords, not, allowed)
        $CONFIG->ecml_permissions = unserialize(get_plugin_setting('ecml_permissions', 'ecml'));
-}
-
-/**
- * Page setup. Adds admin controls to the admin panel for granular permission
- */
-function ecml_pagesetup(){
-       if (get_context() == 'admin' && isadminloggedin()) {
-               global $CONFIG;
-
-       }
+       
+       // 3rd party media embed section
+       register_plugin_hook('embed_get_sections', 'all', 'ecml_embed_web_services_hook');
 }
 
 /**
@@ -93,6 +91,74 @@ function ecml_help_page_handler($page) {
        echo page_draw(elgg_echo('ecml:help'), $body);
 }
 
+/**
+ * Generate ECML given a URL or embed link and service.
+ * Doesn't check if the resource actually exists.
+ * Outputs JSON.
+ * 
+ * @param unknown_type $page
+ */
+function ecml_generate_page_handler($page) {
+       $service = trim(get_input('service'));
+       $resource = trim(get_input('resource'));
+
+       // if standard ECML is passed, guess the service from that instead
+       // only support one.
+       if (elgg_substr($resource, 0, 1) == '[') {
+               if ($keywords = ecml_extract_keywords($resource)) {
+                       $keyword = $keywords[0]['keyword'];
+                       $ecml_info = ecml_get_keyword_info($keyword);
+                       $html = ecml_parse_string($resource);
+                       
+                       echo json_encode(array(
+                               'status' => 'success',
+                               'ecml' => $resource,
+                               'html' => $html
+                       ));
+                       
+                       exit;
+               }
+       }
+
+       if (!$service || !$resource) {
+               echo json_encode(array(
+                       'status' => 'error',
+                       'message' => elgg_echo('ecml:embed:invalid_web_service_keyword')
+               ));
+               
+               exit;
+       }
+       
+       $ecml_info = ecml_get_keyword_info($service);
+       
+       if ($ecml_info) {
+               // don't allow embedding for restricted.
+               if (isset($ecml_info['restricted'])) {
+                       $result = array(
+                               'status' => 'error',
+                               'message' => elgg_echo('ecml:embed:cannot_embed'),
+                       );
+               } else {
+                       // @todo pull this out into a function.  allow optional arguments.
+                       $ecml = "[$service " . sprintf($ecml_info['embed_format'], $resource) . ']';
+                       $html = ecml_parse_string($ecml, NULL);
+                       $result = array(
+                               'status' => 'success',
+                               'ecml' => $ecml,
+                               'html' => $html
+                       );
+               }
+       } else {
+               $result = array(
+                       'status' => 'error',
+                       'message' => elgg_echo('ecml:embed:invalid_web_service_keyword')
+               );
+       }
+       
+       echo json_encode($result);
+       exit;
+}
+
 /**
  * Display a admin area for ECML
  *
@@ -118,13 +184,7 @@ function ecml_admin_page_handler($page) {
 function ecml_parse_view($hook, $entity_type, $return_value, $params) {
        global $CONFIG;
 
-       // give me everything that is not a ], possibly followed by a :, and surrounded by [ ]s
-       //$keyword_regex = '/\[\[([a-z0-9_]+):?([^\]]+)?\]\]/';
-       $keyword_regex = '/\[([a-z0-9\.]+)([^\]]+)?\]/';
-       $CONFIG->ecml_current_view = $params['view'];
-       $return_value = preg_replace_callback($keyword_regex, 'ecml_parse_view_match', $return_value);
-
-       return $return_value;
+       return ecml_parse_string($return_value, $params['view']);
 }
 
 
@@ -141,26 +201,37 @@ function ecml_keyword_hook($hook, $type, $value, $params) {
        // I keep going back and forth about entity and view. They're powerful, but
        // a great way to let a site get hacked if the admin doesn't lock them down.
        $keywords = array(
-               'youtube',
-               'slideshare',
-               'vimeo',
-               'googlemaps',
-               'scribd',
-               'blip.tv',
-               'dailymotion',
-               'livevideo',
-               'redlasso',
-               'entity'
+               'youtube' => array('params' => array('src', 'width', 'height'), 'embed_format' => 'src="%s"'),
+               'slideshare' => array('params' => array('id', 'width', 'height'), 'embed_format' => 'id="%s"'),
+               'vimeo' => array('params' => array('src', 'width', 'height'), 'embed_format' => 'src="%s"'),
+               'googlemaps' => array('params' => array('src', 'width', 'height'), 'embed_format' => 'src="%s"'),
+               //'scribd'
+               'blip.tv' => array('params' => array('width', 'height'), 'embed_format' => '%s'),
+               'dailymotion' => array('params' => array('src', 'width', 'height'), 'embed_format' => 'src="%s"'),
+               'livevideo' => array('params' => array('src', 'width', 'height'), 'embed_format' => 'src="%s"'),
+               'redlasso' => array('params' => array('id', 'width', 'height'), 'embed_format' => 'id="%s"'),
        );
 
-       foreach ($keywords as $keyword) {
+       foreach ($keywords as $keyword => $info) {
                $value[$keyword] = array(
+                       'name' => elgg_echo("ecml:keywords:$keyword"),
                        'view' => "ecml/keywords/$keyword",
                        'description' => elgg_echo("ecml:keywords:$keyword:desc"),
-                       'usage' => elgg_echo("ecml:keywords:$keyword:usage")
+                       'usage' => elgg_echo("ecml:keywords:$keyword:usage"),
+                       'type' => 'web_service',
+                       'params' => $info['params'],
+                       'embed_format' => $info['embed_format']
                );
        }
-
+       
+       // default entity keyword
+       $value['entity'] = array(
+               'name' => elgg_echo('ecml:keywords:entity'),
+               'view' => "ecml/keywords/entity",
+               'description' => elgg_echo("ecml:keywords:entity:desc"),
+               'usage' => elgg_echo("ecml:keywords:entity:usage")
+       );
+       
        return $value;
 }
 
@@ -178,5 +249,23 @@ function ecml_views_hook($hook, $type, $value, $params) {
        return $value;
 }
 
+/**
+ * Show the special Web Services embed section.
+ * 
+ * @param unknown_type $hook
+ * @param unknown_type $type
+ * @param unknown_type $value
+ * @param unknown_type $params
+ */
+function ecml_embed_web_services_hook($hook, $type, $value, $params) {
+       // we're using a view override for this section's content
+       // so only need to pass the name.
+       $value['web_services'] = array(
+               'name' => elgg_echo('embed:web_services')
+       );
+
+       return $value;
+}
+
 // be sure to run after other plugins
 register_elgg_event_handler('init', 'system', 'ecml_init', 9999);
\ No newline at end of file