aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mod/ecml/README.txt30
-rw-r--r--mod/ecml/ecml_functions.php69
-rw-r--r--mod/ecml/start.php151
3 files changed, 217 insertions, 33 deletions
diff --git a/mod/ecml/README.txt b/mod/ecml/README.txt
index 7d59d6dbc..3c18998cc 100644
--- a/mod/ecml/README.txt
+++ b/mod/ecml/README.txt
@@ -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.
diff --git a/mod/ecml/ecml_functions.php b/mod/ecml/ecml_functions.php
index eba8460b2..a4ec8be4f 100644
--- a/mod/ecml/ecml_functions.php
+++ b/mod/ecml/ecml_functions.php
@@ -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
diff --git a/mod/ecml/start.php b/mod/ecml/start.php
index 598af0185..1c1bbd3fd 100644
--- a/mod/ecml/start.php
+++ b/mod/ecml/start.php
@@ -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');
}
/**
@@ -94,6 +92,74 @@ function ecml_help_page_handler($page) {
}
/**
+ * 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
*
* @param array $page
@@ -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