From 2d1b0e1d3f7816639c6221676fee3477b7f935a7 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Tue, 6 Sep 2011 17:43:39 -0700 Subject: [PATCH 001/629] Issue #875366 by fago: Correction in the D7 Rules integration. --- flag.module | 4 ---- 1 file changed, 4 deletions(-) diff --git a/flag.module b/flag.module index b0728e8..3081b5b 100644 --- a/flag.module +++ b/flag.module @@ -1196,10 +1196,6 @@ function flag_theme() { 'render element' => 'element', 'file' => 'includes/flag.admin.inc', ), - 'flag_rules_radios' => array( - 'render element' => 'element', - 'file' => 'flag.rules.inc', - ), ); } From 707b18f0d31119416ca26f05217a2fce6f57c5b8 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Tue, 6 Sep 2011 18:31:58 -0700 Subject: [PATCH 002/629] Issue #1160738 by geerlingguy: Getting 'Undefined index: join field in flag_views_data_alter()' when clearing caches. --- includes/flag.views.inc | 60 +++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/includes/flag.views.inc b/includes/flag.views.inc index 630ea26..02fa5bb 100644 --- a/includes/flag.views.inc +++ b/includes/flag.views.inc @@ -159,35 +159,37 @@ function flag_views_data_alter(&$data) { $flag = flag_flag::factory_by_content_type($flag_type); $info = $flag->get_views_info(); - // Add the flag relationship. - $data[$info['views table']]['flag_content_rel'] = array( - 'group' => t('Flags'), - 'title' => $info['title'], - 'help' => $info['help'], - 'relationship' => array( - 'flag type' => $flag_type, - 'handler' => 'flag_handler_relationship_content', - 'label' => t('flag'), - 'base' => 'flag_content', - 'base field' => 'content_id', - 'relationship field' => $info['join field'], - ), - ); - - // Add the flag counter relationship. - $data[$info['views table']]['flag_count_rel'] = array( - 'group' => t('Flags'), - 'title' => $info['counter title'], - 'help' => $info['counter help'], - 'relationship' => array( - 'flag type' => $flag_type, - 'handler' => 'flag_handler_relationship_counts', - 'label' => t('counter'), - 'base' => 'flag_counts', - 'base field' => 'content_id', - 'relationship field' => $info['join field'], - ), - ); + if(!empty($info['join field'])) { + // Add the flag relationship. + $data[$info['views table']]['flag_content_rel'] = array( + 'group' => t('Flags'), + 'title' => $info['title'], + 'help' => $info['help'], + 'relationship' => array( + 'flag type' => $flag_type, + 'handler' => 'flag_handler_relationship_content', + 'label' => t('flag'), + 'base' => 'flag_content', + 'base field' => 'content_id', + 'relationship field' => $info['join field'], + ), + ); + + // Add the flag counter relationship. + $data[$info['views table']]['flag_count_rel'] = array( + 'group' => t('Flags'), + 'title' => $info['counter title'], + 'help' => $info['counter help'], + 'relationship' => array( + 'flag type' => $flag_type, + 'handler' => 'flag_handler_relationship_counts', + 'label' => t('counter'), + 'base' => 'flag_counts', + 'base field' => 'content_id', + 'relationship field' => $info['join field'], + ), + ); + } } // Add a relationship for the user that flagged any type of content. From e7d73d5722690ee7f3bc1dde731017a339f405dc Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Tue, 6 Sep 2011 19:33:49 -0700 Subject: [PATCH 003/629] Issue #1173124 by Amitaibu: Fix strict notice in flag handler. --- includes/flag_handler_relationships.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/flag_handler_relationships.inc b/includes/flag_handler_relationships.inc index 0ac60af..a283042 100644 --- a/includes/flag_handler_relationships.inc +++ b/includes/flag_handler_relationships.inc @@ -120,7 +120,7 @@ class flag_handler_relationship_content extends flag_handler_relationship { } } - function options_validate($form, &$form_state) { + function options_validate(&$form, &$form_state) { if (!empty($form_state['no flags exist'])) { form_error($form, t('You must first create a flag')); } @@ -130,7 +130,7 @@ class flag_handler_relationship_content extends flag_handler_relationship { return $this->options['user_scope'] == 'current' ? t('by current user') : t('by any user'); } - function ui_name() { + function ui_name($short = FALSE) { // We put the bookmark name in the UI string to save space. return t('!group: !title', array('!group' => $this->definition['group'], '!title' => empty($this->options['flag']) ? t('(Please select a flag)') : $this->options['flag'])); } @@ -190,7 +190,7 @@ class flag_handler_relationship_counts extends flag_handler_relationship { // Nothing to show. } - function ui_name() { + function ui_name($short = FALSE) { // We put the bookmark name in the UI string to save space. return t('!group: !title counter', array('!group' => $this->definition['group'], '!title' => $this->options['flag'])); } From eb55804a013edd5693c108acf97dad208a3fa9d0 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Tue, 6 Sep 2011 19:37:17 -0700 Subject: [PATCH 004/629] Issue #1119842 by duellj: Strict warnings with Views 3.x. --- includes/flag_handler_field_ops.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag_handler_field_ops.inc b/includes/flag_handler_field_ops.inc index 116ff67..aaa8f2b 100644 --- a/includes/flag_handler_field_ops.inc +++ b/includes/flag_handler_field_ops.inc @@ -109,7 +109,7 @@ class flag_handler_field_ops extends views_handler_field { * separate DB query to to avoid complexity and to make 'many to one' tests * (e.g. checking user roles) possible without causing duplicate rows. */ - function pre_render($values) { + function pre_render(&$values) { if (!($flag = $this->get_flag())) { return; // Error message is printed in render(). } From 3b4920b6b2ba8bec31ac57ac7d09b7f0b1ae1688 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Wed, 7 Sep 2011 08:22:30 -0700 Subject: [PATCH 005/629] Issue #1095348 by jzacsh: Add column and table descriptions to hook_schema(). --- flag.install | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 7ebdf11..8997e09 100644 --- a/flag.install +++ b/flag.install @@ -144,38 +144,45 @@ function flag_schema() { $schema = array(); $schema['flags'] = array( + 'description' => 'All available flags in the system.', 'fields' => array( 'fid' => array( + 'description' => 'The unique ID for this particular flag.', 'type' => 'serial', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, ), 'content_type' => array( + 'description' => 'The flag type, such as one of "node", "comment", or "user".', 'type' => 'varchar', 'length' => '32', 'not null' => TRUE, 'default' => '', ), 'name' => array( + 'description' => 'The machine-name for this flag.', 'type' => 'varchar', 'length' => '32', 'not null' => FALSE, 'default' => '', ), 'title' => array( + 'description' => 'The human-readable title for this flag.', 'type' => 'varchar', 'length' => '255', 'not null' => FALSE, 'default' => '', ), 'global' => array( + 'description' => 'Whether this flag state should act as a single toggle to all users across the site.', 'type' => 'int', 'size' => 'tiny', 'not null' => FALSE, 'default' => 0, ), 'options' => array( + 'description' => 'The options and configuration of this flag.', 'type' => 'text', 'not null' => FALSE, ), @@ -187,13 +194,16 @@ function flag_schema() { ); $schema['flag_content'] = array( + 'description' => 'Content that has been flagged.', 'fields' => array( 'fcid' => array( + 'description' => 'The unique ID for this particular tag.', 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, ), 'fid' => array( + 'description' => 'The unqiue flag ID this content has been flagged with, from {flags}.', 'type' => 'int', 'size' => 'small', 'unsigned' => TRUE, @@ -201,30 +211,35 @@ function flag_schema() { 'default' => 0, ), 'content_type' => array( + 'description' => 'The flag type, one of "node", "comment", "user".', 'type' => 'varchar', 'length' => '32', 'not null' => TRUE, 'default' => '', ), 'content_id' => array( + 'description' => 'The unique ID of the content, such as either the {cid}, {uid}, or {nid}.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'uid' => array( + 'description' => 'The user ID by which this content was created.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'sid' => array( + 'description' => "The user's session id as stored in the session table.", 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'timestamp' => array( + 'description' => 'The UNIX time stamp representing when the flag was set.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -243,8 +258,10 @@ function flag_schema() { ); $schema['flag_types'] = array( + 'description' => 'The types (usually as defined in {node_type}) that are affected by a flag.', 'fields' => array( 'fid' => array( + 'description' => 'The unqiue flag ID as defined for the flag in {flags}.', 'type' => 'int', 'size' => 'small', 'unsigned' => TRUE, @@ -252,10 +269,12 @@ function flag_schema() { 'default' => 0, ), 'type' => array( + 'description' => 'The types (usually from {node_type}) that can be flagged by this fid.', 'type' => 'varchar', 'length' => '32', 'not null' => TRUE, - 'default' => '') + 'default' => '', + ), ), 'indexes' => array( 'fid' => array('fid'), @@ -263,6 +282,7 @@ function flag_schema() { ); $schema['flag_counts'] = array( + 'description' => 'The number of times an item has been flagged.', 'fields' => array( 'fid' => array( 'type' => 'int', @@ -272,12 +292,14 @@ function flag_schema() { 'default' => 0, ), 'content_type' => array( + 'description' => 'The flag type, usually one of "node", "comment", "user".', 'type' => 'varchar', 'length' => '32', 'not null' => TRUE, 'default' => '', ), 'content_id' => array( + 'description' => 'The unique ID of the content, usually either the {cid}, {uid}, or {nid}.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -285,6 +307,7 @@ function flag_schema() { 'disp-width' => '10', ), 'count' => array( + 'description' => 'The number of times this content has been flagged for this flag.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, From 142ad508c4fca01a9757c0497d3b882ee804db31 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Wed, 7 Sep 2011 09:43:09 -0700 Subject: [PATCH 006/629] Issue #1047954: User warning: Column 'uid' in on clause is ambiguous query on Flag default views. --- includes/flag.views_default.inc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/includes/flag.views_default.inc b/includes/flag.views_default.inc index 21acacc..8d17f7c 100644 --- a/includes/flag.views_default.inc +++ b/includes/flag.views_default.inc @@ -37,6 +37,7 @@ function flag_views_default_views() { 'id' => 'name', 'table' => 'users', 'field' => 'name', + 'relationship' => 'uid_1', ), ); @@ -98,6 +99,13 @@ function flag_views_default_views() { 'button' => 'Override', ), ), + 'uid_1' => array( + 'label' => 'author', + 'required' => 0, + 'id' => 'uid_1', + 'table' => 'node', + 'field' => 'uid', + ), ); $access = array( From 4c61509091f826aafa7ae9e8f47067a0390ffe70 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Wed, 7 Sep 2011 17:22:07 -0700 Subject: [PATCH 007/629] Issue #1202648 by cyborg_572 and quicksketch: Add a token for Flag link. --- includes/flag.token.inc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/includes/flag.token.inc b/includes/flag.token.inc index 5cd1f4b..75e9ca7 100644 --- a/includes/flag.token.inc +++ b/includes/flag.token.inc @@ -66,6 +66,10 @@ function flag_token_info() { 'name' => t('@flag flag count', array('@flag' => $flag->get_title())), 'description' => t('Total flag count for flag @flag', array('@flag' => $flag->get_title())), ); + $tokens[$flag_type]['flag-'. str_replace('_', '-', $flag->name) .'-link'] = array( + 'name' => t('@flag flag link', array('@flag' => $flag->get_title())), + 'description' => t('Flag/unflag link for @flag', array('@flag' => $flag->get_title())), + ); } } @@ -109,13 +113,13 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr $replacements[$original] = $sanitize ? check_plain($action->content_title) : $action->content_title; break; case 'content-type': - $replacements[$original] =$action->content_type; + $replacements[$original] = $action->content_type; break; case 'content-id': - $replacements[$original] =$action->content_id; + $replacements[$original] = $action->content_id; break; case 'count': - $replacements[$original] =$action->count; + $replacements[$original] = $action->count; break; } } @@ -126,10 +130,14 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr $object = $data[$type]; foreach ($flags as $flag) { foreach ($tokens as $name => $original) { - $flag_token = 'flag-'. str_replace('_', '-', $flag->name) .'-count'; - if ($name == $flag_token) { + $flag_count_token = 'flag-'. str_replace('_', '-', $flag->name) .'-count'; + $flag_link_token = 'flag-'. str_replace('_', '-', $flag->name) .'-count'; + if ($name == $flag_count_token) { $replacements[$original] = $flag->get_count($flag->get_content_id($object)); } + elseif ($name == $flag_link_token) { + $replacements[$original] = flag_create_link($flag->name, $flag->get_content_id($object)); + } } } } From 3b76a95d06fca28ab42326ecfc58a8e58962224b Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Wed, 7 Sep 2011 17:24:10 -0700 Subject: [PATCH 008/629] Issue #1223380 by geerlingguy: Flag module needs to implement hook_user_delete. --- flag.module | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/flag.module b/flag.module index 3081b5b..ec4df96 100644 --- a/flag.module +++ b/flag.module @@ -585,6 +585,20 @@ function flag_user_login(&$edit, &$account) { * Implements hook_user_cancel(). */ function flag_user_cancel($edit, $account, $method) { + flag_user_account_removal($account); +} + +/** + * Implements hook_user_delete(). + */ +function flag_user_delete($account) { + flag_user_account_removal($account); +} + +/** + * Callback function for user account cancellation or deletion. + */ +function flag_user_account_removal($account) { // Remove flags by this user. $query = db_select('flag_content', 'fc'); $query->leftJoin('flag_counts', 'c', 'fc.content_id = c.content_id AND fc.content_type = c.content_type'); From be68a73c9110d4c404a2cb5ed9870899745090d5 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Wed, 7 Sep 2011 17:37:14 -0700 Subject: [PATCH 009/629] Issue #1196266 by bartl: Database error in flag_flag_access_multiple when trying to view bookmarks. --- flag.inc | 2 +- flag.module | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.inc b/flag.inc index 6d1da1c..c4b1bee 100644 --- a/flag.inc +++ b/flag.inc @@ -1248,7 +1248,7 @@ class flag_node extends flag_flag { // Ensure that only flaggable node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_content_id(). $result = db_select('node', 'n')->fields('n', array('nid')) - ->condition('nid', $content_ids, 'IN') + ->condition('nid', array_keys($content_ids), 'IN') ->condition('type', $this->types, 'NOT IN') ->execute(); foreach ($result as $row) { diff --git a/flag.module b/flag.module index ec4df96..e112dcc 100644 --- a/flag.module +++ b/flag.module @@ -917,7 +917,7 @@ function flag_flag_access_multiple($flag, $content_ids, $account) { // want to deny access, or use the current access value provided by Flag. $result = db_select('node', 'n') ->fields('n', array('nid', 'uid')) - ->condition('nid', $content_ids, 'IN') + ->condition('nid', array_keys($content_ids), 'IN') ->condition('type', $flag->types, 'IN') ->execute(); foreach ($result as $row) { From 12471cc009c7b3c80a574404f9097d11089eff21 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Wed, 7 Sep 2011 18:01:51 -0700 Subject: [PATCH 010/629] Issue #1202648 by Dave Reid: Correction to the flag link token. --- includes/flag.token.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.token.inc b/includes/flag.token.inc index 75e9ca7..2b9eb6e 100644 --- a/includes/flag.token.inc +++ b/includes/flag.token.inc @@ -131,7 +131,7 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr foreach ($flags as $flag) { foreach ($tokens as $name => $original) { $flag_count_token = 'flag-'. str_replace('_', '-', $flag->name) .'-count'; - $flag_link_token = 'flag-'. str_replace('_', '-', $flag->name) .'-count'; + $flag_link_token = 'flag-'. str_replace('_', '-', $flag->name) .'-link'; if ($name == $flag_count_token) { $replacements[$original] = $flag->get_count($flag->get_content_id($object)); } From 37602f6f2b047f80ef0ad7c729e299a8d513a652 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Wed, 7 Sep 2011 19:41:30 -0700 Subject: [PATCH 011/629] Issue #901136: Fix the existing tests so they pass. --- tests/flag.test | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/tests/flag.test b/tests/flag.test index 461650e..bcacc9a 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -33,15 +33,15 @@ class FlagTestCase extends DrupalWebTestCase { $edit = array( 'name' => strtolower($this->randomName()), 'title' => $this->randomName(), - 'flag_short' => 'flag short [nid]', - 'flag_long' => 'flag long [nid]', - 'flag_message' => 'flag message [nid]', - 'unflag_short' => 'unflag short [nid]', - 'unflag_long' => 'unflag long [nid]', - 'unflag_message' => 'unflag message [nid]', + 'flag_short' => 'flag short [node:nid]', + 'flag_long' => 'flag long [node:nid]', + 'flag_message' => 'flag message [node:nid]', + 'unflag_short' => 'unflag short [node:nid]', + 'unflag_long' => 'unflag long [node:nid]', + 'unflag_message' => 'unflag message [node:nid]', 'roles[flag][2]' => TRUE, 'roles[unflag][2]' => TRUE, - 'types[story]' => FALSE, + 'types[article]' => FALSE, 'types[page]' => TRUE, 'show_on_teaser' => FALSE, 'show_on_page' => FALSE, @@ -51,10 +51,11 @@ class FlagTestCase extends DrupalWebTestCase { $saved = $edit; $saved['roles'] = array('flag' => array(2), 'unflag' => array(2)); $saved['types'] = array('page'); - unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[story]'], $saved['types[page]']); + unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); $this->drupalPost(FLAG_ADMIN_PATH . '/add/node/' . $edit['name'], $edit, t('Submit')); + flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); // Check that the flag object is in the database. @@ -69,15 +70,15 @@ class FlagTestCase extends DrupalWebTestCase { $edit = array( 'name' => strtolower($this->randomName()), 'title' => $this->randomName(), - 'flag_short' => 'flag 2 short [nid]', - 'flag_long' => 'flag 2 long [nid]', - 'flag_message' => 'flag 2 message [nid]', - 'unflag_short' => 'unflag 2 short [nid]', - 'unflag_long' => 'unflag 2 long [nid]', - 'unflag_message' => 'unflag 2 message [nid]', + 'flag_short' => 'flag 2 short [node:nid]', + 'flag_long' => 'flag 2 long [node:nid]', + 'flag_message' => 'flag 2 message [node:nid]', + 'unflag_short' => 'unflag 2 short [node:nid]', + 'unflag_long' => 'unflag 2 long [node:nid]', + 'unflag_message' => 'unflag 2 message [node:nid]', 'roles[flag][2]' => TRUE, 'roles[unflag][2]' => TRUE, - 'types[story]' => TRUE, + 'types[article]' => TRUE, 'types[page]' => FALSE, 'show_on_teaser' => TRUE, 'show_on_page' => TRUE, @@ -86,10 +87,10 @@ class FlagTestCase extends DrupalWebTestCase { ); $saved = $edit; $saved['roles'] = array('flag' => array(2), 'unflag' => array(2)); - $saved['types'] = array('story'); - unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[story]'], $saved['types[page]']); + $saved['types'] = array('article'); + unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); - $this->drupalPost(FLAG_ADMIN_PATH . '/edit/' . $flag->name, $edit, t('Submit')); + $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name, $edit, t('Submit')); flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); @@ -103,7 +104,7 @@ class FlagTestCase extends DrupalWebTestCase { } // Delete the flag through the UI. - $this->drupalPost(FLAG_ADMIN_PATH . '/delete/' . $flag->name, array(), t('Delete')); + $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name . '/delete', array(), t('Delete')); flag_get_flags(NULL, NULL, NULL, TRUE); $this->assertFalse(flag_get_flag($flag->name), t('Flag successfully deleted.')); } From 8296d3facdbce7babbd9c6f16aa39f45278a868b Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Thu, 8 Sep 2011 10:23:39 -0700 Subject: [PATCH 012/629] Issue #1136248: Update hook_field_extra_fields() for ordering Flag fieldset on forms. --- flag.module | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/flag.module b/flag.module index e112dcc..5de95b6 100644 --- a/flag.module +++ b/flag.module @@ -325,24 +325,27 @@ function flag_flag_link_types() { */ function flag_field_extra_fields() { $extra = array(); - $flags = flag_get_flags('node'); - // Filter out flags which need to be included on the node form. - foreach ($flags as $name => $flag) { - if (!$flag->show_on_form) { - unset($flags[$name]); + foreach (node_type_get_types() as $type) { + $flags = flag_get_flags('node', $type->type); + + // Filter out flags which need to be included on the node form. + $flag_names = array(); + foreach ($flags as $name => $flag) { + if ($flag->show_on_form) { + $flag_names[] = $flag->get_label('title'); + } } - } - if (!empty($flags)) { - foreach (node_type_get_types() as $type) { - $extra['node'][$type->type]['flag'] = array( + if ($flag_names) { + $extra['node'][$type->type]['form']['flag'] = array( 'label' => t('Flags'), - 'description' => t('Flags fieldset.'), - 'weight' => 0 + 'description' => t('Checkboxes for toggling flags (i.e. @flag_names)', array('@flag_names' => implode(', ', $flag_names))), + 'weight' => 1 ); } } + return $extra; } @@ -427,7 +430,7 @@ function flag_form_alter(&$form, &$form_state, $form_id) { } if ($flags_in_form) { $form['flag'] += array( - '#weight' => module_exists('content') ? content_extra_field_weight($form['#node']->type, 'flags') : 1, + '#weight' => 1, '#tree' => TRUE, ); } From 95becbabdea5896b4fe2f1af2247bd76837bf2ab Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Thu, 8 Sep 2011 10:43:40 -0700 Subject: [PATCH 013/629] Issue #1191064: Always include actions (so that VBO can use it). --- flag.module | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/flag.module b/flag.module index 5de95b6..33aa272 100644 --- a/flag.module +++ b/flag.module @@ -178,9 +178,8 @@ function flag_help($path, $arg) { function flag_init() { $path = drupal_get_path('module', 'flag'); include_once $path .'/includes/flag.token.inc'; - if (module_exists('trigger')) { - include_once $path .'/includes/flag.actions.inc'; - } + include_once $path .'/includes/flag.actions.inc'; + if (module_exists('session_api')) { // Set the anonymous user SID immediately, in case the user logs in. flag_set_sid(); From 2dbe641a5d897b4d0c7687b5246aa51900a68ca9 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Thu, 8 Sep 2011 12:08:43 -0700 Subject: [PATCH 014/629] Issue #658400 by dragonwise: Rollback patch that caused a bug in the Is Flagged exposed filter when using the "Any" filter. --- includes/flag_handler_filter_flagged.inc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/includes/flag_handler_filter_flagged.inc b/includes/flag_handler_filter_flagged.inc index ea04d93..5154125 100644 --- a/includes/flag_handler_filter_flagged.inc +++ b/includes/flag_handler_filter_flagged.inc @@ -21,10 +21,7 @@ class flag_handler_filter_flagged extends views_handler_filter_boolean_operator parent::options_form($form, $form_state); $form['value']['#type'] = 'radios'; $form['value']['#title'] = t('Status'); - $form['value']['#options'] = array(1 => t('Flagged'), 0 => t('Not flagged')); - if ($this->options['expose']['optional']) { - $form['value']['#options']['All'] = t('All'); - } + $form['value']['#options'] = array(1 => t('Flagged'), 0 => t('Not flagged'), 'All' => t('All')); $form['value']['#default_value'] = empty($this->options['value']) ? 0 : $this->options['value']; $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; } From ab1485316cb06352019258881003483da3aff595 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Thu, 8 Sep 2011 13:16:39 -0700 Subject: [PATCH 015/629] Issue #1252788 by Dave Reid: Token hook should be moved from /includes/flag.token.inc to /flag.tokens.inc. --- flag.module | 3 +-- includes/flag.token.inc => flag.tokens.inc | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename includes/flag.token.inc => flag.tokens.inc (100%) diff --git a/flag.module b/flag.module index 33aa272..128f906 100644 --- a/flag.module +++ b/flag.module @@ -177,7 +177,6 @@ function flag_help($path, $arg) { */ function flag_init() { $path = drupal_get_path('module', 'flag'); - include_once $path .'/includes/flag.token.inc'; include_once $path .'/includes/flag.actions.inc'; if (module_exists('session_api')) { @@ -1202,7 +1201,7 @@ function flag_theme() { ), 'flag_tokens_browser' => array( 'variables' => array('types' => array('all'), 'global_types' => TRUE), - 'file' => 'includes/flag.token.inc', + 'file' => 'flag.tokens.inc', ), 'flag_admin_page' => array( 'variables' => array('flags' => NULL, 'default_flags' => NULL), diff --git a/includes/flag.token.inc b/flag.tokens.inc similarity index 100% rename from includes/flag.token.inc rename to flag.tokens.inc From df418ab4b660ceebd14b7e2c125530770ec1045d Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Thu, 8 Sep 2011 13:21:31 -0700 Subject: [PATCH 016/629] Issue #1176902 by heyrocker: Remove Services integration, now moved to a dedicated project at http://drupal.org/project/flag_service. --- flag.module | 83 ----------------------------------- includes/flag.services.inc | 90 -------------------------------------- 2 files changed, 173 deletions(-) delete mode 100644 includes/flag.services.inc diff --git a/flag.module b/flag.module index 128f906..c1fe542 100644 --- a/flag.module +++ b/flag.module @@ -1103,89 +1103,6 @@ function flag_mail($key, &$message, $params) { } } -/** - * Implements hook_service(). - */ -function flag_service() { - $items = array(); - - $items[] = array( - '#method' => 'flag.flag', - '#callback' => 'flag_service_flag', - '#access callback' => 'flag_service_flag_access', - '#file' => array( - 'file' => 'inc', - 'module' => 'flag', - 'file name' => 'includes/flag.services', - ), - '#args' => array( - array( - '#name' => 'flag_name', - '#type' => 'string', - '#description' => t('The name of the flag.'), - ), - array( - '#name' => 'content_id', - '#type' => 'int', - '#description' => t('The content ID.'), - ), - array( - '#name' => 'uid', - '#type' => 'int', - '#description' => t('The user ID for which to flag.'), - '#optional' => TRUE, - ), - array( - '#name' => 'action', - '#type' => 'string', - '#description' => t('Optional; The action to perform, default is "flag". Should be "flag" or "unflag".'), - '#optional' => TRUE, - ), - array( - '#name' => 'skip_permission_check', - '#type' => 'boolean', - '#description' => t('Optional; Flag the content even if the user does not have permission to do so. FALSE by default'), - '#optional' => TRUE, - ), - ), - '#return' => 'boolean', - '#help' => t('Flags (or unflags) a content.') - ); - - $items[] = array( - '#method' => 'flag.is_flagged', - '#callback' => 'flag_service_is_flagged', - '#access callback' => 'flag_service_flag_access', - '#file' => array( - 'file' => 'inc', - 'module' => 'flag', - 'file name' => 'includes/flag.services', - ), - '#args' => array( - array( - '#name' => 'flag_name', - '#type' => 'string', - '#description' => t('The name of the flag.'), - ), - array( - '#name' => 'content_id', - '#type' => 'int', - '#description' => t('The content ID.'), - ), - array( - '#name' => 'uid', - '#type' => 'int', - '#description' => t('The user ID that might have flagged the content.'), - '#optional' => TRUE, - ), - ), - '#return' => 'boolean', - '#help' => t('Check if a content was flagged by a user.') - ); - - return $items; -} - /** * Implements hook_theme(). */ diff --git a/includes/flag.services.inc b/includes/flag.services.inc deleted file mode 100644 index 872b560..0000000 --- a/includes/flag.services.inc +++ /dev/null @@ -1,90 +0,0 @@ -access($content_id, $action, $account)) { - // User has no permission to use this flag. - return FALSE; - } - return TRUE; - } -} - -/** - * Service wrapper to flag a content. - * - * @param $flag_name - * The flag name. - * @param $content_id - * The content ID to check if it was flagged. - * @param $uid - * The user ID to check if they flagged the content. - * @param $action - * The action. Should be "flag" or "unflag". - * @return - * TRUE if content was flagged. - */ -function flag_service_flag($flag_name, $content_id, $uid = NULL, $action = 'flag', $skip_permission_check = FALSE) { - global $user; - $account = empty($uid) ? $user : user_load($uid); - $flag = flag_get_flag($flag_name); - $skip_permission_check = (boolean) $skip_permission_check; - return $flag->flag($action, $content_id, $account, $skip_permission_check); -} - -/** - * Service wrapper to check if a content is flagged by a user. - * - * @param $flag_name - * The flag name. - * @param $content_id - * The content ID to check if it was flagged. - * @param $uid - * The user ID to check if they flagged the content. - * @return - * TRUE if content was flagged. - */ -function flag_service_is_flagged($flag_name, $content_id, $uid = NULL) { - $flag = flag_get_flag($flag_name); - return $flag->is_flagged($content_id, $uid); -} From 4a987e002ee07e27a9bf9712daa276bcb98255f5 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Fri, 9 Sep 2011 13:32:47 -0700 Subject: [PATCH 017/629] Issue #1105490 by catch and quicksketch: Add uid to content_type, content_id index for is_flagged(). --- flag.install | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 8997e09..0814cc6 100644 --- a/flag.install +++ b/flag.install @@ -250,9 +250,9 @@ function flag_schema() { 'primary key' => array('fcid'), 'unique keys' => array( 'fid_content_id_uid_sid' => array('fid', 'content_id', 'uid', 'sid'), + 'content_type_content_id_uid_sid' => array('content_type', 'content_id', 'uid', 'sid'), ), 'indexes' => array( - 'content_type_content_id' => array('content_type', 'content_id'), 'content_type_uid_sid' => array('content_type', 'uid', 'sid'), ), ); @@ -403,3 +403,11 @@ function flag_update_6204() { db_drop_primary_key('flag_counts'); db_add_primary_key('flag_counts', array('fid', 'content_id')); } + +/** + * Provide a better index on the flag_content table including 'uid' and 'sid'. + */ +function flag_update_6205() { + db_drop_index('flag_content', 'content_type_content_id'); + db_add_unique_key('flag_content', 'content_type_content_id_uid_sid', array('content_type', 'content_id', 'uid', 'sid')); +} From 38b9d412ac5acdcf4a6f1182caac643ad1c87bf4 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 10 Sep 2011 12:34:56 -0700 Subject: [PATCH 018/629] Issue #1149496 by ultimike: Flagging on node form checks perms of node author - should check perms of active user. --- flag.module | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index c1fe542..4660912 100644 --- a/flag.module +++ b/flag.module @@ -493,9 +493,10 @@ function flag_node_update($node) { * Shared saving routine between flag_node_insert() and flag_node_update(). */ function flag_node_save($node) { + global $user; + // Response to the flag checkboxes added to the form in flag_form_alter(). $remembered = FALSE; - $account = user_load($node->uid); if (isset($node->flag)) { foreach ($node->flag as $name => $state) { $flag = flag_get_flag($name); @@ -507,7 +508,7 @@ function flag_node_save($node) { // modification: $remembered = TRUE; } - flag($state ? 'flag' : 'unflag', $name, $node->nid, $account, TRUE); + flag($state ? 'flag' : 'unflag', $name, $node->nid, $user); } } } From 800b20004d338a5a65643f184d4c448617fca094 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 10 Sep 2011 12:45:23 -0700 Subject: [PATCH 019/629] Issue #720672: Make $flag->access (and _multiple) act in a consistent manner. --- flag.inc | 68 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/flag.inc b/flag.inc index c4b1bee..3c34917 100644 --- a/flag.inc +++ b/flag.inc @@ -405,6 +405,9 @@ class flag_flag { /** * Returns TRUE if the user can flag, or unflag, the given content. * + * This method typically should not be overridden by child classes. Instead + * they should implement type_access(), which is called by this method. + * * @param $content_id * The content ID to flag/unflag. * @param $account @@ -433,6 +436,12 @@ class flag_flag { // Base initial access on the user's basic permission to use this flag. $access = $this->user_access($action, $account); + // Check for additional access rules provided by sub-classes. + $child_access = $this->type_access($content_id, $action, $account); + if (isset($child_access)) { + $access = $child_access; + } + // Allow modules to disallow (or allow) access to flagging. $access_array = module_invoke_all('flag_access', $this, $content_id, $action, $account); @@ -452,6 +461,10 @@ class flag_flag { * test in the Views query, is to make 'many to one' tests possible without * interfering with the rows, and also to reduce the complexity of the code. * + * This method typically should not be overridden by child classes. Instead + * they should implement type_access_multiple(), which is called by this + * method. + * * @param $content_ids * The array of content IDs to check. The keys are the content IDs, the * values are the actions to test: either 'flag' or 'unflag'. @@ -468,6 +481,16 @@ class flag_flag { $access[$content_id] = $this->user_access($content_ids[$content_id], $account); } + // Check for additional access rules provided by sub-classes. + $child_access = $this->type_access_multiple($content_ids, $account); + if (isset($child_access)) { + foreach ($child_access as $content_id => $content_access) { + if (isset($content_access)) { + $access[$content_id] = $content_access; + } + } + } + // Merge in module-defined access. foreach (module_implements('flag_access_multiple') as $module) { $module_access = module_invoke($module, 'flag_access_multiple', $this, $content_ids, $account); @@ -481,6 +504,24 @@ class flag_flag { return $access; } + /** + * An implementation of access() implemented by each child class. + * + * @abstract + */ + function type_access($content_id, $action, $account) { + return NULL; + } + + /** + * An implementation of access_multiple() implemented by each child class. + * + * @abstract + */ + function type_access_multiple($content_ids, $account) { + return NULL; + } + /** * @} End of "defgroup access". */ @@ -1242,8 +1283,8 @@ class flag_node extends flag_flag { return FALSE; } - function access_multiple($content_ids, $account = NULL) { - $access = parent::access_multiple($content_ids, $account); + function type_access_multiple($content_ids, $account = NULL) { + $access = array(); // Ensure that only flaggable node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_content_id(). @@ -1406,10 +1447,7 @@ class flag_comment extends flag_flag { return FALSE; } - function access_multiple($content_ids, $account = NULL) { - $account = isset($account) ? $account : $GLOBALS['user']; - $access = parent::access_multiple($content_ids, $account); - + function type_access_multiple($content_ids, $account) { // Ensure node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_content_id(). $query = db_select('comment', 'c'); @@ -1535,29 +1573,23 @@ class flag_user extends flag_flag { return FALSE; } - function access($content_id, $action = NULL, $account = NULL) { - $access = parent::access($content_id, $action, $account); - $account = isset($account) ? $account : $GLOBALS['user']; - + function type_access($content_id, $action, $account) { // Prevent users from flagging themselves. if ($this->access_uid == 'others' && $content_id == $account->uid) { - $access = FALSE; + return FALSE; } - - return $access; } - function access_multiple($content_ids, $account = NULL) { - $account = isset($account) ? $account : $GLOBALS['user']; - $access = parent::access_multiple($content_ids, $account); + function type_access_multiple($content_ids, $account) { + $access = array(); // Exclude anonymous. - if (array_key_exists(0, $access)) { + if (array_key_exists(0, $content_ids)) { $access[0] = FALSE; } // Prevent users from flagging themselves. - if ($this->access_uid == 'others' && array_key_exists($account->uid, $access)) { + if ($this->access_uid == 'others' && array_key_exists($account->uid, $content_ids)) { $access[$account->uid] = FALSE; } From b4af93135ef2cc59835c851433b8c5279cff8c8f Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 10 Sep 2011 16:31:14 -0700 Subject: [PATCH 020/629] Issue #1159470 by lyricnz and quicksketch: Add ability to adjust flag order on node/add/* & /admin/structure/flags pages. --- flag.inc | 2 +- flag.module | 23 ++++++++- includes/flag.admin.inc | 112 +++++++++++++++++++++++++++++++++++----- 3 files changed, 121 insertions(+), 16 deletions(-) diff --git a/flag.inc b/flag.inc index 3c34917..7886c83 100644 --- a/flag.inc +++ b/flag.inc @@ -193,6 +193,7 @@ class flag_flag { 'flag' => array(DRUPAL_AUTHENTICATED_RID), 'unflag' => array(DRUPAL_AUTHENTICATED_RID), ), + 'weight' => 0, ); // Merge in options from the current link type. @@ -1828,4 +1829,3 @@ class FlagNonGlobalCookieStorage extends FlagCookieStorage { } } } - diff --git a/flag.module b/flag.module index 4660912..d971a9a 100644 --- a/flag.module +++ b/flag.module @@ -1121,10 +1121,18 @@ function flag_theme() { 'variables' => array('types' => array('all'), 'global_types' => TRUE), 'file' => 'flag.tokens.inc', ), - 'flag_admin_page' => array( + 'flag_admin_listing' => array( + 'render element' => 'form', + 'file' => 'includes/flag.admin.inc', + ), + 'flag_admin_listing_disabled' => array( 'variables' => array('flags' => NULL, 'default_flags' => NULL), 'file' => 'includes/flag.admin.inc', ), + 'flag_admin_page' => array( + 'variables' => array('flags' => NULL, 'default_flags' => NULL, 'flag_admin_listing' => NULL), + 'file' => 'includes/flag.admin.inc', + ), 'flag_form_roles' => array( 'render element' => 'element', 'file' => 'includes/flag.admin.inc', @@ -1420,6 +1428,9 @@ function flag_get_flags($content_type = NULL, $content_subtype = NULL, $account } } + // Sort the list of flags by weight. + uasort($flags, '_flag_compare_weight'); + // Allow modules implementing hook_flag_alter(&$flag) to modify each flag. foreach ($flags as $flag) { drupal_alter('flag', $flag); @@ -1452,6 +1463,16 @@ function flag_get_flags($content_type = NULL, $content_subtype = NULL, $account return $filtered_flags; } +/** + * Comparison function for uasort(). + */ +function _flag_compare_weight($flag1, $flag2) { + if ($flag1->weight == $flag2->weight) { + return 0; + } + return $flag1->weight < $flag2->weight ? -1 : 1; +} + /** * Utility function: Checks whether a flag applies to a certain type, and * possibly subtype, of content. diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index e44224b..27543a4 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -11,18 +11,59 @@ function flag_admin_page() { $flags = flag_get_flags(); $default_flags = flag_get_default_flags(TRUE); - return theme('flag_admin_page', array('flags' => $flags, 'default_flags' => $default_flags)); + $flag_admin_listing = drupal_get_form('flag_admin_listing', $flags); + return theme('flag_admin_page', array('flags' => $flags, 'default_flags' => $default_flags, 'flag_admin_listing' => $flag_admin_listing)); } /** - * Theme the output for the main flag administration page. + * A form for ordering the weights of all the active flags in the system. */ -function theme_flag_admin_page($variables) { - $flags = $variables['flags']; - $default_flags = $variables['default_flags']; +function flag_admin_listing($form, &$form_state, $flags) { + $form['#flags'] = $flags; + $form['#tree'] = TRUE; + + foreach ($flags as $flag) { + $form['flags'][$flag->name]['weight'] = array( + '#type' => 'weight', + '#delta' => count($flags) + 5, + '#default_value' => $flag->weight, + '#attributes' => array('class' => array('flag-weight')), + ); + } + + $form['actions'] = array( + '#type' => 'actions', + ); + + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save flag order'), + ); + + return $form; +} + +/** + * Submit handler for the flag_admin_listing form. Save flag weight ordering. + */ +function flag_admin_listing_submit($form, &$form_state) { + foreach ($form['#flags'] as $flag) { + if ($flag->weight != $form_state['values']['flags'][$flag->name]['weight']) { + $flag->weight = $form_state['values']['flags'][$flag->name]['weight']; + $flag->save(); + } + } +} + +/** + * Theme the output of the normal, database flags into a table. + */ +function theme_flag_admin_listing($variables) { + $form = $variables['form']; + $flags = $form['#flags']; + $output = ''; - // Build out the list of normal, database flags. foreach ($flags as $flag) { $ops = array( 'flags_edit' => array('title' => t('edit'), 'href' => $flag->admin_path('edit')), @@ -31,23 +72,43 @@ function theme_flag_admin_page($variables) { ); $roles = array_flip(array_intersect(array_flip(user_roles()), $flag->roles['flag'])); - $rows[] = array( + $row = array( $flag->name, + drupal_render($form['flags'][$flag->name]['weight']), $flag->content_type, empty($flag->roles['flag']) ? '' . t('No roles') . '' : implode(', ', $roles), $flag->types ? implode(', ', $flag->types) : '-', $flag->global ? t('Yes') : t('No'), theme('links', array('links' => $ops)), ); + $rows[] = array( + 'data' => $row, + 'class' => array('draggable'), + ); } if (!$flags) { $rows[] = array( - array('data' => t('No flags are currently defined.'), 'colspan' => 6), + array('data' => t('No flags are currently defined.'), 'colspan' => 7), ); } + else { + drupal_add_tabledrag('flag-admin-listing-table', 'order', 'sibling', 'flag-weight'); + } - $header = array(t('Flag'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations')); - $output .= theme('table', array('header' => $header, 'rows' => $rows)); + $header = array(t('Flag'),t('Weight'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations')); + $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'flag-admin-listing-table'))); + $output .= drupal_render_children($form); + + return $output; +} + +/** + * Theme the list of disabled flags into a table. + */ +function theme_flag_admin_listing_disabled($variables) { + $flags = $variables['flags']; + $default_flags = $variables['default_flags']; + $output = ''; // Build a list of disabled, module-based flags. $rows = array(); @@ -81,6 +142,21 @@ function theme_flag_admin_page($variables) { $output .= theme('table', array('header' => $header, 'rows' => $rows)); } + return $output; +} + +/** + * Theme the output for the main flag administration page. + */ +function theme_flag_admin_page($variables) { + $flags = $variables['flags']; + $default_flags = $variables['default_flags']; + + $output = ''; + + $output .= drupal_render($variables['flag_admin_listing']); + $output .= theme('flag_admin_listing_disabled', array('flags' => $flags, 'default_flags' => $default_flags)); + if (!module_exists('views')) { $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; } @@ -154,9 +230,13 @@ function flag_add_form($form, &$form_state) { '#options' => $types, ); - $form['submit'] = array( + $form['actions'] = array( + '#type' => 'actions', + ); + + $form['actions']['submit'] = array( '#type' => 'submit', - '#value' => t('Submit'), + '#value' => t('Add flag'), ); return $form; @@ -416,9 +496,13 @@ function flag_form($form, &$form_state, $flag) { '#access' => empty($flag->locked['unflag_confirmation']), ); - $form['submit'] = array( + $form['actions'] = array( + '#type' => 'actions', + ); + + $form['actions']['submit'] = array( '#type' => 'submit', - '#value' => t('Submit'), + '#value' => t('Save flag'), // We put this button on the form before calling $flag->options_form() // to give the flag handler a chance to remove it (e.g. flag_broken). '#weight' => 999, From 79e2f15e9c3fba85446b6793a2d07bd2929c15cb Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 10 Sep 2011 16:43:51 -0700 Subject: [PATCH 021/629] Issue #1270708: Flag Actions .install file does not upgrade from D6 1.x to D7 2.x. --- flag_actions.install | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/flag_actions.install b/flag_actions.install index a191da0..8a37657 100644 --- a/flag_actions.install +++ b/flag_actions.install @@ -77,8 +77,6 @@ function flag_actions_schema() { * Add a "repeat_threshold" value to all existing Flag actions. */ function flag_actions_update_6200() { - $ret = array(); - // Add the new repeat_threshold column. if (!db_field_exists('flag_actions', 'repeat_threshold')) { $column = array( @@ -88,7 +86,7 @@ function flag_actions_update_6200() { 'default' => 0, 'disp-width' => '5', ); - db_add_field($ret, 'flag_actions', 'repeat_threshold', $column); + db_add_field('flag_actions', 'repeat_threshold', $column); } // Update the normal threshold column to default to 0. @@ -99,7 +97,5 @@ function flag_actions_update_6200() { 'default' => 0, 'disp-width' => '5', ); - db_change_field($ret, 'flag_actions', 'threshold', 'threshold', $column); - - return $ret; + db_change_field('flag_actions', 'threshold', 'threshold', $column); } From 91dc78953c5c7b4871509983de982debe9480d78 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 10 Sep 2011 17:49:15 -0700 Subject: [PATCH 022/629] Issue #1116690 by Amitaibu: Method flag_flag_access_multiple() on 'comment' flags broken. --- flag.module | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/flag.module b/flag.module index d971a9a..36ce3bc 100644 --- a/flag.module +++ b/flag.module @@ -936,13 +936,13 @@ function flag_flag_access_multiple($flag, $content_ids, $account) { // Restrict access by comment ownership. $query = db_select('comment', 'c'); $query->leftJoin('node', 'n', 'c.nid = n.nid'); - $result = $query - ->fields('c', array('cid', 'nid')) - ->addField('c', 'uid', 'comment_uid') - ->addField('n', 'uid', 'node_uid') - ->condition('c.cid', $content_ids, 'IN') - ->execute(); - while ($row = db_fetch_object($result)) { + $query + ->fields('c', array('cid', 'nid', 'uid')) + ->condition('c.cid', $content_ids, 'IN'); + $query->addField('c', 'uid', 'comment_uid'); + $result = $query->execute(); + + foreach ($result as $row) { if ($flag->access_author == 'node_own') { $access[$row->cid] = $row->node_uid != $account->uid ? FALSE : NULL; } From 29658d8cdabda371ba119be7e5755a0fb96e6ea5 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 10 Sep 2011 18:32:43 -0700 Subject: [PATCH 023/629] Issue #1134516: Fixing minor notice in comment multiple access checks (seen when using flags in comment views). --- flag.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flag.inc b/flag.inc index 7886c83..7839ef7 100644 --- a/flag.inc +++ b/flag.inc @@ -520,7 +520,7 @@ class flag_flag { * @abstract */ function type_access_multiple($content_ids, $account) { - return NULL; + return array(); } /** @@ -1449,6 +1449,8 @@ class flag_comment extends flag_flag { } function type_access_multiple($content_ids, $account) { + $access = array(); + // Ensure node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_content_id(). $query = db_select('comment', 'c'); From a0e0e32a9b6628c17688dda436beabd56c25e3d7 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 11 Sep 2011 19:14:15 -0700 Subject: [PATCH 024/629] Issue #1258282: Logging in after anonymous flagging may cause duplicate entry SQL errors. --- flag.inc | 16 +++++++--------- flag.module | 36 ++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/flag.inc b/flag.inc index 7839ef7..27e241b 100644 --- a/flag.inc +++ b/flag.inc @@ -767,18 +767,16 @@ class flag_flag { db_delete('flag_counts')->condition('fid', $this->fid)->condition('content_id', $content_id)->execute(); } else { - $num_updated = db_update('flag_counts')->fields(array('count' => $count)) - ->condition('fid', $this->fid) - ->condition('content_id', $content_id) - ->execute(); - if (!$num_updated) { - db_insert('flag_counts')->fields(array( + db_merge('flag_counts') + ->fields(array( 'fid' => $this->fid, 'content_type' => $this->content_type, 'content_id' => $content_id, - 'count' => $count)) - ->execute(); - } + 'count' => $count + )) + ->condition('fid', $this->fid) + ->condition('content_id', $content_id) + ->execute(); } } diff --git a/flag.module b/flag.module index 36ce3bc..8e8d1a6 100644 --- a/flag.module +++ b/flag.module @@ -561,21 +561,37 @@ function flag_node_translation_change($node) { function flag_user_login(&$edit, &$account) { // Migrate anonymous flags to this user's account. if (module_exists('session_api') && ($sid = flag_get_sid(0))) { - // The @ symbol suppresses errors if the user flags a piece of content - // they have already flagged as a logged-in user. - @db_update('flag_content') - ->fields(array( - 'uid' => $account->uid, - 'sid' => 0, - )) + // Get a list of flag_content IDs that will be moved over. + $fcids = db_select('flag_content', 'fc') + ->fields('fc', array('fcid')) ->condition('uid', 0) ->condition('sid', $sid) - ->execute(); + ->execute() + ->fetchCol('fcid'); + + // Convert anonymous flaggings to their authenticated account. + foreach ($fcids as $fcid) { + // Each update is wrapped in a try block to prevent unique key errors. + // Any duplicate content that was flagged as anonoymous is deleted in the + // subsequent db_delete() call. + try { + db_update('flag_content') + ->fields(array( + 'uid' => $account->uid, + 'sid' => 0, + )) + ->condition('fcid', $fcid) + ->execute(); + } + catch (Exception $e) { + NULL; + } + } // Delete any remaining flags this user had as an anonymous user. db_delete('flag_content') ->condition('uid', 0) - ->condition('sid', flag_get_sid(0)) + ->condition('sid', $sid) ->execute(); // Clean up anonymous cookies. @@ -1005,7 +1021,7 @@ function flag_reset_flag($flag, $content_id = NULL) { $query->condition('content_id', $content_id); } - $result = $query->execute()->fetchAllAssoc('fcid', PDO::FETCH_ASSOC);; + $result = $query->execute()->fetchAllAssoc('fcid', PDO::FETCH_ASSOC); $rows = array(); foreach ($result as $row) { $rows[] = $row; From 92df3eb4a1010760e3fd3163f28adb67bce5f2a8 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 11 Sep 2011 20:28:18 -0700 Subject: [PATCH 025/629] Issue #1064148 by ufku and quicksketch: Remove unnecessary DB hit and PHP processing when there is no access restriction by authorship. --- flag.module | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flag.module b/flag.module index 8e8d1a6..55441e3 100644 --- a/flag.module +++ b/flag.module @@ -881,6 +881,11 @@ function flag_flag($action, $flag, $content_id, $account) { * Implements hook_flag_access(). */ function flag_flag_access($flag, $content_id, $action, $account) { + // Do nothing if there is no restriction by authorship. + if (empty($flag->access_author)) { + return; + } + // Restrict access by authorship. It's important that TRUE is never returned // here, otherwise we'd grant permission even if other modules denied access. if ($flag->content_type == 'node') { @@ -928,6 +933,11 @@ function flag_flag_access($flag, $content_id, $action, $account) { function flag_flag_access_multiple($flag, $content_ids, $account) { $access = array(); + // Do nothing if there is no restriction by authorship. + if (empty($flag->access_author)) { + return $access; + } + if ($flag->content_type == 'node') { // Restrict access by authorship. This is similar to flag_flag_access() // above, but returns an array of 'nid' => $access values. Similarly, we From e13cf1f6b13b28489eca3ed2a2aa23ca3f0e1134 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 11 Sep 2011 21:13:45 -0700 Subject: [PATCH 026/629] Issue #1067822: $flag_name_css not being set/sent to flag.tpl.php. --- flag.module | 1 + 1 file changed, 1 insertion(+) diff --git a/flag.module b/flag.module index 55441e3..0ede96e 100644 --- a/flag.module +++ b/flag.module @@ -1221,6 +1221,7 @@ function template_preprocess_flag(&$variables) { $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $content_id); $variables['link_title'] = isset($link['attributes']['title']) ? check_plain($link['attributes']['title']) : check_plain(strip_tags($flag->get_label($action . '_long', $content_id))); $variables['status'] = ($action == 'flag' ? 'unflagged' : 'flagged'); + $variables['flag_name_css'] = $flag_css_name; $variables['flag_wrapper_classes_array'] = array(); $variables['flag_wrapper_classes_array'][] = 'flag-wrapper'; From 65797e05231b34f5902b4854fdca549419ea0d32 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 11 Sep 2011 22:02:48 -0700 Subject: [PATCH 027/629] Issue #1088672 by jodarove: Occasional duplicate fid-node key error when flagging content. --- flag.inc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/flag.inc b/flag.inc index 27e241b..4535713 100644 --- a/flag.inc +++ b/flag.inc @@ -768,14 +768,11 @@ class flag_flag { } else { db_merge('flag_counts') + ->key(array('fid' => $this->fid, 'content_id' => $content_id)) ->fields(array( - 'fid' => $this->fid, 'content_type' => $this->content_type, - 'content_id' => $content_id, 'count' => $count )) - ->condition('fid', $this->fid) - ->condition('content_id', $content_id) ->execute(); } } From 419081ae017268f2dd3640dd36917e5c1ec9347e Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 24 Sep 2011 16:09:34 -0700 Subject: [PATCH 028/629] Issue #1105490: Correction update to add uid to content_type, content_id index for is_flagged(). --- flag.install | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/flag.install b/flag.install index 0814cc6..a85e705 100644 --- a/flag.install +++ b/flag.install @@ -250,10 +250,10 @@ function flag_schema() { 'primary key' => array('fcid'), 'unique keys' => array( 'fid_content_id_uid_sid' => array('fid', 'content_id', 'uid', 'sid'), - 'content_type_content_id_uid_sid' => array('content_type', 'content_id', 'uid', 'sid'), ), 'indexes' => array( 'content_type_uid_sid' => array('content_type', 'uid', 'sid'), + 'content_type_content_id_uid_sid' => array('content_type', 'content_id', 'uid', 'sid'), ), ); @@ -408,6 +408,23 @@ function flag_update_6204() { * Provide a better index on the flag_content table including 'uid' and 'sid'. */ function flag_update_6205() { - db_drop_index('flag_content', 'content_type_content_id'); - db_add_unique_key('flag_content', 'content_type_content_id_uid_sid', array('content_type', 'content_id', 'uid', 'sid')); + // This update has been removed and corrected in flag_update_6206. + // See http://drupal.org/node/1105490. +} + +/** + * Correction to flag_update_6205(). Convert unique key to an index. + */ +function flag_update_6206() { + // Remove the old index that did not include UID or SID. + if (db_index_exists('flag_content', 'content_type_content_id')) { + db_drop_index('flag_content', 'content_type_content_id'); + } + + // Remove the erroneous unique key that was added in flag_update_6205(). + if (db_index_exists('flag_content', 'content_type_content_id_uid_sid')) { + db_drop_unique_key('flag_content', 'content_type_content_id_uid_sid'); + } + + db_add_index('flag_content', 'content_type_content_id_uid_sid', array('content_type', 'content_id', 'uid', 'sid')); } From 1dc8d5fda04d42fea6fa44b488b72f0dbf47ba74 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 24 Sep 2011 22:04:08 -0700 Subject: [PATCH 029/629] Issue #652558 by jaydub: Add last_updated timestamp when updating count in flag_counts_table. --- flag.inc | 3 ++- flag.install | 16 ++++++++++++++++ includes/flag.views.inc | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/flag.inc b/flag.inc index 4535713..60425a8 100644 --- a/flag.inc +++ b/flag.inc @@ -771,7 +771,8 @@ class flag_flag { ->key(array('fid' => $this->fid, 'content_id' => $content_id)) ->fields(array( 'content_type' => $this->content_type, - 'count' => $count + 'count' => $count, + 'last_updated' => REQUEST_TIME, )) ->execute(); } diff --git a/flag.install b/flag.install index a85e705..8f7539f 100644 --- a/flag.install +++ b/flag.install @@ -313,6 +313,14 @@ function flag_schema() { 'not null' => TRUE, 'default' => 0, 'disp-width' => '10', + ), + 'last_updated' => array( + 'description' => 'The UNIX time stamp representing when the flag was last updated.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'disp-size' => 11, ) ), 'primary key' => array('fid', 'content_id'), @@ -320,6 +328,7 @@ function flag_schema() { 'fid_content_type' => array('fid', 'content_type'), 'content_type_content_id' => array('content_type', 'content_id'), 'count' => array('count'), + 'last_updated' => array('last_updated'), ), ); @@ -428,3 +437,10 @@ function flag_update_6206() { db_add_index('flag_content', 'content_type_content_id_uid_sid', array('content_type', 'content_id', 'uid', 'sid')); } + +/** + * Adds column last_updated to flag_counts table. + */ +function flag_update_6207() { + db_add_field('flag_counts', 'last_updated', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'disp-size' => 11), array('indexes' => array('last_updated' => array('last_updated')))); +} diff --git a/includes/flag.views.inc b/includes/flag.views.inc index 02fa5bb..b5522a9 100644 --- a/includes/flag.views.inc +++ b/includes/flag.views.inc @@ -147,6 +147,24 @@ function flag_views_data() { ), ); + $data['flag_counts']['last_updated'] = array( + 'title' => t('Time last flagged'), + 'help' => t('The time a piece of content was most recently flagged by any user.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_date', + ), + ); + return $data; } From 78852411e643a13e36473faeed6c05c922a8dcf3 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 24 Sep 2011 22:39:32 -0700 Subject: [PATCH 030/629] Issue #928634 by jaydub: Deleting a user doesn't remove flags on that user from flag_content and flag_counts tables. --- flag.module | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/flag.module b/flag.module index 0ede96e..228c3ab 100644 --- a/flag.module +++ b/flag.module @@ -639,6 +639,17 @@ function flag_user_account_removal($account) { db_delete('flag_content') ->condition('uid', $account->uid) ->execute(); + + // Remove flags that have been done to this user. + db_delete('flag_content') + ->condition('content_type', 'user') + ->condition('content_id', $account->uid) + ->execute(); + + db_delete('flag_counts') + ->condition('content_type', 'user') + ->condition('content_id', $account->uid) + ->execute(); } /** From 005664c85b95dba2dee7130cdd7800d82a0f1453 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 24 Sep 2011 22:41:37 -0700 Subject: [PATCH 031/629] Issue #1277124 by ericduran: Pass the $link variable in the $variables array for other modules. --- flag.module | 1 + 1 file changed, 1 insertion(+) diff --git a/flag.module b/flag.module index 228c3ab..6f65b81 100644 --- a/flag.module +++ b/flag.module @@ -1228,6 +1228,7 @@ function template_preprocess_flag(&$variables) { $initialized[$link_type['name']] = TRUE; } + $variables['link'] = $link; $variables['link_href'] = isset($link['href']) ? check_url(url($link['href'], $link)) : FALSE; $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $content_id); $variables['link_title'] = isset($link['attributes']['title']) ? check_plain($link['attributes']['title']) : check_plain(strip_tags($flag->get_label($action . '_long', $content_id))); From f0c5b29d57938d4fb411dbfff436367ebeaccf18 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 24 Sep 2011 22:46:38 -0700 Subject: [PATCH 032/629] Issue #1284556 by hefox: flag_views_default_views returns wrong value when bookmark flag doesn't exist. --- includes/flag.views_default.inc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/includes/flag.views_default.inc b/includes/flag.views_default.inc index 8d17f7c..8be9bd5 100644 --- a/includes/flag.views_default.inc +++ b/includes/flag.views_default.inc @@ -13,7 +13,7 @@ function flag_views_default_views() { // If it's been deleted, don't create any views. $flag = flag_get_flag('bookmarks'); if (!$flag) { - return; + return array(); } // Set up properties that are used for both views. @@ -147,8 +147,6 @@ function flag_views_default_views() { ); } - $views = array(); - /* Individual users user/%/bookmarks tab. */ // Additional relationship for this view. From 87783505a245e5bc5e2f02bc5c0a5ad337d6d9b2 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 24 Sep 2011 22:49:04 -0700 Subject: [PATCH 033/629] Issue #1258764 by trrroy, gagarine, and quicksketch: Flag starts a session on anonymous user loads which is bad for pressflow/varnish. --- flag.inc | 2 +- flag.module | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/flag.inc b/flag.inc index 60425a8..25228e0 100644 --- a/flag.inc +++ b/flag.inc @@ -602,7 +602,7 @@ class flag_flag { $sid = 0; } else { - $sid = flag_get_sid($uid); + $sid = flag_get_sid($uid, TRUE); // Anonymous users must always have a session id. if ($sid == 0 && $account->uid == 0) { return FALSE; diff --git a/flag.module b/flag.module index 6f65b81..a7bef47 100644 --- a/flag.module +++ b/flag.module @@ -178,11 +178,6 @@ function flag_help($path, $arg) { function flag_init() { $path = drupal_get_path('module', 'flag'); include_once $path .'/includes/flag.actions.inc'; - - if (module_exists('session_api')) { - // Set the anonymous user SID immediately, in case the user logs in. - flag_set_sid(); - } } /** @@ -1647,6 +1642,11 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid; $sid = !isset($sid) ? flag_get_sid($uid) : $sid; + // If the user is anonymous and doesn't have a session, return an empty list. + if ($uid == 0 && empty($sid)) { + return array(); + } + if (isset($content_id)) { if (!isset($flagged_content[$uid][$sid][$content_type][$content_id])) { $flag_names = _flag_get_flag_names(); @@ -1803,11 +1803,8 @@ function flag_check_token($token, $content_id) { /** * Set the Session ID for a user. Utilizes the Session API module. - * - * This function is only called in flag_init(), to set the current user's - * SID in case the user logs in during this request. */ -function flag_set_sid($uid = NULL) { +function flag_set_sid($uid = NULL, $create = TRUE) { static $sids = array(); if (!isset($uid)) { @@ -1816,7 +1813,7 @@ function flag_set_sid($uid = NULL) { if (!isset($sids[$uid])) { if (module_exists('session_api') && session_api_available() && $uid == 0) { - $sids[$uid] = session_api_get_sid(); + $sids[$uid] = session_api_get_sid($create); } else { $sids[$uid] = 0; @@ -1828,7 +1825,14 @@ function flag_set_sid($uid = NULL) { /** * Get the Session ID for a user. Utilizes the Session API module. + * + * @param $uid + * The user ID. If the UID is 0 (anonymous users), then a SID will be + * returned. SID will always be 0 for any authenticated user. + * @param $create + * If the user doesn't yet have a session, should one be created? Defaults + * to FALSE. */ -function flag_get_sid($uid = NULL) { - return flag_set_sid($uid); +function flag_get_sid($uid = NULL, $create = FALSE) { + return flag_set_sid($uid, $create); } From 878cfe887c2abdd5e18f9a63bb4545fe38e11f4a Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 25 Sep 2011 21:33:58 -0700 Subject: [PATCH 034/629] Issue #719616 by andrewlevine, dereine, ralf.strobel, and quicksketch: Keep flag_counts current by manual in/decreasing of count. --- flag.inc | 64 ++++++++++++++++++++++++++++++++++++----------------- flag.module | 24 +++++++++++--------- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/flag.inc b/flag.inc index 25228e0..7da1af7 100644 --- a/flag.inc +++ b/flag.inc @@ -721,7 +721,7 @@ class flag_flag { 'timestamp' => REQUEST_TIME, )) ->execute(); - $this->_update_count($content_id); + $this->_increase_count($content_id); return $fcid; } @@ -748,34 +748,58 @@ class flag_flag { ->fetchField(); if ($fcid) { db_delete('flag_content')->condition('fcid', $fcid)->execute(); - $this->_update_count($content_id); + $this->_decrease_count($content_id); } return $fcid; } /** - * Updates the flag count for this content + * Increases the flag count for a piece of content. + * + * @param $content_id + * For which item should the count be increased. + * @param $number + * The amount of counts to increasing. Defaults to 1. * * @private - */ - function _update_count($content_id) { - $count = db_select('flag_content', 'fc')->fields('fc', array('fcid')) + */ + function _increase_count($content_id, $number = 1) { + db_merge('flag_counts') + ->key(array( + 'fid' => $this->fid, + 'content_id' => $content_id, + )) + ->fields(array( + 'content_type' => $this->content_type, + 'count' => $number, + )) + ->expression('count', 'count + :inc', array(':inc' => $number)) + ->execute(); + } + + /** + * Decreases the flag count for a piece of content. + * + * @param $content_id + * For which item should the count be descreased. + * @param $number + * The amount of counts to decrease. Defaults to 1. + * + * @private + */ + function _decrease_count($content_id, $number = 1) { + db_update('flag_counts') + ->expression('count', 'count - :inc', array(':inc' => $number)) ->condition('fid', $this->fid) ->condition('content_id', $content_id) - ->countQuery()->execute()->fetchField(); - if ($count == 0) { - db_delete('flag_counts')->condition('fid', $this->fid)->condition('content_id', $content_id)->execute(); - } - else { - db_merge('flag_counts') - ->key(array('fid' => $this->fid, 'content_id' => $content_id)) - ->fields(array( - 'content_type' => $this->content_type, - 'count' => $count, - 'last_updated' => REQUEST_TIME, - )) - ->execute(); - } + ->execute(); + + // Delete rows with count 0, for data consistency and space-saving. + db_delete('flag_counts') + ->condition('fid', $this->fid) + ->condition('content_id', $content_id) + ->condition('count', 0) + ->execute(); } /** diff --git a/flag.module b/flag.module index a7bef47..11f8d1d 100644 --- a/flag.module +++ b/flag.module @@ -557,15 +557,16 @@ function flag_user_login(&$edit, &$account) { // Migrate anonymous flags to this user's account. if (module_exists('session_api') && ($sid = flag_get_sid(0))) { // Get a list of flag_content IDs that will be moved over. - $fcids = db_select('flag_content', 'fc') - ->fields('fc', array('fcid')) + $duplicate_flaggings = array(); + $flaggings = db_select('flag_content', 'fc') + ->fields('fc', array('fcid', 'fid', 'content_id')) ->condition('uid', 0) ->condition('sid', $sid) ->execute() - ->fetchCol('fcid'); + ->fetchAllAssoc('fcid', PDO::FETCH_ASSOC); // Convert anonymous flaggings to their authenticated account. - foreach ($fcids as $fcid) { + foreach ($flaggings as $fcid => $flagging) { // Each update is wrapped in a try block to prevent unique key errors. // Any duplicate content that was flagged as anonoymous is deleted in the // subsequent db_delete() call. @@ -579,15 +580,18 @@ function flag_user_login(&$edit, &$account) { ->execute(); } catch (Exception $e) { - NULL; + $duplicate_flaggings[$fcid] = $flagging; } } - // Delete any remaining flags this user had as an anonymous user. - db_delete('flag_content') - ->condition('uid', 0) - ->condition('sid', $sid) - ->execute(); + // Delete any remaining flags this user had as an anonymous user. We use the + // proper unflag action here to make sure the count gets decremented again + // and so that other modules can clean up their tables if needed. + $anonymous_user = drupal_anonymous_user(); + foreach ($duplicate_flaggings as $fcid => $flagging) { + $flag = flag_get_flag(NULL, $flagging['fid']); + $flag->flag('unflag', $flagging['content_id'], $anonymous_user, TRUE); + } // Clean up anonymous cookies. FlagCookieStorage::drop(); From 26c36bce9e126d760e55ca4d7e76db69c4cafe75 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 25 Sep 2011 22:39:05 -0700 Subject: [PATCH 035/629] Issue #1217314: Fix flag_count indexes to add fid to "count" and "last_updated". --- flag.install | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/flag.install b/flag.install index 8f7539f..2571afb 100644 --- a/flag.install +++ b/flag.install @@ -327,8 +327,8 @@ function flag_schema() { 'indexes' => array( 'fid_content_type' => array('fid', 'content_type'), 'content_type_content_id' => array('content_type', 'content_id'), - 'count' => array('count'), - 'last_updated' => array('last_updated'), + 'fid_count' => array('fid', 'count'), + 'fid_last_updated' => array('fid', 'last_updated'), ), ); @@ -444,3 +444,14 @@ function flag_update_6206() { function flag_update_6207() { db_add_field('flag_counts', 'last_updated', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'disp-size' => 11), array('indexes' => array('last_updated' => array('last_updated')))); } + +/** + * Convert flag_count indexes to include FID for more efficient indexing. + */ +function flag_update_6208() { + db_drop_index('flag_counts', 'count'); + db_drop_index('flag_counts', 'last_updated'); + + db_add_index('flag_counts', 'fid_count', array('fid', 'count')); + db_add_index('flag_counts', 'fid_last_updated', array('fid', 'last_updated')); +} From 41e913a0ed58bda1ce6a9bf57b7657d2e42182a0 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 25 Sep 2011 23:23:24 -0700 Subject: [PATCH 036/629] Issue #719616 by ralf.strobel: Fix to keep flag_counts current by manual in/decreasing of count. --- flag.inc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/flag.inc b/flag.inc index 7da1af7..821343f 100644 --- a/flag.inc +++ b/flag.inc @@ -788,17 +788,18 @@ class flag_flag { * @private */ function _decrease_count($content_id, $number = 1) { - db_update('flag_counts') - ->expression('count', 'count - :inc', array(':inc' => $number)) + // Delete rows with count 0, for data consistency and space-saving. + $deleted = db_delete('flag_counts') ->condition('fid', $this->fid) ->condition('content_id', $content_id) + ->condition('count', $number, '<=') ->execute(); - // Delete rows with count 0, for data consistency and space-saving. - db_delete('flag_counts') + // Update the count with the new value otherwise. + db_update('flag_counts') + ->expression('count', 'count + :inc', array(':inc' => $number)) ->condition('fid', $this->fid) ->condition('content_id', $content_id) - ->condition('count', 0) ->execute(); } From 5cd55a5a70b0fa7e7a84142a8806b32755b48670 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Mon, 26 Sep 2011 13:54:40 -0700 Subject: [PATCH 037/629] #719616 by ralf.strobel: Code cleanup and additional docs to the _decrement_count() method. --- flag.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flag.inc b/flag.inc index 821343f..1f73c78 100644 --- a/flag.inc +++ b/flag.inc @@ -789,7 +789,8 @@ class flag_flag { */ function _decrease_count($content_id, $number = 1) { // Delete rows with count 0, for data consistency and space-saving. - $deleted = db_delete('flag_counts') + // Done before the db_update() to prevent out-of-bounds errors on "count". + db_delete('flag_counts') ->condition('fid', $this->fid) ->condition('content_id', $content_id) ->condition('count', $number, '<=') From 46a07670044170c772101aecc0eb117534f717ad Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 1 Oct 2011 21:56:27 -0700 Subject: [PATCH 038/629] Issue #1296364 by twistor and quicksketch: Tests broken and setUp should be declared static. --- tests/flag.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/flag.test b/tests/flag.test index bcacc9a..1bd85f0 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -6,7 +6,7 @@ class FlagTestCase extends DrupalWebTestCase { /** * Implementation of getInfo(). */ - function getInfo() { + public static function getInfo() { return array( 'name' => t('Flag tests'), 'description' => t('Add, edit and delete flags.'), @@ -53,7 +53,7 @@ class FlagTestCase extends DrupalWebTestCase { $saved['types'] = array('page'); unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); - $this->drupalPost(FLAG_ADMIN_PATH . '/add/node/' . $edit['name'], $edit, t('Submit')); + $this->drupalPost(FLAG_ADMIN_PATH . '/add/node/' . $edit['name'], $edit, t('Save flag')); flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); @@ -90,7 +90,7 @@ class FlagTestCase extends DrupalWebTestCase { $saved['types'] = array('article'); unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); - $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name, $edit, t('Submit')); + $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name, $edit, t('Save flag')); flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); @@ -113,7 +113,7 @@ class FlagTestCase extends DrupalWebTestCase { * Test that only allowed users have access to flags. */ function testFlagAccess() { - + } } From 2344c0d14ece98a62f963f141a78fb69d7122e50 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sat, 1 Oct 2011 23:21:52 -0700 Subject: [PATCH 039/629] Issue #719616: Include last_updated count when incrementing or decrementing counts. --- flag.inc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/flag.inc b/flag.inc index 1f73c78..0b4fa52 100644 --- a/flag.inc +++ b/flag.inc @@ -772,6 +772,10 @@ class flag_flag { ->fields(array( 'content_type' => $this->content_type, 'count' => $number, + 'last_updated' => REQUEST_TIME, + )) + ->updateFields(array( + 'last_updated' => REQUEST_TIME, )) ->expression('count', 'count + :inc', array(':inc' => $number)) ->execute(); @@ -798,7 +802,10 @@ class flag_flag { // Update the count with the new value otherwise. db_update('flag_counts') - ->expression('count', 'count + :inc', array(':inc' => $number)) + ->expression('count', 'count - :inc', array(':inc' => $number)) + ->fields(array( + 'last_updated' => REQUEST_TIME, + )) ->condition('fid', $this->fid) ->condition('content_id', $content_id) ->execute(); From ef83279bd87e7bd50c273c8f050cc4c0def1be8d Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Mon, 3 Oct 2011 11:45:25 -0700 Subject: [PATCH 040/629] Issue #1258764: Bug fix to make global flagging work again after changes to anonymous session handling broke it. --- flag.module | 5 ----- 1 file changed, 5 deletions(-) diff --git a/flag.module b/flag.module index 11f8d1d..98b06d4 100644 --- a/flag.module +++ b/flag.module @@ -1646,11 +1646,6 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid; $sid = !isset($sid) ? flag_get_sid($uid) : $sid; - // If the user is anonymous and doesn't have a session, return an empty list. - if ($uid == 0 && empty($sid)) { - return array(); - } - if (isset($content_id)) { if (!isset($flagged_content[$uid][$sid][$content_type][$content_id])) { $flag_names = _flag_get_flag_names(); From e6b6c9a5f461ce5b4509d741d2361dbaaba33c07 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Mon, 3 Oct 2011 11:59:46 -0700 Subject: [PATCH 041/629] Issue #1298274: Flag's default CSS under Bartik doesn't align flagged messages correctly. --- theme/flag.css | 1 + 1 file changed, 1 insertion(+) diff --git a/theme/flag.css b/theme/flag.css index 6668658..d069869 100644 --- a/theme/flag.css +++ b/theme/flag.css @@ -4,6 +4,7 @@ top: 1.7em; line-height: normal; left: 0; + text-align: left; width: 300px; font-size: .8em; } From 213182ce6fa41dbe3da2496fc908b0d9efd1d657 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 16 Oct 2011 21:45:04 -0400 Subject: [PATCH 042/629] Issue #1300676: Update Flag to be Coder compliant and follow code standards throughout. --- flag.inc | 4 +- flag.install | 10 ++--- flag.module | 30 +++++++------- flag.rules.inc | 52 ++++++++++++------------- flag.tokens.inc | 8 ++-- flag_actions.install | 6 +-- flag_actions.module | 6 +-- includes/flag.actions.inc | 16 ++++---- includes/flag.admin.inc | 4 +- includes/flag.export.inc | 4 +- includes/flag.features.inc | 10 ++--- includes/flag.views.inc | 10 ++--- includes/flag.views_convert.inc | 11 +++--- includes/flag.views_default.inc | 6 +-- includes/flag_handler_relationships.inc | 6 +-- tests/flag.test | 9 ++++- 16 files changed, 99 insertions(+), 93 deletions(-) diff --git a/flag.inc b/flag.inc index 0b4fa52..453b119 100644 --- a/flag.inc +++ b/flag.inc @@ -506,7 +506,7 @@ class flag_flag { } /** - * An implementation of access() implemented by each child class. + * Implements access() implemented by each child class. * * @abstract */ @@ -515,7 +515,7 @@ class flag_flag { } /** - * An implementation of access_multiple() implemented by each child class. + * Implements access_multiple() implemented by each child class. * * @abstract */ diff --git a/flag.install b/flag.install index 2571afb..f81b70d 100644 --- a/flag.install +++ b/flag.install @@ -12,7 +12,7 @@ function flag_install() { } /** - * Implementation of hook_uninstall(). + * Implements hook_uninstall(). */ function flag_uninstall() { $result = db_select('variable', 'v') @@ -27,14 +27,14 @@ function flag_uninstall() { } /** - * Implementation of hook_enable(). + * Implements hook_enable(). * * We create the demonstration flag on enable, so hook implementations in flag * module will fire correctly, as the APIs are not available on install. */ function flag_enable() { // Load the flag API in case we want to use it when enabling. - include_once(drupal_get_path('module', 'flag') .'/flag.module'); + include_once(drupal_get_path('module', 'flag') . '/flag.module'); if (!flag_get_flags()) { // Install a demonstration flag only if no flag exists. This is to prevent @@ -78,7 +78,7 @@ function _flag_install_get_suggested_node_types() { } /** - * Implementation of hook_requirements(). + * Implements hook_requirements(). * * Prevent installing this module if the "Flag content" module is installed as well. */ @@ -138,7 +138,7 @@ function _flag_flag_content_message() { } /** - * Implementation of hook_schema(). + * Implements hook_schema(). */ function flag_schema() { $schema = array(); diff --git a/flag.module b/flag.module index 98b06d4..0d18ff5 100644 --- a/flag.module +++ b/flag.module @@ -10,7 +10,7 @@ define('FLAG_API_VERSION', 2); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); -include_once dirname(__FILE__) .'/flag.inc'; +include_once dirname(__FILE__) . '/flag.inc'; /** * Implements hook_menu(). @@ -177,7 +177,7 @@ function flag_help($path, $arg) { */ function flag_init() { $path = drupal_get_path('module', 'flag'); - include_once $path .'/includes/flag.actions.inc'; + include_once $path . '/includes/flag.actions.inc'; } /** @@ -247,7 +247,7 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { // The flag links are actually fully rendered theme functions. // The HTML attribute is set to TRUE to allow whatever the themer desires. - $links['flag-'. $flag->name] = array( + $links['flag-' . $flag->name] = array( 'title' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id), 'html' => TRUE, ); @@ -278,7 +278,7 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { function flag_flag_link($flag, $action, $content_id) { $token = flag_get_token($content_id); return array( - 'href' => 'flag/'. ($flag->link_type == 'confirm' ? 'confirm/' : '') ."$action/$flag->name/$content_id", + 'href' => 'flag/' . ($flag->link_type == 'confirm' ? 'confirm/' : '') . "$action/$flag->name/$content_id", 'query' => drupal_get_destination() + ($flag->link_type == 'confirm' ? array() : array('token' => $token)), ); } @@ -352,11 +352,11 @@ function flag_form_alter(&$form, &$form_state, $form_id) { $flags = flag_get_flags('node', $form['#node_type']->type, $user); foreach ($flags as $flag) { if ($flag->show_on_form) { - $var = 'flag_'. $flag->name .'_default'; + $var = 'flag_' . $flag->name . '_default'; $form['workflow']['flag'][$var] = array( '#type' => 'checkbox', '#title' => $flag->get_label('flag_short', $form['#node_type']->type), - '#default_value' => variable_get($var .'_'. $form['#node_type']->type, 0), + '#default_value' => variable_get($var . '_' . $form['#node_type']->type, 0), '#return_value' => 1, ); } @@ -373,7 +373,7 @@ function flag_form_alter(&$form, &$form_state, $form_id) { ); } } - elseif (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] .'_node_form')) { + elseif (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] . '_node_form')) { $nid = !empty($form['nid']['#value']) ? $form['nid']['#value'] : NULL; $flags = flag_get_flags('node', $form['type']['#value'], $user); @@ -662,7 +662,7 @@ function flag_user_view($account, $view_mode) { // User has no permission to use this flag. continue; } - if (!$flag->uses_hook_link(array())){ + if (!$flag->uses_hook_link(array())) { // Flag not set to appear on profile. continue; } @@ -809,9 +809,9 @@ function flag_confirm($form, &$form_state, $action, $flag, $content_id) { '#value' => $content_id, ); - $question = $flag->get_label($action .'_confirmation', $content_id); + $question = $flag->get_label($action . '_confirmation', $content_id); $path = isset($_GET['destination']) ? $_GET['destination'] : ''; - $yes = $flag->get_label($action .'_short', $content_id); + $yes = $flag->get_label($action . '_short', $content_id); return confirm_form($form, $question, $path, '', $yes); } @@ -1120,8 +1120,8 @@ function flag_user_operations() { return $operations; } /** -* Callback function for hook_user_operations(). -*/ + * Callback function for hook_user_operations(). + */ function flag_users($users, $action, $flag_name) { foreach ($users as $uid) { flag($action, $flag_name, $uid); @@ -1144,7 +1144,7 @@ function flag_mail($key, &$message, $params) { * Implements hook_theme(). */ function flag_theme() { - $path = drupal_get_path('module', 'flag') .'/theme'; + $path = drupal_get_path('module', 'flag') . '/theme'; return array( 'flag' => array( @@ -1242,8 +1242,8 @@ function template_preprocess_flag(&$variables) { $variables['flag_classes_array'] = array(); $variables['flag_classes_array'][] = 'flag'; - $variables['flag_classes_array'][] = $variables['action'] .'-action'; - $variables['flag_classes_array'][] = 'flag-link-'. $flag->link_type; + $variables['flag_classes_array'][] = $variables['action'] . '-action'; + $variables['flag_classes_array'][] = 'flag-link-' . $flag->link_type; if (isset($link['attributes']['class'])) { $variables['flag_classes_array'][] = $link['attributes']['class']; } diff --git a/flag.rules.inc b/flag.rules.inc index 10d2976..f7cd84e 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -1,7 +1,7 @@ array( + 'flag_flag' . $type => array( 'label' => t('Flag a @type', array('@type' => $type)), 'base' => 'flag_rules_action_flag', 'parameter' => array( @@ -212,7 +212,7 @@ function flag_rules_action_info() { 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), - 'flag_unflag'. $type => array( + 'flag_unflag' . $type => array( 'label' => t('Unflag a @type', array('@type' => $type)), 'base' => 'flag_rules_action_unflag', 'parameter' => array( @@ -305,7 +305,7 @@ function flag_rules_condition_info() { $entity_info = entity_get_info($type); $label = isset($entity_info[$type]['label']) ? $entity_info[$type]['label'] : $type; $items += array( - 'flag_threshold_'. $type => array( + 'flag_threshold_' . $type => array( 'label' => drupal_ucfirst(t('@type has flagging count', array('@type' => $label))), 'base' => 'flag_rules_condition_threshold', 'parameter' => array( @@ -315,28 +315,28 @@ function flag_rules_condition_info() { 'flag_type' => $type, 'description' => t('The flag to check for.') ), - $type => array( - 'type' => $type, - 'label' => $label, - ), - 'number' => array( - 'type' => 'integer', - 'label' => t('Number'), - 'description' => t('The number against which to test the number of times the object is flagged. For example, if you type "3" here, and choose "Greater than" for the operator, then this condition will return TRUE if the object is flagged more than three times.'), - ), - 'operator' => array( - 'type' => 'text', - 'label' => t('Comparison operator'), - 'options list' => 'flag_rules_condition_threshold_operator_options', - 'restriction' => 'input', - 'default value' => '=', - 'optional' => TRUE, - ), + $type => array( + 'type' => $type, + 'label' => $label, + ), + 'number' => array( + 'type' => 'integer', + 'label' => t('Number'), + 'description' => t('The number against which to test the number of times the object is flagged. For example, if you type "3" here, and choose "Greater than" for the operator, then this condition will return TRUE if the object is flagged more than three times.'), + ), + 'operator' => array( + 'type' => 'text', + 'label' => t('Comparison operator'), + 'options list' => 'flag_rules_condition_threshold_operator_options', + 'restriction' => 'input', + 'default value' => '=', + 'optional' => TRUE, + ), ), 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), - 'flag_flagged_'. $type => array( + 'flag_flagged_' . $type => array( 'label' => drupal_ucfirst(t('@type is flagged', array('@type' => $label))), 'base' => 'flag_rules_condition_flagged', 'parameter' => array( @@ -346,10 +346,10 @@ function flag_rules_condition_info() { 'flag_type' => $type, 'description' => t('The flag to check for.') ), - $type => array( - 'type' => $type, - 'label' => $label, - ), + $type => array( + 'type' => $type, + 'label' => $label, + ), 'user' => array( 'type' => 'user', 'label' => t('User on whose behalf to check'), diff --git a/flag.tokens.inc b/flag.tokens.inc index 2b9eb6e..e6707cf 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -62,11 +62,11 @@ function flag_token_info() { foreach (flag_get_types() as $flag_type) { $flags = flag_get_flags($flag_type); foreach ($flags as $flag) { - $tokens[$flag_type]['flag-'. str_replace('_', '-', $flag->name) .'-count'] = array( + $tokens[$flag_type]['flag-' . str_replace('_', '-', $flag->name) . '-count'] = array( 'name' => t('@flag flag count', array('@flag' => $flag->get_title())), 'description' => t('Total flag count for flag @flag', array('@flag' => $flag->get_title())), ); - $tokens[$flag_type]['flag-'. str_replace('_', '-', $flag->name) .'-link'] = array( + $tokens[$flag_type]['flag-' . str_replace('_', '-', $flag->name) . '-link'] = array( 'name' => t('@flag flag link', array('@flag' => $flag->get_title())), 'description' => t('Flag/unflag link for @flag', array('@flag' => $flag->get_title())), ); @@ -130,8 +130,8 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr $object = $data[$type]; foreach ($flags as $flag) { foreach ($tokens as $name => $original) { - $flag_count_token = 'flag-'. str_replace('_', '-', $flag->name) .'-count'; - $flag_link_token = 'flag-'. str_replace('_', '-', $flag->name) .'-link'; + $flag_count_token = 'flag-' . str_replace('_', '-', $flag->name) . '-count'; + $flag_link_token = 'flag-' . str_replace('_', '-', $flag->name) . '-link'; if ($name == $flag_count_token) { $replacements[$original] = $flag->get_count($flag->get_content_id($object)); } diff --git a/flag_actions.install b/flag_actions.install index 8a37657..5124393 100644 --- a/flag_actions.install +++ b/flag_actions.install @@ -6,19 +6,19 @@ */ /** - * Implementation of hook_install(). + * Implements hook_install(). */ function flag_actions_install() { } /** - * Implementation of hook_uninstall(). + * Implements hook_uninstall(). */ function flag_actions_uninstall() { } /** - * Implementation of hook_schema(). + * Implements hook_schema(). */ function flag_actions_schema() { $schema = array(); diff --git a/flag_actions.module b/flag_actions.module index 6a20555..6a06880 100644 --- a/flag_actions.module +++ b/flag_actions.module @@ -6,14 +6,14 @@ */ /** - * Implementation of hook_flag(). Trigger actions if any are available. + * Implements hook_flag(). Trigger actions if any are available. */ function flag_actions_flag($event, $flag, $content_id, $account) { flag_actions_do($event, $flag, $content_id, $account); } /** - * Implementation of hook_menu(). + * Implements hook_menu(). */ function flag_actions_menu() { $items = array(); @@ -54,7 +54,7 @@ function flag_actions_menu() { } /** - * Implementation of hook_theme(). + * Implements hook_theme(). */ function flag_actions_theme() { return array( diff --git a/includes/flag.actions.inc b/includes/flag.actions.inc index 61a2d97..4f55529 100644 --- a/includes/flag.actions.inc +++ b/includes/flag.actions.inc @@ -6,7 +6,7 @@ */ /** - * Implementation of hook_trigger_info(). + * Implements hook_trigger_info(). */ function flag_trigger_info() { $hooks = array( @@ -21,15 +21,15 @@ function flag_trigger_info() { ); foreach (flag_get_flags() as $flag) { - $hooks['flag']['flag_flag_'. $flag->name]['label'] = t('A %type has been flagged with %name', array('%type' => $flag->content_type, '%name' => $flag->name)); - $hooks['flag']['flag_unflag_'. $flag->name]['label'] = t('A %type has been unflagged with %name', array('%type' => $flag->content_type, '%name' => $flag->name)); + $hooks['flag']['flag_flag_' . $flag->name]['label'] = t('A %type has been flagged with %name', array('%type' => $flag->content_type, '%name' => $flag->name)); + $hooks['flag']['flag_unflag_' . $flag->name]['label'] = t('A %type has been unflagged with %name', array('%type' => $flag->content_type, '%name' => $flag->name)); } return $hooks; } /** - * Implementation of hook_action_info(). + * Implements hook_action_info(). */ function flag_action_info() { return array( @@ -62,7 +62,7 @@ function flag_action_info() { } /** - * Implementation of hook_action_info_alter(). + * Implements hook_action_info_alter(). * * Enable Flag actions on Node, Comment, and User hooks without * the trigger_unlock.module. @@ -101,7 +101,7 @@ function flag_action_info_alter(&$actions) { } /** - * Implementation of a Drupal action. Flags a node. + * Implements Drupal action. Flags a node. * * Note the first parameter is "object" because it may be a comment or a node. */ @@ -127,7 +127,7 @@ function flag_node_action_submit($form, $form_state) { } /** - * Implementation of a Drupal action. Flags a comment. + * Implements Drupal action. Flags a comment. */ function flag_comment_action(&$comment, $context = array()) { if ($flag = flag_get_flag($context['flag_action']['flag'])) { @@ -151,7 +151,7 @@ function flag_comment_action_submit($form, $form_state) { } /** - * Implementation of a Drupal action. Flags a user. + * Implements Drupal action. Flags a user. */ function flag_user_action(&$user, $context = array()) { if ($flag = flag_get_flag($context['flag_action']['flag'])) { diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 27543a4..cd51eee 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -95,7 +95,7 @@ function theme_flag_admin_listing($variables) { drupal_add_tabledrag('flag-admin-listing-table', 'order', 'sibling', 'flag-weight'); } - $header = array(t('Flag'),t('Weight'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations')); + $header = array(t('Flag'), t('Weight'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations')); $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'flag-admin-listing-table'))); $output .= drupal_render_children($form); @@ -275,7 +275,7 @@ function flag_form($form, &$form_state, $flag) { ); if (!empty($flag->fid)) { - $form['name']['#description'] .= ' '. t('Change this value only with great care.') .''; + $form['name']['#description'] .= ' ' . t('Change this value only with great care.') . ''; } $form['title'] = array( diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 26ffc0e..d0ea2ec 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -16,7 +16,7 @@ */ function flag_export_flags($flags = array(), $module = '', $indent = '') { module_load_include('inc', 'features', 'features.export'); // For features_var_export() (optional). - $output = $indent . '$flags = array();'. "\n"; + $output = $indent . '$flags = array();' . "\n"; foreach ($flags as $item) { if (is_object($item)) { $flag = $item; @@ -52,7 +52,7 @@ function flag_export_flags($flags = array(), $module = '', $indent = '') { // The name is emitted as the key for the array. unset($new_flag['name']); - $output .= $indent . '// Exported flag: "'. check_plain($flag->get_title()) . '"' . ".\n"; + $output .= $indent . '// Exported flag: "' . check_plain($flag->get_title()) . '"' . ".\n"; $output .= $indent . '$flags[\'' . $flag->name . '\'] = ' . (function_exists('features_var_export') ? features_var_export($new_flag, $indent) : var_export($new_flag, TRUE)) . ";\n"; } $output .= $indent . 'return $flags;'; diff --git a/includes/flag.features.inc b/includes/flag.features.inc index eff1081..b80cccb 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -6,7 +6,7 @@ */ /** - * Implementation of hook_features_export(). + * Implements hook_features_export(). */ function flag_features_export($data, &$export, $module_name = '') { $pipe = array(); @@ -29,20 +29,20 @@ function flag_features_export($data, &$export, $module_name = '') { } /** - * Implementation of hook_features_export_options(). + * Implements hook_features_export_options(). */ function flag_features_export_options() { $options = array(); // Get all flags, including disabled defaults. $flags = flag_get_flags() + flag_get_default_flags(TRUE); foreach ($flags as $name => $flag) { - $options[$name] = ucfirst(check_plain($flag->content_type)) .': '. check_plain($flag->title); + $options[$name] = drupal_ucfirst(check_plain($flag->content_type)) . ': ' . check_plain($flag->title); } return $options; } /** - * Implementation of hook_features_export_render(). + * Implements hook_features_export_render(). */ function flag_features_export_render($module, $data) { module_load_include('inc', 'flag', '/includes/flag.export'); @@ -51,7 +51,7 @@ function flag_features_export_render($module, $data) { } /** - * Implementation of hook_features_revert(). + * Implements hook_features_revert(). * * @param $module * The name of module for which to revert content. diff --git a/includes/flag.views.inc b/includes/flag.views.inc index b5522a9..3dd6df0 100644 --- a/includes/flag.views.inc +++ b/includes/flag.views.inc @@ -6,7 +6,7 @@ */ /** - * Implementation of hook_views_handlers(). + * Implements hook_views_handlers(). */ function flag_views_handlers() { return array( @@ -40,7 +40,7 @@ function flag_views_handlers() { } /** - * Implementation of hook_views_plugins(). + * Implements hook_views_plugins(). */ function flag_views_plugins() { return array( @@ -64,7 +64,7 @@ function flag_views_plugins() { ); } /** - * Implementation of hook_views_data(). + * Implements hook_views_data(). */ function flag_views_data() { $data = array(); @@ -169,7 +169,7 @@ function flag_views_data() { } /** - * Implementation of hook_views_data_alter(). + * Implements hook_views_data_alter(). */ function flag_views_data_alter(&$data) { @@ -177,7 +177,7 @@ function flag_views_data_alter(&$data) { $flag = flag_flag::factory_by_content_type($flag_type); $info = $flag->get_views_info(); - if(!empty($info['join field'])) { + if (!empty($info['join field'])) { // Add the flag relationship. $data[$info['views table']]['flag_content_rel'] = array( 'group' => t('Flags'), diff --git a/includes/flag.views_convert.inc b/includes/flag.views_convert.inc index 4cc815d..d7e0d07 100644 --- a/includes/flag.views_convert.inc +++ b/includes/flag.views_convert.inc @@ -1,11 +1,12 @@ add_item() won't produce @@ -23,10 +24,10 @@ function flag_views_convert($display, $type, &$view, $field, $id) { ); foreach ($field as $property => $value) { foreach ($key_search as $search => $replace) { - if (!empty($value) && is_string($value) && preg_match('/'. $search .'/', $value, $matches)) { + if (!empty($value) && is_string($value) && preg_match('/' . $search . '/', $value, $matches)) { $flag = flag_get_flag(NULL, $matches[1]); $replace = $replace . $flag->name; - $field[$property] = preg_replace('/'. $search .'/', $replace, $value); + $field[$property] = preg_replace('/' . $search . '/', $replace, $value); } } } @@ -188,7 +189,7 @@ function flag_views_convert($display, $type, &$view, $field, $id) { } elseif ($new_rel == 'flag_counts_rel') { $view->display[$display]->display_options['relationships'][$new_rel] = array( - 'label' => $flag_name .' counts', + 'label' => $flag_name . ' counts', 'required' => 0, 'flag' => $flag_name, 'id' => 'flag_counts_rel', @@ -199,7 +200,7 @@ function flag_views_convert($display, $type, &$view, $field, $id) { } elseif ($new_rel == 'uid') { $view->display[$display]->display_options['relationships'][$new_rel] = array( - 'label' => isset($flag_name) ? $flag_name .' user' : 'user', + 'label' => isset($flag_name) ? $flag_name . ' user' : 'user', 'required' => 0, 'id' => 'uid', 'table' => 'flag_content', diff --git a/includes/flag.views_default.inc b/includes/flag.views_default.inc index 8be9bd5..f57a916 100644 --- a/includes/flag.views_default.inc +++ b/includes/flag.views_default.inc @@ -6,7 +6,7 @@ */ /** - * Implementation of hook_views_default_views(). + * Implements hook_views_default_views(). */ function flag_views_default_views() { // Only setup views for the "bookmarks" flag. @@ -246,7 +246,7 @@ function flag_views_default_views() { ); $view = new view; - $view->name = 'flag_'. $flag->name; + $view->name = 'flag_' . $flag->name; $view->description = 'A page listing the current user\'s bookmarks at /bookmarks.'; $view->tag = 'flag'; $view->view_php = ''; @@ -262,7 +262,7 @@ function flag_views_default_views() { $handler->override_option('title', t('My bookmarks')); $handler->override_option('items_per_page', '25'); $handler->override_option('use_pager', TRUE); - $handler->override_option('empty', 'You have not yet bookmarked any content. Click the "'. $flag->flag_short .'" link when viewing a piece of content to add it to this list.'); + $handler->override_option('empty', 'You have not yet bookmarked any content. Click the "' . $flag->flag_short . '" link when viewing a piece of content to add it to this list.'); $handler->override_option('empty_format', filter_fallback_format()); $handler->override_option('style_plugin', 'table'); $handler->override_option('style_options', $style_options); diff --git a/includes/flag_handler_relationships.inc b/includes/flag_handler_relationships.inc index a283042..130542c 100644 --- a/includes/flag_handler_relationships.inc +++ b/includes/flag_handler_relationships.inc @@ -38,7 +38,7 @@ abstract class flag_handler_relationship extends views_handler_relationship { if (!$this->options['flag']) { $errors[] = t('You must pick a flag to use for the relationship "@relationship-name".', $tokens); } - else if (!flag_get_flag($this->options['flag'])) { + elseif (!flag_get_flag($this->options['flag'])) { $errors[] = t('This view is looking for a flag by the name "@flag-name", but there is no such flag. Perhaps it was deleted. Please update the relationship "@relationship-name" in this view to use an existing flag.', $tokens); } return $errors; @@ -92,7 +92,7 @@ class flag_handler_relationship_content extends flag_handler_relationship { function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); $content_type = $this->definition['flag type']; - $form['label']['#description'] .= ' '. t('The name of the selected flag makes a good label.'); + $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); $form['flag'] = flag_views_flag_config_form('radios', $content_type, $this->options['flag']); $form['user_scope'] = array( @@ -234,7 +234,7 @@ class flag_handler_relationship_user_content extends flag_handler_relationship { function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); - $form['label']['#description'] .= ' '. t('Including name of the selected flag helps identify this relationship.'); + $form['label']['#description'] .= ' ' . t('Including name of the selected flag helps identify this relationship.'); $form['flag'] = flag_views_flag_config_form('radios', NULL, $this->options['flag']); $form['flag']['#title'] = t('Flagged'); diff --git a/tests/flag.test b/tests/flag.test index 1bd85f0..4580d7f 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -1,10 +1,15 @@ Date: Mon, 17 Oct 2011 01:37:12 -0400 Subject: [PATCH 043/629] Issue #1139796: Allow hook_flag_link to pass class attribute as an array. --- flag.module | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 0d18ff5..957bb12 100644 --- a/flag.module +++ b/flag.module @@ -1245,7 +1245,8 @@ function template_preprocess_flag(&$variables) { $variables['flag_classes_array'][] = $variables['action'] . '-action'; $variables['flag_classes_array'][] = 'flag-link-' . $flag->link_type; if (isset($link['attributes']['class'])) { - $variables['flag_classes_array'][] = $link['attributes']['class']; + $link['attributes']['class'] = is_string($link['attributes']['class']) ? array_filter(explode(' ', $link['attributes']['class'])) : $link['attributes']['class']; + $variables['flag_classes_array'] = array_merge($variables['flag_classes_array'], $link['attributes']['class']); } if ($variables['after_flagging']) { $inverse_action = ($action == 'flag' ? 'unflag' : 'flag'); From b33c392347e8c698d27bc92f830c7195a8390be0 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Mon, 17 Oct 2011 02:12:44 -0400 Subject: [PATCH 044/629] Issue #1290890: Add hook_flag_definitions_alter() hook. --- flag.inc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/flag.inc b/flag.inc index 453b119..ca27db4 100644 --- a/flag.inc +++ b/flag.inc @@ -39,23 +39,24 @@ function flag_flag_definitions() { * Returns a flag definition. */ function flag_fetch_definition($content_type = NULL) { - static $cache; - if (!isset($cache)) { - $cache = module_invoke_all('flag_definitions'); - if (!isset($cache['node'])) { + static $defintions; + if (!isset($defintions)) { + $defintions = module_invoke_all('flag_definitions'); + drupal_alter('flag_definitions', $defintions); + if (!isset($defintions['node'])) { // We want our API to be available in hook_install, but our module is not // enabled by then, so let's load our implementation directly: - $cache += flag_flag_definitions(); + $defintions += flag_flag_definitions(); } } if (isset($content_type)) { - if (isset($cache[$content_type])) { - return $cache[$content_type]; + if (isset($defintions[$content_type])) { + return $defintions[$content_type]; } } else { - return $cache; + return $defintions; } } From d97949a81ce48c0ba9afcff8a6dd2c55352d4747 Mon Sep 17 00:00:00 2001 From: fago Date: Wed, 14 Mar 2012 10:06:57 +0100 Subject: [PATCH 045/629] Issue #1293132: Fixed setting Rules conditions on user flags. --- flag.install | 7 +++++++ flag.rules.inc | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index f81b70d..687301c 100644 --- a/flag.install +++ b/flag.install @@ -455,3 +455,10 @@ function flag_update_6208() { db_add_index('flag_counts', 'fid_count', array('fid', 'count')); db_add_index('flag_counts', 'fid_last_updated', array('fid', 'last_updated')); } + +/** + * Clear caches. + */ +function flag_update_7201() { + // Do nothing. Update.php is going to clear caches for us. +} diff --git a/flag.rules.inc b/flag.rules.inc index f7cd84e..5103829 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -350,7 +350,7 @@ function flag_rules_condition_info() { 'type' => $type, 'label' => $label, ), - 'user' => array( + 'flagging_user' => array( 'type' => 'user', 'label' => t('User on whose behalf to check'), 'description' => t('For non-global flags, this is the user on whose behalf the flag is checked.'), From faf4128ad7ee9a1319d90b9b93a00ac441002750 Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 20 May 2012 13:42:05 -0500 Subject: [PATCH 046/629] Issue #1484352 by Itangalo: Illegal choice *relationship* in Flag element causes Views contextual filters to fail. --- includes/flag_plugin_argument_validate_flaggability.inc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/includes/flag_plugin_argument_validate_flaggability.inc b/includes/flag_plugin_argument_validate_flaggability.inc index 1efe9af..0cba7ed 100644 --- a/includes/flag_plugin_argument_validate_flaggability.inc +++ b/includes/flag_plugin_argument_validate_flaggability.inc @@ -26,6 +26,11 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v } function options_form(&$form, &$form_state) { + // If there are no flag relationships set, skip this form of validation. + $flags = flag_get_flags($this->flag_type); + if (!$flags) { + return array(); + } $options = $this->flags_options(); $form[$this->_option_name('flag_name')] = array( From 753cf25caf7f3788d4837d7edabf82f2e57bcbbd Mon Sep 17 00:00:00 2001 From: Nathan Haug Date: Sun, 20 May 2012 15:55:31 -0500 Subject: [PATCH 047/629] Issue #1198530 by semiaddict and quicksketch: Use Contextual Links for add/remove commands on teasers. --- flag.inc | 7 +++++++ flag.module | 33 +++++++++++++++++++++++++++++++++ theme/flag.css | 9 +++++++++ 3 files changed, 49 insertions(+) diff --git a/flag.inc b/flag.inc index ca27db4..7d5d7bf 100644 --- a/flag.inc +++ b/flag.inc @@ -1248,6 +1248,7 @@ class flag_node extends flag_flag { 'show_on_page' => TRUE, 'show_on_teaser' => TRUE, 'show_on_form' => FALSE, + 'show_contextual_link' => FALSE, 'access_author' => '', 'i18n' => 0, ); @@ -1301,6 +1302,12 @@ class flag_node extends flag_flag { '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), '#access' => empty($this->locked['show_on_form']), ); + $form['display']['show_contextual_link'] = array( + '#type' => 'checkbox', + '#title' => t('Display in contextual links'), + '#default_value' => $this->show_contextual_link, + '#access' => empty($this->locked['show_contextual_link']) && module_exists('contextual'), + ); } function _load_content($content_id) { diff --git a/flag.module b/flag.module index 957bb12..fb898b3 100644 --- a/flag.module +++ b/flag.module @@ -446,6 +446,39 @@ function flag_form_alter(&$form, &$form_state, $form_id) { } } +/* + * Implements hook_contextual_links_view_alter(). + */ +function flag_contextual_links_view_alter(&$element, $items) { + + // Check if we have a node link to process + if (isset($element['#element']['#node']->nid)) { + $node = $element['#element']['#node']; + + // Get all possible flags for this content-type. + $flags = flag_get_flags('node'); + + foreach ($flags as $name => $flag) { + if (!$flag->show_contextual_link) { + continue; + } + + $content_id = $flag->get_content_id($node); + if (!$flag->access($content_id) && (!$flag->is_flagged($content_id) || !$flag->access($content_id, 'flag'))) { + // User has no permission to use this flag or flag does not apply to this + // content. The link is not skipped if the user has "flag" access but + // not "unflag" access (this way the unflag denied message is shown). + continue; + } + + $element['#links']['flag-'. $name] = array( + 'title' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id), + 'html' => TRUE, + ); + } + } +} + /** * Implements hook_comment_view(). */ diff --git a/theme/flag.css b/theme/flag.css index d069869..610b4b0 100644 --- a/theme/flag.css +++ b/theme/flag.css @@ -13,6 +13,15 @@ position: relative; } +/* Better contextual link support, prevent line wrapping. */ +ul.contextual-links li .flag-wrapper a { + display: inline-block; +} + +ul.contextual-links li .flag-wrapper { + display: block; +} + /* The rest deals with indicating the waiting state. */ .flag-waiting a { From 199e13ab68cc9c309fbb77e391b4c6a5415f7db3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 13 Jul 2012 20:28:10 +0100 Subject: [PATCH 048/629] by joachim: Fixed typo in UI text. --- flag.install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 687301c..cbbc3ce 100644 --- a/flag.install +++ b/flag.install @@ -113,7 +113,7 @@ function flag_requirements($phase) { $requirements['flag_robots'] = array( 'title' => $t('Flag robots.txt problem'), 'severity' => REQUIREMENT_WARNING, - 'description' => $t('Flag module may currently be used with anonymous users, however the robots.txt file does not exlude the "@flag-path" path, which may cause search engines to randomly flag and unflag content when they index the site. It is highly recommended to add "@robots-string" to your robots.txt file (located in the root of your Drupal installation).', array('@flag-path' => $flag_path, '@robots-string' => $robots_string)), + 'description' => $t('Flag module may currently be used with anonymous users, however the robots.txt file does not exclude the "@flag-path" path, which may cause search engines to randomly flag and unflag content when they index the site. It is highly recommended to add "@robots-string" to your robots.txt file (located in the root of your Drupal installation).', array('@flag-path' => $flag_path, '@robots-string' => $robots_string)), 'value' => $t('Search engines flagging content'), ); } From acc331b53645123a49cf5731a9d5e92f39ca3a4a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 13 Jul 2012 21:02:47 +0100 Subject: [PATCH 049/629] Issue #970052, part 1 by joachim: Added api documentation file, not all flags fully documented yet. --- flag.api.php | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 flag.api.php diff --git a/flag.api.php b/flag.api.php new file mode 100644 index 0000000..cb6db90 --- /dev/null +++ b/flag.api.php @@ -0,0 +1,129 @@ + array( + 'title' => t('Nodes'), + 'description' => t("Nodes are a Drupal site's primary content."), + 'handler' => 'flag_node', + ), + ); +} + +/** + * Alter flag type definitions provided by other modules. + * + * @param $definitions + * An array of flag definitions returned by hook_flag_definitions(). + */ +function hook_flag_definitions_alter(&$definitions) { + +} + +/** + * TODO + */ +function hook_flag_options_alter() { + +} + +/** + * Define default flags. + */ +function hook_flag_default_flags() { + +} + +/** + * Allow modules to alter a flag when it is initially loaded. + * + * @see flag_get_flags(). + */ +function hook_flag_alter(&$flag) { + +} + +/** + * Act on a flagging. + * + * @param $op + * The operation being performed: one of 'flag' or 'unflag'. + * @param $flag + * The flag object. + * @param $content_id + * The id of the content (aka entity) the flag is on. + * @param $account + * The user account performing the action. + * @param $fcid + * The id of the flagging in the {flag_content} table. + */ +function hook_flag($op, $flag, $content_id, $account, $fcid) { + +} + +/** + * TODO + */ +function hook_flag_access() { + +} + +/** + * TODO + */ +function hook_flag_access_multiple() { + +} + +/** + * + */ +function hook_flag_link() { + +} + +/** + * TODO + */ +function hook_flag_link_types() { + +} + +/** + * TODO + */ +function flag_delete () { + +} + +/** + * TODO + */ +function hook_flag_reset() { + +} + From bcb051392140b30cc2781d16cec8d041c637f8ee Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 13 Jul 2012 20:42:48 -0500 Subject: [PATCH 050/629] Issue #1402948 by stevector: Use drupal_exit() instead of exit --- flag.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index fb898b3..585e126 100644 --- a/flag.module +++ b/flag.module @@ -792,7 +792,7 @@ function flag_page($action, $flag, $content_id) { 'status' => FALSE, 'errorMessage' => $error, )); - exit; + drupal_exit(); } else { drupal_set_message($error); @@ -814,7 +814,7 @@ function flag_page($action, $flag, $content_id) { 'flagName' => $flag->name, 'flagStatus' => $flag->is_flagged($content_id) ? 'flagged' : 'unflagged', )); - exit; + drupal_exit(); } else { drupal_set_message($flag->get_label($action . '_message', $content_id)); From 54749ea1cf4061ff2409639509729be69b769622 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 14 Jul 2012 19:06:21 +0100 Subject: [PATCH 051/629] Issue #970052, part 2 by joachim: Added further documentation to api.php file. --- flag.api.php | 55 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/flag.api.php b/flag.api.php index cb6db90..65bd13a 100644 --- a/flag.api.php +++ b/flag.api.php @@ -41,14 +41,39 @@ function hook_flag_definitions() { * An array of flag definitions returned by hook_flag_definitions(). */ function hook_flag_definitions_alter(&$definitions) { - + } /** - * TODO + * Define one or more flag link types. + * + * @see flag_get_link_types() + * @see hook_flag_link_types_alter() + * + * @return + * An array of one or more types, keyed by the machine name of the type, and + * where each value is a link type definition as an array with the following + * properties: + * - 'title': The human-readable name of the type. + * - 'description': The description of the link type. + * - 'options': An array of extra options for the link type. + * - 'uses standard js': Boolean, indicates whether the link requires Flag + * module's own JS file for links. + * - 'uses standard css': Boolean, indicates whether the link requires Flag + * module's own CSS file for links. */ -function hook_flag_options_alter() { - +function hook_flag_link_types() { + +} + +/** + * Alter other modules' definitions of flag link types. + * + * @see flag_get_link_types() + * @see hook_flag_link_types() + */ +function hook_flag_link_types_alter(&$link_types) { + } /** @@ -67,6 +92,21 @@ function hook_flag_alter(&$flag) { } +/** + * Alter a flag's default options. + * + * @param $options + * The array of default options for the flag type, with the options for the + * flag's link type merged in. + * @param $flag + * The flag object. + * + * @see flag_flag::options() + */ +function hook_flag_options_alter(&$options, $flag) { + +} + /** * Act on a flagging. * @@ -106,13 +146,6 @@ function hook_flag_link() { } -/** - * TODO - */ -function hook_flag_link_types() { - -} - /** * TODO */ From d975598ce00e9d164790ea01dc968410ef87aac6 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 14 Jul 2012 19:09:56 +0100 Subject: [PATCH 052/629] by joachim: Added docblock to flag_get_link_types(). --- flag.module | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/flag.module b/flag.module index 585e126..ca6c4f2 100644 --- a/flag.module +++ b/flag.module @@ -1792,6 +1792,19 @@ function flag_create_link($flag_name, $content_id) { /** * Return an array of link types provided by modules. + * + * @param $reset + * (Optional) Whether to reset the static cache. + * + * @return + * An array of link types as defined by hook_flag_link_types(). These are keyed + * by the type name, and each value is an array of properties. In addition to + * those defined in hook_flag_link_types(), the following properties are set: + * - 'module': The providing module. + * - 'name': The machine name of the type. + * + * @see hook_flag_link_types() + * @see hook_flag_link_types_alter() */ function flag_get_link_types($reset = FALSE) { static $link_types; From ee5be691dca4bd5fa166d628b553bc7a3c34296e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 14 Jul 2012 19:10:09 +0100 Subject: [PATCH 053/629] by joachim: Added documentation to flag default options. --- flag.inc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flag.inc b/flag.inc index 7d5d7bf..922ce0c 100644 --- a/flag.inc +++ b/flag.inc @@ -182,13 +182,18 @@ class flag_flag { */ function options() { $options = array( + // The text for the "flag this" link for this flag. 'flag_short' => '', + // The description of the "flag this" link. 'flag_long' => '', + // Message displayed after flagging content. 'flag_message' => '', + // Likewise but for unflagged. 'unflag_short' => '', 'unflag_long' => '', 'unflag_message' => '', 'unflag_denied_text' => '', + // The link type used by the flag, as defined in hook_flag_link_types(). 'link_type' => 'toggle', 'roles' => array( 'flag' => array(DRUPAL_AUTHENTICATED_RID), From b8bc3bf44c58f24b4c20940e2beed1f1fc518834 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 14 Jul 2012 19:33:07 +0100 Subject: [PATCH 054/629] by joachim: Changed docblock for flag_flag_definitions() to match hook docblock. --- flag.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.inc b/flag.inc index 922ce0c..a2a80f1 100644 --- a/flag.inc +++ b/flag.inc @@ -9,7 +9,7 @@ /** * Implements hook_flag_definitions(). * - * Defines the flags this module implements. + * Defines the flag types this module implements. * * @return * An "array of arrays", keyed by content-types. The 'handler' slot From 756608fededb292bcc2f04aeb080dfc963054c11 Mon Sep 17 00:00:00 2001 From: goron Date: Sat, 14 Jul 2012 18:46:51 -0500 Subject: [PATCH 055/629] Remove 'Could not load default flag' error --- includes/flag.features.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/flag.features.inc b/includes/flag.features.inc index b80cccb..8fde24e 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -74,12 +74,12 @@ function flag_features_revert($module = NULL) { } } _flag_clear_cache(); + return TRUE; } else { - drupal_set_message(t('Could not load default flag.'), 'error'); + // No flags were found. return FALSE; } - return TRUE; } /** From 50c3dd62dd28ec31e9c63df27bcd2865ea49912a Mon Sep 17 00:00:00 2001 From: k_zoltan Date: Sat, 14 Jul 2012 22:03:44 -0500 Subject: [PATCH 056/629] Issue #1450042 by k_zoltan: flag_get_flag_counts function db_select to wrong table --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index ca6c4f2..099374b 100644 --- a/flag.module +++ b/flag.module @@ -1403,7 +1403,7 @@ function flag_get_flag_counts($flag_name, $reset = FALSE) { } if (!isset($counts[$flag_name])) { $flag = flag_get_flag($flag_name); - $counts[$flag_name] = db_select('flag_count', 'fc')->fields('fc', array('fcid')) + $counts[$flag_name] = db_select('flag_counts', 'fc')->fields('fc', array('fcid')) ->condition('fid', $flag->fid)->countQuery()->execute()->fetchField(); } From 4f321b8587a14fbd75fa85cf2b31ede3d89eabc6 Mon Sep 17 00:00:00 2001 From: git Date: Sat, 14 Jul 2012 23:24:57 -0500 Subject: [PATCH 057/629] Issue #1352274 by graker: ->get_user_count() --- flag.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.inc b/flag.inc index a2a80f1..ebb91a5 100644 --- a/flag.inc +++ b/flag.inc @@ -859,7 +859,7 @@ class flag_flag { } return db_select('flag_content', 'fc')->fields('fc', array('fcid')) ->condition('fid', $this->fid)->condition('uid', $uid)->condition('sid', $sid) - ->countQuery()->execute(); + ->countQuery()->execute()->fetchField(); } /** From 06438b711935bc201a90d6f9eed555643cb558a2 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 16 Jul 2012 21:25:03 +0100 Subject: [PATCH 058/629] Issue #1596492 by andypost, rafamatito: Fixed flag database data not cleaned up on comment & node delete. --- flag.install | 17 +++++++++++++++++ flag.module | 49 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/flag.install b/flag.install index cbbc3ce..782b291 100644 --- a/flag.install +++ b/flag.install @@ -462,3 +462,20 @@ function flag_update_6208() { function flag_update_7201() { // Do nothing. Update.php is going to clear caches for us. } + +/** + * Clean-up flag records for deleted nodes and comments. + */ +function flag_update_7202() { + // These queries can't use db_delete() because that doesn't support a + // subquery: see http://drupal.org/node/1267508. + // Clean-up for nodes. + db_query("DELETE FROM {flag_content} WHERE content_type = 'node' AND NOT EXISTS (SELECT 1 FROM {node} n WHERE content_id = n.nid)"); + db_query("DELETE FROM {flag_counts} WHERE content_type = 'node' AND NOT EXISTS (SELECT 1 FROM {node} n WHERE content_id = n.nid)"); + // Clean-up for comments. Do not use module_exists() because comment module + // could be disabled. + if (db_table_exists('comment')) { + db_query("DELETE FROM {flag_content} WHERE content_type = 'comment' AND NOT EXISTS (SELECT 1 FROM {comment} c WHERE content_id = c.cid)"); + db_query("DELETE FROM {flag_counts} WHERE content_type = 'comment' AND NOT EXISTS (SELECT 1 FROM {comment} c WHERE content_id = c.cid)"); + } +} diff --git a/flag.module b/flag.module index 099374b..6dc3544 100644 --- a/flag.module +++ b/flag.module @@ -550,12 +550,7 @@ function flag_node_delete($node) { // of a translation set, don't delete the flagging record. // Instead, data will be updated in the 'translation_change' op, below. if (!$flag->i18n || empty($node->tnid)) { - db_delete('flag_content') - ->condition('fid', $flag->fid) - ->condition('content_id', $node->nid); - db_delete('flag_counts') - ->condition('fid', $flag->fid) - ->condition('content_id', $node->nid); + _flag_content_delete('node', $node->nid, $flag->fid); } } } @@ -583,6 +578,38 @@ function flag_node_translation_change($node) { } } +/** + * Implements hook_comment_delete(). + */ +function flag_comment_delete($comment) { + _flag_content_delete('comment', $comment->cid); +} + +/** + * Deletes flagging records for the entity. + * + * @param $entity_type + * The type of the entity being deleted; e.g. 'node' or 'comment'. + * @param $entity_id + * The ID of the entity being deleted. + * @param $fid + * The flag id + */ +function _flag_content_delete($entity_type, $entity_id, $fid = NULL) { + $query_content = db_delete('flag_content') + ->condition('content_type', $entity_type) + ->condition('content_id', $entity_id); + $query_counts = db_delete('flag_counts') + ->condition('content_type', $entity_type) + ->condition('content_id', $entity_id); + if (isset($fid)) { + $query_content->condition('fid', $fid); + $query_counts->condition('fid', $fid); + } + $query_content->execute(); + $query_counts->execute(); +} + /** * Implements hook_user_login(). */ @@ -673,15 +700,7 @@ function flag_user_account_removal($account) { ->execute(); // Remove flags that have been done to this user. - db_delete('flag_content') - ->condition('content_type', 'user') - ->condition('content_id', $account->uid) - ->execute(); - - db_delete('flag_counts') - ->condition('content_type', 'user') - ->condition('content_id', $account->uid) - ->execute(); + _flag_content_delete('user', $account->uid); } /** From e08ee17378a93a92503a03ba419fa27980294d0a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 16 Jul 2012 21:28:43 +0100 Subject: [PATCH 059/629] by joachim: Fixed function docblock, added note about provenance of mystery hook, fixed mention of it. --- flag.module | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 6dc3544..e30def8 100644 --- a/flag.module +++ b/flag.module @@ -548,7 +548,7 @@ function flag_node_delete($node) { foreach (flag_get_flags('node') as $flag) { // If the flag is being tracked by translation set and the node is part // of a translation set, don't delete the flagging record. - // Instead, data will be updated in the 'translation_change' op, below. + // Instead, data will be updated in hook_node_translation_change(), below. if (!$flag->i18n || empty($node->tnid)) { _flag_content_delete('node', $node->nid, $flag->fid); } @@ -556,7 +556,9 @@ function flag_node_delete($node) { } /** - * Implements hook_translation_change(). + * Implements hook_node_translation_change(). + * + * (Hook provided by translation_helpers module.) */ function flag_node_translation_change($node) { if (isset($node->translation_change)) { From 43ca8037c0fb47f7a5a6c40156ee6b9c3924ce22 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 16 Jul 2012 21:30:00 +0100 Subject: [PATCH 060/629] Issue #1686644 by andypost: Fixed docblock for hook_node_type_delete(). --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index e30def8..e60fb7f 100644 --- a/flag.module +++ b/flag.module @@ -766,7 +766,7 @@ function flag_session_api_cleanup($arg = 'run') { } /** - * Implements hook_node_type(). + * Implements hook_node_type_delete(). */ function flag_node_type_delete($info) { // Remove entry from flaggable content types. From 5746c3334660919dfb73ed69964476be2734321d Mon Sep 17 00:00:00 2001 From: gcassie Date: Mon, 16 Jul 2012 21:36:13 -0500 Subject: [PATCH 061/629] Issue #1343838 by gcassie: Take advantage of drupal_page_is_cacheable() --- includes/flag_handler_relationships.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag_handler_relationships.inc b/includes/flag_handler_relationships.inc index 130542c..a2fa516 100644 --- a/includes/flag_handler_relationships.inc +++ b/includes/flag_handler_relationships.inc @@ -156,7 +156,7 @@ class flag_handler_relationship_content extends flag_handler_relationship { ); if (array_search(DRUPAL_ANONYMOUS_RID, $flag->roles['flag']) !== FALSE) { // Disable page caching for anonymous users. - $GLOBALS['conf']['cache'] = 0; + drupal_page_is_cacheable(FALSE); // Add in the SID from Session API for anonymous users. $this->definition['extra'][] = array( From d482c81ab5af1602a19eff2a4ec12a1770ba1fa3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 11:42:08 +0100 Subject: [PATCH 062/629] by joachim: Added @see to API docs. --- flag.api.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/flag.api.php b/flag.api.php index 65bd13a..f8c1169 100644 --- a/flag.api.php +++ b/flag.api.php @@ -23,6 +23,8 @@ * - 'description': A longer description shown in the UI when creating a new * flag. * - 'handler': The name of the class implementing this flag type. + * + * @see flag_fetch_definition() */ function hook_flag_definitions() { return array( From 23f41eb18cfc1abc3da8a05de4301f5ba7840b0a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 13:35:50 +0100 Subject: [PATCH 063/629] by joachim: Added API docs for hook_flag_access(). --- flag.api.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/flag.api.php b/flag.api.php index f8c1169..3fecb79 100644 --- a/flag.api.php +++ b/flag.api.php @@ -128,9 +128,20 @@ function hook_flag($op, $flag, $content_id, $account, $fcid) { } /** - * TODO + * Allow modules to allow or deny access to flagging. + * + * @param $flag + * The flag object. + * @param $content_id + * The id of the entity in question. + * @param $action + * The action to test. Either 'flag' or 'unflag'. + * @param $account + * The user on whose behalf to test the flagging action. + * + * @see flag_flag:access() */ -function hook_flag_access() { +function hook_flag_access($flag, $content_id, $action, $account) { } From a583aba5379c30df4976be00df3bb27c0b29ae62 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 13:36:17 +0100 Subject: [PATCH 064/629] by joachim: Added documentation note about D6-era terminology. --- flag.module | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/flag.module b/flag.module index e60fb7f..0018ef8 100644 --- a/flag.module +++ b/flag.module @@ -3,6 +3,14 @@ /** * @file * The Flag module. + * + * A note on terminology: due to the 7.x-2.x branch of flag being a reasonably + * straight port of 6.x-2.x, the Drupal 6 term 'content type' persists in + * function names, database fields, and variables. + * Thus: + * 'content type' -> 'entity type' + * 'content' -> 'entity' + * 'sub-type' -> 'bundle' ('type' is also used sometimes!) */ define('FLAG_API_VERSION', 2); From 72960a50edd58918a7833ba756c8f83533735efb Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 14:45:29 +0100 Subject: [PATCH 065/629] by joachim: Fixed parameters in docblock on access(). --- flag.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flag.inc b/flag.inc index ebb91a5..60e3ba4 100644 --- a/flag.inc +++ b/flag.inc @@ -417,12 +417,12 @@ class flag_flag { * * @param $content_id * The content ID to flag/unflag. - * @param $account - * The user on whose behalf to test the flagging action. Leave NULL for the - * current user. * @param $action * The action to test. Either 'flag' or 'unflag'. Leave NULL to determine * by flag status. + * @param $account + * The user on whose behalf to test the flagging action. Leave NULL for the + * current user. */ function access($content_id, $action = NULL, $account = NULL) { if (!isset($account)) { From 1479d488dd3ea58ab54c1fd8e8634c5aef526e1d Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 15:01:47 +0100 Subject: [PATCH 066/629] Issue #1689478 by joachim: Changed hook_form_alter() to separate functions per form id. --- flag.module | 57 +++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/flag.module b/flag.module index 0018ef8..ca25827 100644 --- a/flag.module +++ b/flag.module @@ -351,37 +351,42 @@ function flag_field_extra_fields() { } /** - * Implements hook_form_alter(). + * Implements hook_form_FORM_ID_alter(): node_type_form. */ -function flag_form_alter(&$form, &$form_state, $form_id) { +function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { global $user; - - if ($form_id == 'node_type_form') { - $flags = flag_get_flags('node', $form['#node_type']->type, $user); - foreach ($flags as $flag) { - if ($flag->show_on_form) { - $var = 'flag_' . $flag->name . '_default'; - $form['workflow']['flag'][$var] = array( - '#type' => 'checkbox', - '#title' => $flag->get_label('flag_short', $form['#node_type']->type), - '#default_value' => variable_get($var . '_' . $form['#node_type']->type, 0), - '#return_value' => 1, - ); - } - } - - if (isset($form['workflow']['flag'])) { - $form['workflow']['flag'] += array( - '#type' => 'item', - '#title' => t('Default flags'), - '#description' => t('Above are the flags you elected to show on the node editing form. You may specify their initial state here.', array('@flag-url' => url(FLAG_ADMIN_PATH))), - // Make the spacing a bit more compact: - '#prefix' => '
', - '#suffix' => '
', + $flags = flag_get_flags('node', $form['#node_type']->type, $user); + foreach ($flags as $flag) { + if ($flag->show_on_form) { + $var = 'flag_' . $flag->name . '_default'; + $form['workflow']['flag'][$var] = array( + '#type' => 'checkbox', + '#title' => $flag->get_label('flag_short', $form['#node_type']->type), + '#default_value' => variable_get($var . '_' . $form['#node_type']->type, 0), + '#return_value' => 1, ); } } - elseif (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] . '_node_form')) { + + if (isset($form['workflow']['flag'])) { + $form['workflow']['flag'] += array( + '#type' => 'item', + '#title' => t('Default flags'), + '#description' => t('Above are the flags you elected to show on the node editing form. You may specify their initial state here.', array('@flag-url' => url(FLAG_ADMIN_PATH))), + // Make the spacing a bit more compact: + '#prefix' => '
', + '#suffix' => '
', + ); + } +} + +/** + * Implements hook_form_alter(). + */ +function flag_form_alter(&$form, &$form_state, $form_id) { + // Alter node forms. + if (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] . '_node_form')) { + global $user; $nid = !empty($form['nid']['#value']) ? $form['nid']['#value'] : NULL; $flags = flag_get_flags('node', $form['type']['#value'], $user); From a7f8007d41b51b657f2aaf888cdf6c5610bc3890 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 17:47:54 +0100 Subject: [PATCH 067/629] Issue #1550540 by refineo, klausi: Fixed Rules 'Permission check' parameter label. --- flag.rules.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.rules.inc b/flag.rules.inc index 5103829..5669786 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -185,8 +185,8 @@ function flag_rules_action_info() { ), 'permission_check' => array( 'type' => 'boolean', - 'label' => t('Permission check'), - 'description' => t('Whether to check access permissions against the user on whose behalf to flag.'), + 'label' => t('Skip permission check'), + 'description' => t('Whether to ignore permissions of the user on whose behalf to flag.'), 'restriction' => 'input', ), ); From 83b2a5fb112d44476800572c4548e14eb3c5f643 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 17:49:32 +0100 Subject: [PATCH 068/629] Issue #1683204 by bberl: Fixed hook_features_revert() returning useless value. --- includes/flag.features.inc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/includes/flag.features.inc b/includes/flag.features.inc index 8fde24e..859f56f 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -74,11 +74,6 @@ function flag_features_revert($module = NULL) { } } _flag_clear_cache(); - return TRUE; - } - else { - // No flags were found. - return FALSE; } } From 7f862b3ee0058e48cf4f80b24489e8a149dc5b52 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 17 Jul 2012 18:00:17 +0100 Subject: [PATCH 069/629] by joachim: Fixed permission label. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index ca25827..7fc2527 100644 --- a/flag.module +++ b/flag.module @@ -218,7 +218,7 @@ function flag_features_api() { function flag_permission() { return array( 'administer flags' => array( - 'title' => t('administer flags'), + 'title' => t('Administer flags'), 'description' => t('Create and edit site-wide flags.'), ), ); From e38a0d6118faed30ab7860a9ec74c22d3172bff5 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 18 Jul 2012 11:45:12 +0100 Subject: [PATCH 070/629] Issue #1372850 by joachim: Added permission for use of PHP in flag import. --- flag.module | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 7fc2527..819442c 100644 --- a/flag.module +++ b/flag.module @@ -51,7 +51,7 @@ function flag_menu() { 'title' => 'Import', 'page callback' => 'drupal_get_form', 'page arguments' => array('flag_import_form'), - 'access arguments' => array('administer flags'), + 'access arguments' => array('use flag import'), 'file' => 'includes/flag.export.inc', 'type' => MENU_LOCAL_TASK, 'weight' => 2, @@ -221,6 +221,11 @@ function flag_permission() { 'title' => t('Administer flags'), 'description' => t('Create and edit site-wide flags.'), ), + 'use flag import' => array( + 'title' => t('Use flag importer'), + 'description' => t('Access the flag import functionality.'), + 'restrict access' => TRUE, + ), ); } From 64dc41c992f4648a86a96d219053148dea1ab48e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 18 Jul 2012 12:48:50 +0100 Subject: [PATCH 071/629] by joachim: Added further clarification to explanation of terminology. --- flag.module | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 819442c..07ceb35 100644 --- a/flag.module +++ b/flag.module @@ -8,7 +8,8 @@ * straight port of 6.x-2.x, the Drupal 6 term 'content type' persists in * function names, database fields, and variables. * Thus: - * 'content type' -> 'entity type' + * 'content type' -> 'entity type' (though not exclusively, as a flag type + * may be defined for any kind of object) * 'content' -> 'entity' * 'sub-type' -> 'bundle' ('type' is also used sometimes!) */ From a154a88596cf582a8b97cfb90eeadab9f3751182 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 20 Jul 2012 08:41:38 +0100 Subject: [PATCH 072/629] Issue #1035410 by mh86, univate, joachim, zkday, alexweber: Added ability to flag any entity type. --- flag.inc | 363 ++++++++++++++++++++++++--------------- flag.module | 209 +++++++++++++++++----- includes/flag.admin.inc | 4 +- includes/flag.export.inc | 5 + 4 files changed, 401 insertions(+), 180 deletions(-) diff --git a/flag.inc b/flag.inc index 60e3ba4..ba2958b 100644 --- a/flag.inc +++ b/flag.inc @@ -16,7 +16,8 @@ * should point to the PHP class implementing this flag. */ function flag_flag_definitions() { - return array( + // Entity types we specifically cater for. + $flags = array( 'node' => array( 'title' => t('Nodes'), 'description' => t("Nodes are a Drupal site's primary content."), @@ -33,6 +34,29 @@ function flag_flag_definitions() { 'handler' => 'flag_user', ), ); + + return $flags; +} + +/** + * Implements hook_flag_definitions_alter(). + * + * Step in and add flag types for any entities not yet catered for, using the + * basic flag_entity handler. This allows other modules to provide more + * specialized handlers for entities in hook_flag_definitions() as normal. + */ +function flag_flag_definitions_alter(&$definitions) { + foreach (entity_get_info() as $entity_type => $entity) { + // Only add flag support for entities that don't yet have them, and which + // are non-config entities. + if (!isset($definitions[$entity_type]) && empty($entity['configuration'])) { + $definitions[$entity_type] = array( + 'title' => $entity['label'], + 'description' => t('@entity-type entity', array('@entity-type' => $entity['label'])), + 'handler' => 'flag_entity', + ); + } + } } /** @@ -1243,25 +1267,205 @@ class flag_flag { } } +/** + * Base entity flag handler. + */ +class flag_entity extends flag_flag { + /** + * The entity info for this flag's entity type. + */ + var $entity_info; + + /** + * Default contructor that furthermore loads the entity info for the current + * content_type. (Note content_type is used as synonym for entity_type in this + * handler.) + */ + function construct() { + parent::construct(); + $this->entity_info = entity_get_info($this->content_type); + } + + /** + * Adds additional options that are common for all entity types. + */ + function options() { + $options = parent::options(); + $options += array( + // Output the flag in the entity links. + // @see hook_entity_view(). + 'show_on_entity' => TRUE, + // Add a checkbox for the flag in the entity form. + // @see hook_field_attach_form(). + 'show_on_form' => FALSE, + 'access_author' => '', + ); + return $options; + } + + /** + * Options form extras for the generic entity flag. + */ + function options_form(&$form) { + $bundles = array(); + foreach ($this->entity_info['bundles'] as $bundle_key => $bundle) { + $bundles[$bundle_key] = check_plain($bundle['label']); + } + $form['access']['types'] = array( + '#type' => 'checkboxes', + '#title' => t('Bundles'), + '#options' => $bundles, + '#description' => t('Check any bundle that this flag may be used on. You must check at least one bundle.'), + '#default_value' => $this->types, + '#required' => TRUE, + ); + // Handlers may want to unset this option if they provide their own more + // specific ways to show links. + $form['display']['show_on_entity'] = array( + '#type' => 'checkbox', + '#title' => t('Display link on entity'), + '#default_value' => isset($this->show_on_entity) ? $this->show_on_entity : TRUE, + '#access' => empty($this->locked['show_on_entity']), + ); + $form['display']['show_on_form'] = array( + '#type' => 'checkbox', + '#title' => t('Display checkbox on entity edit form'), + '#default_value' => $this->show_on_form, + '#access' => empty($this->locked['show_on_form']), + ); + } + + /** + * Loads the entity object. + */ + function _load_content($content_id) { + if (is_numeric($content_id)) { + $entity = entity_load($this->content_type, array($content_id)); + return reset($entity); + } + return NULL; + } + + /** + * Checks whether the flag applies for the current entity bundle. + */ + function applies_to_content_object($entity) { + if (empty($this->entity_info['entity keys']['bundle']) || in_array($entity->{$this->entity_info['entity keys']['bundle']}, $this->types)) { + return TRUE; + } + return FALSE; + } + + /** + * Returns the entity id, if it already exists. + */ + function get_content_id($entity) { + if ($entity && isset($entity->{$this->entity_info['entity keys']['id']})) { + return $entity->{$this->entity_info['entity keys']['id']}; + } + } + + /** + * Returns TRUE if the link should be displayed. + */ + function uses_hook_link($teaser) { + if ($this->show_on_entity) { + return TRUE; + } + return FALSE; + } + + /** + * Returns token types for the current entity type. + */ + function get_labels_token_types() { + // The token type name might be different to the entity type name. If so, + // an own flag entity handler can be used for overriding this. + return array_merge(array($this->content_type), parent::get_labels_token_types()); + } + + /** + * Replaces tokens. + */ + function replace_tokens($label, $contexts, $options, $content_id) { + if ($content_id && ($entity = $this->fetch_content($content_id))) { + $contexts[$this->content_type] = $entity; + } + return parent::replace_tokens($label, $contexts, $options, $content_id); + } + + /** + * Returns a 'flag action' object. + */ + function get_flag_action($content_id) { + $flag_action = parent::get_flag_action($content_id); + $entity = $this->fetch_content($content_id); + $flag_action->content_title = entity_label($this->content_type, $entity); + $flag_action->content_url = _flag_url($this->content_type . '/' . $this->get_content_id($entity)); + return $flag_action; + } + + /** + * Returns objects the action may possible need. + */ + function get_relevant_action_objects($content_id) { + return array( + $this->content_type => $this->fetch_content($content_id), + ); + } + + /** + * Returns information for the Views integration. + */ + function get_views_info() { + return array( + 'views table' => $this->entity_info['base table'], + 'join field' => $this->entity_info['entity keys']['id'], + 'title field' => isset($this->entity_info['entity keys']['label']) ? $this->entity_info['entity keys']['label'] : '', + 'title' => t('@entity_label flag', array('@entity_label' => $this->entity_info['label'])), + 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), + 'counter title' => t('@entity_label flag counter', array('@entity_label' => $this->entity_info['label'])), + 'counter help' => t('Include this to gain access to the flag counter field.'), + ); + } +} + /** * Implements a node flag. */ -class flag_node extends flag_flag { +class flag_node extends flag_entity { function options() { $options = parent::options(); + // Use own display settings in the meanwhile. + unset($options['show_on_entity']); $options += array( 'show_on_page' => TRUE, 'show_on_teaser' => TRUE, 'show_on_form' => FALSE, 'show_contextual_link' => FALSE, - 'access_author' => '', 'i18n' => 0, ); return $options; } + /** + * Options form extras for node flags. + */ function options_form(&$form) { parent::options_form($form); + + $form['access']['access_author'] = array( + '#type' => 'radios', + '#title' => t('Flag access by content authorship'), + '#options' => array( + '' => t('No additional restrictions'), + 'own' => t('Users may only flag content they own'), + 'others' => t('Users may only flag content of others'), + ), + '#default_value' => $this->access_author, + '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), + ); + // Support for i18n flagging requires Translation helpers module. $form['i18n'] = array( '#type' => 'radios', @@ -1276,54 +1480,32 @@ class flag_node extends flag_flag { '#weight' => 5, ); - $form['access']['access_author'] = array( - '#type' => 'radios', - '#title' => t('Flag access by content authorship'), - '#options' => array( - '' => t('No additional restrictions'), - 'own' => t('Users may only flag content they own'), - 'others' => t('Users may only flag content of others'), - ), - '#default_value' => $this->access_author, - '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), - ); - $form['display']['show_on_teaser'] = array( '#type' => 'checkbox', '#title' => t('Display link on node teaser'), '#default_value' => $this->show_on_teaser, '#access' => empty($this->locked['show_on_teaser']), ); + $form['display']['show_on_page'] = array( '#type' => 'checkbox', '#title' => t('Display link on node page'), '#default_value' => $this->show_on_page, '#access' => empty($this->locked['show_on_page']), ); + // Override the UI texts for nodes. $form['display']['show_on_form'] = array( - '#type' => 'checkbox', '#title' => t('Display checkbox on node edit form'), - '#default_value' => $this->show_on_form, '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), - '#access' => empty($this->locked['show_on_form']), - ); + ) + $form['display']['show_on_form']; $form['display']['show_contextual_link'] = array( '#type' => 'checkbox', '#title' => t('Display in contextual links'), '#default_value' => $this->show_contextual_link, '#access' => empty($this->locked['show_contextual_link']) && module_exists('contextual'), ); - } - - function _load_content($content_id) { - return is_numeric($content_id) ? node_load($content_id) : NULL; - } - function applies_to_content_object($node) { - if ($node && in_array($node->type, $this->types)) { - return TRUE; - } - return FALSE; + unset($form['display']['show_on_entity']); } function type_access_multiple($content_ids, $account = NULL) { @@ -1342,10 +1524,6 @@ class flag_node extends flag_flag { return $access; } - function get_content_id($node) { - return $node->nid; - } - /** * Adjust the Content ID to find the translation parent if i18n-enabled. * @@ -1383,10 +1561,6 @@ class flag_node extends flag_flag { return parent::get_flagging_record($content_id, $uid, $sid); } - function get_labels_token_types() { - return array_merge(array('node'), parent::get_labels_token_types()); - } - function replace_tokens($label, $contexts, $options, $content_id) { if (is_numeric($content_id) && ($node = $this->fetch_content($content_id))) { $contexts['node'] = $node; @@ -1403,50 +1577,16 @@ class flag_node extends flag_flag { } return parent::replace_tokens($label, $contexts, $options, $content_id); } - - function get_flag_action($content_id) { - $flag_action = parent::get_flag_action($content_id); - $node = $this->fetch_content($content_id); - $flag_action->content_title = $node->title; - $flag_action->content_url = _flag_url('node/' . $node->nid); - return $flag_action; - } - - function get_valid_actions() { - $actions = module_invoke_all('action_info'); - foreach ($actions as $callback => $action) { - if ($action['type'] != 'node' && !in_array('any', $action['triggers'])) { - unset($actions[$callback]); - } - } - return $actions; - } - - function get_relevant_action_objects($content_id) { - return array( - 'node' => $this->fetch_content($content_id), - ); - } - - function get_views_info() { - return array( - 'views table' => 'node', - 'join field' => 'nid', - 'title field' => 'title', - 'title' => t('Node flag'), - 'help' => t('Limit results to only those nodes flagged by a certain flag; Or display information about the flag set on a node.'), - 'counter title' => t('Node flag counter'), - 'counter help' => t('Include this to gain access to the flag counter field.'), - ); - } } /** * Implements a comment flag. */ -class flag_comment extends flag_flag { +class flag_comment extends flag_entity { function options() { $options = parent::options(); + // Use own display settings in the meanwhile. + unset($options['show_on_entity']); $options += array( 'access_author' => '', 'show_on_comment' => TRUE, @@ -1454,6 +1594,9 @@ class flag_comment extends flag_flag { return $options; } + /** + * Options form extras for comment flags. + */ function options_form(&$form) { parent::options_form($form); @@ -1477,17 +1620,8 @@ class flag_comment extends flag_flag { '#default_value' => $this->show_on_comment, '#access' => empty($this->locked['show_on_comment']), ); - } - function _load_content($content_id) { - return comment_load($content_id); - } - - function applies_to_content_object($comment) { - if ($comment && ($node = node_load($comment->nid)) && in_array($node->type, $this->types)) { - return TRUE; - } - return FALSE; + unset($form['display']['show_on_entity']); } function type_access_multiple($content_ids, $account) { @@ -1549,26 +1683,16 @@ class flag_comment extends flag_flag { 'node' => node_load($comment->nid), ); } - - function get_views_info() { - return array( - 'views table' => 'comment', - 'join field' => 'cid', - 'title field' => 'subject', - 'title' => t('Comment flag'), - 'help' => t('Limit results to only those comments flagged by a certain flag; Or display information about the flag set on a comment.'), - 'counter title' => t('Comment flag counter'), - 'counter help' => t('Include this to gain access to the flag counter field.'), - ); - } } /** * Implements a user flag. */ -class flag_user extends flag_flag { +class flag_user extends flag_entity { function options() { $options = parent::options(); + // Use own display settings in the meanwhile. + unset($options['show_on_entity']); $options += array( 'show_on_profile' => TRUE, 'access_uid' => '', @@ -1576,6 +1700,9 @@ class flag_user extends flag_flag { return $options; } + /** + * Options form extras for user flags. + */ function options_form(&$form) { parent::options_form($form); $form['access']['types'] = array( @@ -1596,6 +1723,8 @@ class flag_user extends flag_flag { '#default_value' => $this->show_on_profile, '#access' => empty($this->locked['show_on_profile']), ); + + unset($form['display']['show_on_entity']); } function form_input($form_values) { @@ -1605,19 +1734,6 @@ class flag_user extends flag_flag { $this->access_uid = empty($form_values['access_uid']) ? 'others' : ''; } - function _load_content($content_id) { - return user_load($content_id); - } - - function applies_to_content_object($user) { - // This user flag doesn't currently support subtypes so we return TRUE for - // any user. - if ($user) { - return TRUE; - } - return FALSE; - } - function type_access($content_id, $action, $account) { // Prevent users from flagging themselves. if ($this->access_uid == 'others' && $content_id == $account->uid) { @@ -1641,10 +1757,6 @@ class flag_user extends flag_flag { return $access; } - function get_content_id($user) { - return $user->uid; - } - function uses_hook_link($teaser) { if ($this->show_on_profile) { return TRUE; @@ -1652,17 +1764,6 @@ class flag_user extends flag_flag { return FALSE; } - function get_labels_token_types() { - return array_merge(array('user'), parent::get_labels_token_types()); - } - - function replace_tokens($label, $contexts, $options, $content_id) { - if ($content_id && ($user = $this->fetch_content($content_id))) { - $contexts['user'] = $user; - } - return parent::replace_tokens($label, $contexts, $options, $content_id); - } - function get_flag_action($content_id) { $flag_action = parent::get_flag_action($content_id); $user = $this->fetch_content($content_id); @@ -1678,15 +1779,9 @@ class flag_user extends flag_flag { } function get_views_info() { - return array( - 'views table' => 'users', - 'join field' => 'uid', - 'title field' => 'name', - 'title' => t('User flag'), - 'help' => t('Limit results to only those users flagged by a certain flag; Or display information about the flag set on a user.'), - 'counter title' => t('User flag counter'), - 'counter help' => t('Include this to gain access to the flag counter field.'), - ); + $views_info = parent::get_views_info(); + $views_info['title field'] = 'name'; + return $views_info; } } diff --git a/flag.module b/flag.module index 07ceb35..8099081 100644 --- a/flag.module +++ b/flag.module @@ -233,8 +233,7 @@ function flag_permission() { /** * Implements hook_link(). * - * This hook does not exist in Drupal 7, it is called from flag_node_view() and - * flag_comment_view() functions. + * This hook does not exist in Drupal 7, it is called from flag_entity_view(). */ function flag_link($type, $object = NULL, $teaser = FALSE) { if (!isset($object) || !flag_fetch_definition($type)) { @@ -333,24 +332,20 @@ function flag_flag_link_types() { function flag_field_extra_fields() { $extra = array(); - foreach (node_type_get_types() as $type) { - $flags = flag_get_flags('node', $type->type); - - // Filter out flags which need to be included on the node form. - $flag_names = array(); - foreach ($flags as $name => $flag) { + $flags = flag_get_flags(); + foreach ($flags as $name => $flag) { + // In order to make sense with this hook's structure, we use D7 lingo, hence + // some translation is required... + $entity_type = $flag->content_type; + foreach ($flag->types as $bundle_name) { if ($flag->show_on_form) { - $flag_names[] = $flag->get_label('title'); + $extra[$entity_type][$bundle_name]['form']['flag'] = array( + 'label' => t('Flags'), + 'description' => t('Checkboxes for toggling flags'), + 'weight' => 10 + ); } } - - if ($flag_names) { - $extra['node'][$type->type]['form']['flag'] = array( - 'label' => t('Flags'), - 'description' => t('Checkboxes for toggling flags (i.e. @flag_names)', array('@flag_names' => implode(', ', $flag_names))), - 'weight' => 1 - ); - } } return $extra; @@ -386,6 +381,131 @@ function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { } } +/** + * Implements hook_field_attach_form(). + * + * Handles the 'show_on_form' flag option. + * + * Warning: will not work on entity types that are not fieldable, as this relies + * on a field module hook. + * + * @see flag_field_attach_submit(). + */ +function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) { + // Nodes have their own special form handling: see flag_form_alter(). + if ($entity_type == 'node') { + return; + } + + list($id) = entity_extract_ids($entity_type, $entity); + // Some modules are being stupid here. Commerce! + if (empty($id)) { + $id = NULL; + } + + // Get all possible flags for this content-type. + $flags = flag_get_flags($entity_type); + + // Filter out flags which need to be included on the node form. + $flags_in_form = 0; + $flags_visible = 0; + foreach ($flags as $flag) { + if (!$flag->show_on_form) { + continue; + } + + // Get the flag status. + // We don't have per-bundle defaults on general entities yet. + $flag_status = $id ? $flag->is_flagged($id) : FALSE; + + // If the flag is not global and the user doesn't have access, skip it. + // Global flags have their value set even if the user doesn't have access + // to it, similar to the way "published" and "promote" keep the default + // values even if the user doesn't have "administer nodes" permission. + global $user; + $access = $flag->access($id, $flag_status ? 'unflag' : 'flag'); + if (!$access && !$flag->global) { + continue; + } + + $form['flag'][$flag->name] = array( + '#type' => 'checkbox', + '#title' => $flag->get_label('flag_short', $id), + '#description' => $flag->get_label('flag_long', $id), + '#default_value' => $flag_status, + '#return_value' => 1, + ); + + // If the user does not have access to the flag, set as a value. + if (!$access) { + $form['flag'][$flag->name]['#type'] = 'value'; + $form['flag'][$flag->name]['#value'] = $flag_status; + } + else { + $flags_visible++; + } + $flags_in_form++; + } + + if ($flags_in_form) { + $form['flag'] += array( + '#weight' => 1, + '#tree' => TRUE, + ); + } + if ($flags_visible) { + $form['flag'] += array( + '#type' => 'fieldset', + '#title' => t('Flags'), + '#collapsible' => TRUE, + ); + } +} + +/** + * Implements hook_field_attach_submit(). + * + * @see flag_field_attach_form(). + */ +function flag_field_attach_submit($entity_type, $entity, $form, &$form_state) { + // Put the form values in the entity so flag_field_attach_save() can find + // them. We can't call flag() here as new entities have no id yet. + if (isset($form_state['values']['flag'])) { + $entity->flag = $form_state['values']['flag']; + } +} + +/** + * Implements hook_field_attach_insert(). + */ +function flag_field_attach_insert($entity_type, $entity) { + if (isset($entity->flag)) { + flag_field_attach_save($entity_type, $entity); + } +} + +/** + * Implements hook_field_attach_update(). + */ +function flag_field_attach_update($entity_type, $entity) { + if (isset($entity->flag)) { + flag_field_attach_save($entity_type, $entity); + } +} + +/** + * Shared saving routine between flag_field_attach_insert/update(). + * + * @see flag_field_attach_form(). + */ +function flag_field_attach_save($entity_type, $entity) { + list($id) = entity_extract_ids($entity_type, $entity); + // Get the flag values we stashed in the entity in flag_field_attach_submit(). + foreach ($entity->flag as $flag_name => $state) { + flag($state ? 'flag' : 'unflag', $flag_name, $id); + } +} + /** * Implements hook_form_alter(). */ @@ -499,27 +619,21 @@ function flag_contextual_links_view_alter(&$element, $items) { } /** - * Implements hook_comment_view(). - */ -function flag_comment_view($comment) { - $links = flag_link('comment', $comment); - $comment->content['links']['flag'] = array( - '#theme' => 'links', - '#links' => $links, - '#attributes' => array('class' => array('links', 'inline')), - ); -} - -/** - * Implements hook_node_view(). + * Implements hook_entity_view(). + * + * Handles the 'show_on_entity' flag option. + * + * Note this is broken for taxonomy terms. @see http://drupal.org/node/1067120 */ -function flag_node_view($node, $view_mode) { - $links = flag_link('node', $node, $view_mode == 'teaser'); - $node->content['links']['flag'] = array( - '#theme' => 'links__node__flag', - '#links' => $links, - '#attributes' => array('class' => array('links', 'inline')), - ); +function flag_entity_view($entity, $type, $view_mode, $langcode) { + $links = flag_link($type, $entity, $view_mode == 'teaser'); + if (isset($links)) { + $entity->content['links']['flag'] = array( + '#theme' => 'links', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); + } } /** @@ -560,6 +674,20 @@ function flag_node_save($node) { } } +/** + * Implements hook_entity_delete(). + */ +function flag_entity_delete($entity, $type) { + // Node and user flags handle things through the entity type delete hooks. + // @todo: make this configurable in the flag type definition? + if ($type == 'node' || $type == 'user') { + return; + } + + list($id) = entity_extract_ids($type, $entity); + _flag_content_delete($type, $id); +} + /** * Implements hook_node_delete(). */ @@ -599,13 +727,6 @@ function flag_node_translation_change($node) { } } -/** - * Implements hook_comment_delete(). - */ -function flag_comment_delete($comment) { - _flag_content_delete('comment', $comment->cid); -} - /** * Deletes flagging records for the entity. * diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index cd51eee..e1039b9 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -95,7 +95,7 @@ function theme_flag_admin_listing($variables) { drupal_add_tabledrag('flag-admin-listing-table', 'order', 'sibling', 'flag-weight'); } - $header = array(t('Flag'), t('Weight'), t('Flag type'), t('Roles'), t('Node types'), t('Global?'), t('Operations')); + $header = array(t('Flag'), t('Weight'), t('Flag type'), t('Roles'), t('Entity bundles'), t('Global?'), t('Operations')); $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'flag-admin-listing-table'))); $output .= drupal_render_children($form); @@ -293,7 +293,7 @@ function flag_form($form, &$form_state, $flag) { '#type' => 'checkbox', '#title' => t('Global flag'), '#default_value' => $flag->global, - '#description' => t('If checked, flag is considered "global" and each node is either flagged or not. If unchecked, each user has individual flags on content.'), + '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), '#access' => empty($flag->locked['global']), '#weight' => -1, ); diff --git a/includes/flag.export.inc b/includes/flag.export.inc index d0ea2ec..51843da 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -52,6 +52,11 @@ function flag_export_flags($flags = array(), $module = '', $indent = '') { // The name is emitted as the key for the array. unset($new_flag['name']); +// Do not export the whole entity info, as it is just used as helper data. + if (isset($new_flag['entity_info'])) { + unset($new_flag['entity_info']); + } + $output .= $indent . '// Exported flag: "' . check_plain($flag->get_title()) . '"' . ".\n"; $output .= $indent . '$flags[\'' . $flag->name . '\'] = ' . (function_exists('features_var_export') ? features_var_export($new_flag, $indent) : var_export($new_flag, TRUE)) . ";\n"; } From 3c8772ea7014ce658a0db0d267b8783cc78b87c8 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 20 Jul 2012 09:14:31 +0100 Subject: [PATCH 073/629] Issue #1689686 by joachim: Fixed cleaning of {flag_types} on entity bundle delete. --- flag.module | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/flag.module b/flag.module index 8099081..a145cee 100644 --- a/flag.module +++ b/flag.module @@ -906,11 +906,17 @@ function flag_session_api_cleanup($arg = 'run') { } /** - * Implements hook_node_type_delete(). - */ -function flag_node_type_delete($info) { - // Remove entry from flaggable content types. - db_delete('flag_types')->condition('type', $info->type)->execute(); + * Implements hook_field_attach_delete_bundle(). + * + * Delete any flags' applicability to the deleted bundle. + */ +function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { + // This query can't use db_delete() because that doesn't support a + // subquery: see http://drupal.org/node/1267508. + db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM flags WHERE content_type = :entity_type)", array( + ':bundle' => $bundle, + ':entity_type' => $entity_type, + )); } /** From 38ab479e87bfff2da853ac2ac6e3735b855a2e02 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 20 Jul 2012 20:01:04 +0100 Subject: [PATCH 074/629] Issue #1451730 by pavlos_dan, Shnapoo: Fixed fatal PHP error in Rules administration after deleting a flag. --- flag.rules.inc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flag.rules.inc b/flag.rules.inc index 5669786..75c5d37 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -83,6 +83,11 @@ class FlagRulesUIClass extends RulesDataUI implements RulesDataDirectInputFormIn public static function render($value) { $flag = flag_get_flag($value); + + if ($flag === FALSE) { + return array(); + } + return array( 'content' => array('#markup' => check_plain($flag->get_title())), '#attributes' => array('class' => array('rules-parameter-flag')), From e577c0c94a5a732bb0255ce7ff3b73ca0df5d18b Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 20 Jul 2012 20:01:27 +0100 Subject: [PATCH 075/629] by joachim: Added function documentation. --- flag.module | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index a145cee..bc2adb0 100644 --- a/flag.module +++ b/flag.module @@ -1581,9 +1581,12 @@ function flag_get_flag_counts($flag_name, $reset = FALSE) { * Load a single flag either by name or by flag ID. * * @param $name - * The the flag name. + * (optional) The flag name. * @param $fid - * The the flag id. + * (optional) The the flag id. + * + * @return + * The flag object, or FALSE if no matching flag was found. */ function flag_get_flag($name = NULL, $fid = NULL) { $flags = flag_get_flags(); From a100cf55fb4a47e154a40822d8f8503950489202 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 21 Jul 2012 08:10:11 +0100 Subject: [PATCH 076/629] Issue #1462000 by joachim, joelstein: Fixed incorrect value returned by argument flaggability check. --- includes/flag_plugin_argument_validate_flaggability.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag_plugin_argument_validate_flaggability.inc b/includes/flag_plugin_argument_validate_flaggability.inc index 0cba7ed..cb3587a 100644 --- a/includes/flag_plugin_argument_validate_flaggability.inc +++ b/includes/flag_plugin_argument_validate_flaggability.inc @@ -219,7 +219,7 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v global $user; if (!$user->uid) { // Anonymous user - return FALSE; + return array(); } $flattened_ids = implode(',', $ids); return $this->_test_by_sql("SELECT content_id FROM {flag_content} WHERE fid = :fid AND content_id IN ($flattened_ids) AND uid = :uid", array(':fid' => $flag->fid, ':uid' => $user->uid)); From 3e2031ee8f10378e0e628cd20b0579d05c34cd40 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 23 Jul 2012 21:46:15 +0100 Subject: [PATCH 077/629] Issue #1483854 by osopolar: Fixed views flagged filter options form not showing default value for 'Not flagged' option. --- includes/flag_handler_filter_flagged.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag_handler_filter_flagged.inc b/includes/flag_handler_filter_flagged.inc index 5154125..d22c40b 100644 --- a/includes/flag_handler_filter_flagged.inc +++ b/includes/flag_handler_filter_flagged.inc @@ -22,7 +22,7 @@ class flag_handler_filter_flagged extends views_handler_filter_boolean_operator $form['value']['#type'] = 'radios'; $form['value']['#title'] = t('Status'); $form['value']['#options'] = array(1 => t('Flagged'), 0 => t('Not flagged'), 'All' => t('All')); - $form['value']['#default_value'] = empty($this->options['value']) ? 0 : $this->options['value']; + $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; } From 79df77c00aadcc49fe00bd77f1e0ae3437f6d3b9 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 23 Jul 2012 21:50:56 +0100 Subject: [PATCH 078/629] Issue #1362704 by loganfsmyth: Removed obsolete hook_views_handlers(). --- includes/flag.views.inc | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/includes/flag.views.inc b/includes/flag.views.inc index 3dd6df0..1fefe95 100644 --- a/includes/flag.views.inc +++ b/includes/flag.views.inc @@ -5,40 +5,6 @@ * Provides support for the Views module. */ -/** - * Implements hook_views_handlers(). - */ -function flag_views_handlers() { - return array( - 'info' => array( - 'path' => drupal_get_path('module', 'flag') . '/includes', - ), - 'handlers' => array( - 'flag_handler_relationship_content' => array( - 'parent' => 'views_handler_relationship', - 'file' => 'flag_handler_relationships.inc', - ), - 'flag_handler_relationship_counts' => array( - 'parent' => 'views_handler_relationship', - 'file' => 'flag_handler_relationships.inc', - ), - 'flag_handler_relationship_user_content' => array( - 'parent' => 'views_handler_relationship', - 'file' => 'flag_handler_relationships.inc', - ), - 'flag_handler_field_ops' => array( - 'parent' => 'views_handler_field', - ), - 'flag_handler_filter_flagged' => array( - 'parent' => 'views_handler_filter_boolean_operator', - ), - 'flag_handler_argument_content_id' => array( - 'parent' => 'views_handler_argument_numeric', - ), - ), - ); -} - /** * Implements hook_views_plugins(). */ From 122968e7585404e7c29873b58590020a2e946493 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 23 Jul 2012 22:00:15 +0100 Subject: [PATCH 079/629] Issue #1331614 by q0rban, fangel: Added uid on flag_content table as argument, field, and filter in Views. --- includes/flag.views.inc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/includes/flag.views.inc b/includes/flag.views.inc index 1fefe95..2c3402d 100644 --- a/includes/flag.views.inc +++ b/includes/flag.views.inc @@ -39,13 +39,24 @@ function flag_views_data() { $data['flag_counts']['table']['group'] = t('Flags'); $data['flag_content']['uid'] = array( - 'title' => t('User'), - 'help' => t('The user that flagged an item.'), + 'title' => t('User uid'), + 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), 'relationship' => array( 'base' => 'users', + 'title' => t('User'), + 'help' => t('Relate an item to the user that flagged it.'), 'handler' => 'views_handler_relationship', 'label' => t('Flag user'), ), + 'filter' => array( + 'handler' => 'views_handler_filter_user_name', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + ), + 'field' => array( + 'handler' => 'views_handler_field_user', + ), ); $data['flag_content']['timestamp'] = array( From 5a227b3686129a4d0826f387fb64115d8ba9c50c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 24 Jul 2012 11:46:05 +0100 Subject: [PATCH 080/629] Issue #1362260 by jaanhoinatski: Fixed user account deletion potentially causing out of bounds PDO error when decrementing flag counts. --- flag.module | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/flag.module b/flag.module index bc2adb0..4569e4f 100644 --- a/flag.module +++ b/flag.module @@ -828,14 +828,23 @@ function flag_user_account_removal($account) { ->execute(); foreach ($result as $flag_data) { - $flag_data->count--; - db_update('flag_counts') - ->fields(array( - 'count' => $flag_data->count, - )) - ->condition('fid', $flag_data->fid) - ->condition('content_id', $flag_data->content_id) - ->execute(); + // Only decrement the flag count table if it's greater than 1. + if ($flag_data->count > 0) { + $flag_data->count--; + db_update('flag_counts') + ->fields(array( + 'count' => $flag_data->count, + )) + ->condition('fid', $flag_data->fid) + ->condition('content_id', $flag_data->content_id) + ->execute(); + } + elseif ($flag_data->count == 0) { + db_delete('flag_counts') + ->condition('fid', $flag_data->fid) + ->condition('content_id', $flag_data->content_id) + ->execute(); + } } db_delete('flag_content') ->condition('uid', $account->uid) From 1941b07bc42537a29a8e50a5e810f3c7e04296e8 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 25 Jul 2012 11:09:05 +0100 Subject: [PATCH 081/629] Issue #1689704 by joachim: Changed flag object to retrieve entity info rather than store it. --- flag.inc | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/flag.inc b/flag.inc index ba2958b..b24dd1e 100644 --- a/flag.inc +++ b/flag.inc @@ -1271,21 +1271,6 @@ class flag_flag { * Base entity flag handler. */ class flag_entity extends flag_flag { - /** - * The entity info for this flag's entity type. - */ - var $entity_info; - - /** - * Default contructor that furthermore loads the entity info for the current - * content_type. (Note content_type is used as synonym for entity_type in this - * handler.) - */ - function construct() { - parent::construct(); - $this->entity_info = entity_get_info($this->content_type); - } - /** * Adds additional options that are common for all entity types. */ @@ -1308,7 +1293,8 @@ class flag_entity extends flag_flag { */ function options_form(&$form) { $bundles = array(); - foreach ($this->entity_info['bundles'] as $bundle_key => $bundle) { + $entity_info = entity_get_info($this->content_type); + foreach ($entity_info['bundles'] as $bundle_key => $bundle) { $bundles[$bundle_key] = check_plain($bundle['label']); } $form['access']['types'] = array( @@ -1350,7 +1336,8 @@ class flag_entity extends flag_flag { * Checks whether the flag applies for the current entity bundle. */ function applies_to_content_object($entity) { - if (empty($this->entity_info['entity keys']['bundle']) || in_array($entity->{$this->entity_info['entity keys']['bundle']}, $this->types)) { + $entity_info = entity_get_info($this->content_type); + if (empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { return TRUE; } return FALSE; @@ -1360,8 +1347,9 @@ class flag_entity extends flag_flag { * Returns the entity id, if it already exists. */ function get_content_id($entity) { - if ($entity && isset($entity->{$this->entity_info['entity keys']['id']})) { - return $entity->{$this->entity_info['entity keys']['id']}; + $entity_info = entity_get_info($this->content_type); + if ($entity && isset($entity->{$entity_info['entity keys']['id']})) { + return $entity->{$entity_info['entity keys']['id']}; } } @@ -1418,13 +1406,14 @@ class flag_entity extends flag_flag { * Returns information for the Views integration. */ function get_views_info() { + $entity_info = entity_get_info($this->content_type); return array( - 'views table' => $this->entity_info['base table'], - 'join field' => $this->entity_info['entity keys']['id'], - 'title field' => isset($this->entity_info['entity keys']['label']) ? $this->entity_info['entity keys']['label'] : '', - 'title' => t('@entity_label flag', array('@entity_label' => $this->entity_info['label'])), + 'views table' => $entity_info['base table'], + 'join field' => $entity_info['entity keys']['id'], + 'title field' => isset($entity_info['entity keys']['label']) ? $entity_info['entity keys']['label'] : '', + 'title' => t('@entity_label flag', array('@entity_label' => $entity_info['label'])), 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), - 'counter title' => t('@entity_label flag counter', array('@entity_label' => $this->entity_info['label'])), + 'counter title' => t('@entity_label flag counter', array('@entity_label' => $entity_info['label'])), 'counter help' => t('Include this to gain access to the flag counter field.'), ); } From 8a39353ba6965ab8613883cb7bda1243305cbbbc Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 25 Jul 2012 11:39:32 +0100 Subject: [PATCH 082/629] by joachim: Added further details to documentation; cleaned up for comment style. --- flag.api.php | 22 ++++++++++++++++++++-- flag.inc | 25 ++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/flag.api.php b/flag.api.php index 3fecb79..3d76825 100644 --- a/flag.api.php +++ b/flag.api.php @@ -139,6 +139,10 @@ function hook_flag($op, $flag, $content_id, $account, $fcid) { * @param $account * The user on whose behalf to test the flagging action. * + * @return + * Boolean TRUE if the user is allowed to flag/unflag the given content. + * FALSE otherwise. + * * @see flag_flag:access() */ function hook_flag_access($flag, $content_id, $action, $account) { @@ -146,9 +150,23 @@ function hook_flag_access($flag, $content_id, $action, $account) { } /** - * TODO + * Allow modules to allow or deny access to flagging. + * + * @param $flag + * The flag object. + * @param $content_ids + * An array of object ids to check access. + * @param $account + * The user on whose behalf to test the flagging action. + * + * @return + * An array whose keys are the object IDs and values are booleans indicating + * access. + * + * @see hook_flag_access() + * @see flag_flag:access_multiple() */ -function hook_flag_access_multiple() { +function hook_flag_access_multiple($flag, $content_ids, $account) { } diff --git a/flag.inc b/flag.inc index b24dd1e..6abd60e 100644 --- a/flag.inc +++ b/flag.inc @@ -286,6 +286,9 @@ class flag_flag { /** * Validates that the current flag's name is valid. + * + * @return + * A list of errors encountered while validating this flag's name. */ function validate_name() { $errors = array(); @@ -388,6 +391,7 @@ class flag_flag { /** * Returns TRUE if the flag applies to the given content. + * * Derived classes must implement this. * * @abstract @@ -408,7 +412,7 @@ class flag_flag { } /** - * Returns TRUE if user has access to use this flag. + * Determines whether the user has access to use this flag. * * @param $action * Optional. The action to test, either "flag" or "unflag". If none given, @@ -434,7 +438,7 @@ class flag_flag { } /** - * Returns TRUE if the user can flag, or unflag, the given content. + * Determines whether the user may flag, or unflag, the given content. * * This method typically should not be overridden by child classes. Instead * they should implement type_access(), which is called by this method. @@ -447,6 +451,10 @@ class flag_flag { * @param $account * The user on whose behalf to test the flagging action. Leave NULL for the * current user. + * + * @return + * Boolean TRUE if the user is allowed to flag/unflag the given content. + * FALSE otherwise. */ function access($content_id, $action = NULL, $account = NULL) { if (!isset($account)) { @@ -486,7 +494,9 @@ class flag_flag { } /** - * Similar to access() but works on multiple IDs at once. It is called in the + * Determine access to multiple objects. + * + * Similar to user_access() but works on multiple IDs at once. Called in the * pre_render() stage of the 'Flag links' field within Views to find out where * that link applies. The reason we do a separate DB query, and not lump this * test in the Views query, is to make 'many to one' tests possible without @@ -502,6 +512,12 @@ class flag_flag { * @param $account * Optional. The account for which the actions will be compared against. * If left empty, the current user will be used. + * + * @return + * An array whose keys are the object IDs and values are booleans indicating + * access. + * + * @see hook_flag_access_multiple() */ function access_multiple($content_ids, $account = NULL) { $account = isset($account) ? $account : $GLOBALS['user']; @@ -599,12 +615,15 @@ class flag_flag { * applicable to the item, etc.), TRUE otherwise. */ function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE) { + // Get the user. if (!isset($account)) { $account = $GLOBALS['user']; } if (!$account) { return FALSE; } + + // Check access and applicability. if (!$skip_permission_check) { if (!$this->access($content_id, $action, $account)) { // User has no permission to flag/unflag this object. From 3f50b5b78eced336d41ef9aa8c56644f9f6eddc3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 25 Jul 2012 14:21:48 +0100 Subject: [PATCH 083/629] by joachim: Added documentation to flag_confirm() form handlers. --- flag.module | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/flag.module b/flag.module index 4569e4f..3f8aad9 100644 --- a/flag.module +++ b/flag.module @@ -1003,6 +1003,12 @@ function flag_page($action, $flag, $content_id) { * * @param $action * Either 'flag' or 'unflag'. + * @param $flag + * A loaded flag object. + * @param $content_id + * The id of the content to operate on. The type is implicit in the flag. + * + * @see flag_confirm_submit() */ function flag_confirm($form, &$form_state, $action, $flag, $content_id) { $form['action'] = array( @@ -1025,6 +1031,14 @@ function flag_confirm($form, &$form_state, $action, $flag, $content_id) { return confirm_form($form, $question, $path, '', $yes); } +/** + * Submit handler for the flag confirm form. + * + * Note that validating whether the user may perform the action is done here, + * rather than in a form validation handler. + * + * @see flag_confirm() + */ function flag_confirm_submit(&$form, &$form_state) { $action = $form_state['values']['action']; $flag_name = $form_state['values']['flag_name']; From b99979e6a3cceb9889dd9dd8c255f70591ebc94a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 26 Jul 2012 16:52:16 +0100 Subject: [PATCH 084/629] by joachim: Added further detail to API docs for hook_flag_options_alter(). --- flag.api.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flag.api.php b/flag.api.php index 3d76825..9ef94ed 100644 --- a/flag.api.php +++ b/flag.api.php @@ -97,6 +97,10 @@ function hook_flag_alter(&$flag) { /** * Alter a flag's default options. * + * Modules that wish to extend flags and provide additional options must declare + * them here so that their additions to the flag admin form are saved into the + * flag object. + * * @param $options * The array of default options for the flag type, with the options for the * flag's link type merged in. From 93fb0a11c53ed445dfcfc4fbde24905fa8c61702 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 09:05:24 +0100 Subject: [PATCH 085/629] Issue #871064 by mooffie, q0rban, ericduran, goron, wroxbox, joachim: Added flaggings as a fieldable entity. --- flag.inc | 119 ++++++++++++++++++++++++++++++++++--- flag.info | 1 + flag.module | 125 ++++++++++++++++++++++++++++++++++++++- flag.rules.inc | 9 +++ flag.tokens.inc | 30 ++++++++++ includes/flag.admin.inc | 5 +- includes/flag.entity.inc | 24 ++++++++ 7 files changed, 302 insertions(+), 11 deletions(-) create mode 100644 includes/flag.entity.inc diff --git a/flag.inc b/flag.inc index 6abd60e..4f73efe 100644 --- a/flag.inc +++ b/flag.inc @@ -610,11 +610,15 @@ class flag_flag { * The user on whose behalf to flag. Leave empty for the current user. * @param $skip_permission_check * Flag the item even if the $account user don't have permission to do so. + * @param $flagging + * Optional. This method works in tandem with Drupal's Field subsystem. + * Pass in a flagging entity if you want operate on it as well. + * * @return * FALSE if some error occured (e.g., user has no permission, flag isn't * applicable to the item, etc.), TRUE otherwise. */ - function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE) { + function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { // Get the user. if (!isset($account)) { $account = $GLOBALS['user']; @@ -658,15 +662,31 @@ class flag_flag { } } + // Set our uid and sid to the flagging object. + if (isset($flagging)) { + $flagging->uid = $uid; + $flagging->sid = $sid; + } + + // @todo: Discuss: Should we call field_attach_validate()? None of the + // entities in core does this (fields entered through forms are already + // validated). + // + // @todo: Discuss: Core wraps everything in a try { }, should we? + // Perform the flagging or unflagging of this flag. - $flagged = $this->_is_flagged($content_id, $uid, $sid); + $existing_fcid = $this->_is_flagged($content_id, $uid, $sid); + $flagged = (bool) $existing_fcid; if ($action == 'unflag') { if ($this->uses_anonymous_cookies()) { $this->_unflag_anonymous($content_id); } if ($flagged) { - $fcid = $this->_unflag($content_id, $uid, $sid); - module_invoke_all('flag', 'unflag', $this, $content_id, $account, $fcid); + // Note the order: We delete the entity before calling _unflag() to + // delete the {flag_content} record. + $this->_delete_flagging($existing_fcid); + $this->_unflag($content_id, $uid, $sid); + module_invoke_all('flag', 'unflag', $this, $content_id, $account, $existing_fcid); } } elseif ($action == 'flag') { @@ -674,14 +694,85 @@ class flag_flag { $this->_flag_anonymous($content_id); } if (!$flagged) { + if (!isset($flagging)) { + // Construct a new flagging object if we don't have one. + $flagging = $this->new_flagging($content_id, $uid, $sid); + } $fcid = $this->_flag($content_id, $uid, $sid); + // We're writing out a flagging entity even when we aren't passed one + // (e.g., when flagging via JavaScript toggle links); in this case + // Field API will assign the fields their default values. + $this->_insert_flagging($flagging, $content_id, $fcid); module_invoke_all('flag', 'flag', $this, $content_id, $account, $fcid); } + else { + // Nothing to do. Item is already flagged. + // + // Except in the case a $flagging object is passed in: in this case + // we're, for example, arriving from an editing form and need to update + // the entity. + if ($flagging) { + $this->_update_flagging($flagging); + } + } } return TRUE; } + /** + * The entity CRUD methods _{insert,update,delete}_flagging() are for private + * use by the flag() method. + * + * The reason programmers should not call them directly is because a flagging + * operation is also accompanied by some bookkeeping (calling hooks, updating + * counters) or access control. These tasks are handled by the flag() method. + */ + private function _insert_flagging($flagging, $content_id, $fcid) { + $flagging->fcid = $fcid; + field_attach_presave('flagging', $flagging); + field_attach_insert('flagging', $flagging); + } + private function _update_flagging($flagging) { + field_attach_presave('flagging', $flagging); + field_attach_update('flagging', $flagging); + // Update the cache. + flagging_load($flagging->fcid, TRUE); + } + private function _delete_flagging($fcid) { + if (($flagging = flagging_load($fcid))) { + field_attach_delete('flagging', $flagging); + // Remove from the cache. + flagging_load($fcid, TRUE); + } + } + + /** + * Construct a new, empty flagging entity object. + * + * @param mixed $content_id + * The unique identifier of the content being flagged. + * @param int $uid + * Optional. The user id of the user doing the flagging. + * @param mixed $sid + * Optional. The user SID (provided by Session API) who is doing the + * flagging. The SID is 0 for logged in users. + * + * @return stdClass + * The returned object has at least the 'flag_name' property set, which + * enables Field API to figure out the bundle, but it's your responsibility + * to eventually populate 'content_id' and 'fcid'. + */ + function new_flagging($content_id = NULL, $uid = NULL, $sid = NULL) { + return (object) array( + 'fcid' => NULL, + 'flag_name' => $this->name, + 'content_id' => $content_id, + 'uid' => $uid, + 'sid' => $sid, + ); + } + /** * Determines if a certain user has flagged this content. * @@ -721,6 +812,15 @@ class flag_flag { return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL; } + /** + * Similar to is_flagged() excepts it returns the flagging entity. + */ + function get_flagging($content_id, $uid = NULL, $sid = NULL) { + if (($record = $this->get_flagging_record($content_id, $uid, $sid))) { + return flagging_load($record->fcid); + } + } + /** * Determines if a certain user has flagged this content. * @@ -946,6 +1046,11 @@ class flag_flag { * token contexts they understand. */ function replace_tokens($label, $contexts, $options, $content_id) { + if (strpos($label , 'flagging:') !== FALSE) { + if (($flagging = $this->get_flagging($content_id))) { + $contexts['flagging'] = $flagging; + } + } return token_replace($label, $contexts, $options); } @@ -957,7 +1062,7 @@ class flag_flag { * Derived classes should override this. */ function get_labels_token_types() { - return array(); + return array('flagging'); } /** @@ -1557,9 +1662,9 @@ class flag_node extends flag_entity { return FALSE; } - function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE) { + function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { $content_id = $this->get_translation_id($content_id); - return parent::flag($action, $content_id, $account, $skip_permission_check); + return parent::flag($action, $content_id, $account, $skip_permission_check, $flagging); } // Instead of overriding is_flagged() we override get_flagging_record(), diff --git a/flag.info b/flag.info index 6933238..23e9009 100644 --- a/flag.info +++ b/flag.info @@ -6,6 +6,7 @@ configure = admin/structure/flags ; Files that contain classes. files[] = flag.inc +files[] = includes/flag.entity.inc files[] = flag.rules.inc files[] = includes/flag_handler_argument_content_id.inc files[] = includes/flag_handler_field_ops.inc diff --git a/flag.module b/flag.module index 3f8aad9..5d69b73 100644 --- a/flag.module +++ b/flag.module @@ -21,6 +21,84 @@ define('FLAG_ADMIN_PATH_START', 3); include_once dirname(__FILE__) . '/flag.inc'; +/** + * Implements hook_entity_info(). + */ +function flag_entity_info() { + $return = array( + 'flagging' => array( + 'label' => t('Flagging'), + 'controller class' => 'FlaggingController', + 'base table' => 'flag_content', + 'fieldable' => TRUE, + 'entity keys' => array( + 'id' => 'fcid', + 'bundle' => 'flag_name', + ), + // The following tells Field UI how to extract the bundle name from a + // $flag object when we're visiting ?q=admin/.../manage/%flag/fields. + 'bundle keys' => array( + 'bundle' => 'name', + ), + 'bundles' => array(), + ), + ); + + foreach (flag_get_flags(NULL, NULL, NULL, TRUE) as $flag) { + $return['flagging']['bundles'][$flag->name] = array( + 'label' => $flag->title, + 'admin' => array( + 'path' => FLAG_ADMIN_PATH . '/manage/%flag', + 'real path' => FLAG_ADMIN_PATH . '/manage/' . $flag->name, + 'bundle argument' => FLAG_ADMIN_PATH_START + 1, + 'access arguments' => array('administer flags'), + ), + ); + } + + return $return; +} + +/** + * Loads a flagging entity. + * + * @param $fcid + * The 'fcid' database serial column. + * @param $reset + * Whether to reset the DrupalDefaultEntityController cache. + * + * @return + * The entity object, or FALSE if it can't be found. + */ +function flagging_load($fcid, $reset = FALSE) { + $result = entity_load('flagging', array($fcid), array(), $reset); + return reset($result); +} + +// @todo: Implement flagging_save(). It's not required but other modules may expect it. + +// @todo: Implement flagging_view(). Not extremely useful. I already have it. + +// @todo: When renaming a flag: Call field_attach_rename_bundle(). + +// @todo: When creating a flag: Call field_attach_create_bundle(). + +// @todo: When deleting a flag: Call field_attach_delete_bundle(). + +// @tood: Discuss: Should flag deleting call flag_reset_flag()? No. + +// @todo: flag_reset_flag(): +// - it should delete the flaggings. +// - (it has other issues; see http://drupal.org/node/894992.) +// - (is problematic: it might not be possible to delete all data in a single page request.) + +// @todo: Discuss: Note that almost all functions/identifiers dealing with +// flaggings *aren't* prefixed by "flag_". For example: +// - The menu argument is %flagging, not %flag_flagging. +// - The entity type is "flagging", not "flag_flagging". +// On the one hand this succinct version is readable and nice. On the other hand, it isn't +// very "correct". + /** * Implements hook_menu(). */ @@ -178,6 +256,23 @@ function flag_help($path, $arg) { case FLAG_ADMIN_PATH: $output = '

' . t('This page lists all the flags that are currently defined on this system.') . '

'; return $output; + case FLAG_ADMIN_PATH . '/manage/%/fields': + $output = '

' . t('Flags can have fields added to them. For example, a "Spam" flag could have a Reason field where a user could type in why he believes the item flagged is spam. A "Bookmarks" flag could have a Folder field into which a user could arrange her bookmarks.') . '

'; + $output .= '

' . t('On this page you can add fields to flags, delete them, and otherwise manage them.') . '

'; + $output .= '

'; + $output .= t('You will also want to pick either the "Confirmation form" or the "Form" link type for your flag, or else users won\'t have a means to enter values for the fields. (In case a form isn\'t used, the fields are assigned their default values.)', array( + '@form-link-type-url' => url('admin/structure/flags/manage/' . $arg[4], array('fragment' => 'edit-link-type')), + )); + if (!module_exists('flag_form')) { + $output .= ' ' + . t("Note: You don't have the Flagging Form module enabled. You'll have to enable it to have the \"Form\" link-type.", array( + '@enable-url' => url('admin/modules'), + '@flagging-form-url' => 'http://drupal.org/project/flagging_form', + )) + . ''; + } + $output .= '

'; + return $output; } } @@ -1028,6 +1123,14 @@ function flag_confirm($form, &$form_state, $action, $flag, $content_id) { $path = isset($_GET['destination']) ? $_GET['destination'] : ''; $yes = $flag->get_label($action . '_short', $content_id); + if ($action == 'flag') { + // If the action 'flag', we're potentially about to create a new + // flagging entity. We need an empty new entity to pass to FieldAPI. + $flagging = $flag->new_flagging($content_id); + field_attach_form('flagging', $flagging, $form, $form_state); + $form['#flagging'] = $flagging; + } + return confirm_form($form, $question, $path, '', $yes); } @@ -1044,12 +1147,23 @@ function flag_confirm_submit(&$form, &$form_state) { $flag_name = $form_state['values']['flag_name']; $content_id = $form_state['values']['content_id']; - $result = flag($action, $flag_name, $content_id); + $flag = flag_get_flag($flag_name); + + if ($action == 'flag') { + // If the action 'flag', further build up the new entity from form values. + $flagging = $form['#flagging']; + entity_form_submit_build_entity('flagging', $flagging, $form, $form_state); + + $result = $flag->flag($action, $content_id, NULL, FALSE, $flagging); + } + else { + $result = $flag->flag($action, $content_id, NULL, FALSE); + } + if (!$result) { drupal_set_message(t('You are not allowed to flag, or unflag, this content.')); } else { - $flag = flag_get_flag($flag_name); drupal_set_message($flag->get_label($action . '_message', $content_id)); } } @@ -1104,7 +1218,12 @@ function flag_flag($action, $flag, $content_id, $account) { $event_name = ($action == 'flag' ? 'flag_flagged_' : 'flag_unflagged_') . $flag->name; // We only support flags on entities. if (entity_get_info($flag->content_type)) { - $variables = array('flag' => $flag, 'flagged_' . $flag->content_type => $content_id, 'flagging_user' => $account); + $variables = array( + 'flag' => $flag, + 'flagged_' . $flag->content_type => $content_id, + 'flagging_user' => $account, + 'flagging' => $flag->get_flagging($content_id,$account->uid), + ); rules_invoke_event_by_args($event_name, $variables); } } diff --git a/flag.rules.inc b/flag.rules.inc index 75c5d37..a50d8bf 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -17,6 +17,11 @@ function flag_rules_data_info() { 'wrapper class' => 'FlagRulesDataWrapper', 'wrap' => TRUE, ), + 'flagging' => array( + 'label' => t('flagging'), + 'parent' => 'entity', + 'group' => t('flag'), + ), ); } @@ -134,6 +139,10 @@ function flag_rules_event_info() { 'type' => 'user', 'label' => t('flagging user'), ), + 'flagging' => array( + 'type' => 'flagging', + 'label' => t('flagging'), + ), ); // For each flag we define two events. diff --git a/flag.tokens.inc b/flag.tokens.inc index e6707cf..64f15e9 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -27,6 +27,22 @@ function flag_token_info() { 'description' => t('The human-readable flag title.'), ); + // Flagging tokens. + // + // Attached fields are exposed as tokens via some contrib module, but we + // need to expose other fields ourselves. Currently, 'date' is the only such + // field we expose. + $types['flagging'] = array( + 'name' => t('Flaggings'), + 'description' => t('Tokens related to flaggings.'), + 'needs-data' => 'flagging', + ); + $tokens['flagging']['date'] = array( + 'name' => t('Flagging date'), + 'description' => t('The date an item was flagged.'), + 'type' => 'date', + ); + // Flage action tokens. $types['flag-action'] = array( 'name' => t('Flag actions'), @@ -85,6 +101,7 @@ function flag_token_info() { function flag_tokens($type, $tokens, array $data = array(), array $options = array()) { $replacements = array(); $sanitize = !empty($options['sanitize']); + $langcode = isset($options['language']) ? $options['language']->language : NULL; if ($type == 'flag' && !empty($data['flag'])) { $flag = $data['flag']; @@ -99,6 +116,19 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr } } } + elseif ($type == 'flagging' && !empty($data['flagging'])) { + $flagging = $data['flagging']; + foreach ($tokens as $name => $original) { + switch ($name) { + case 'date': + $replacements[$original] = format_date($flagging->timestamp, 'medium', '', NULL, $langcode); + break; + } + } + if ($date_tokens = token_find_with_prefix($tokens, 'date')) { + $replacements += token_generate('date', $date_tokens, array('date' => $flagging->timestamp), $options); + } + } elseif ($type == 'flag-action' && !empty($data['flag-action'])) { $action = $data['flag-action']; foreach ($tokens as $name => $original) { diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index e1039b9..0aa6066 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -67,10 +67,13 @@ function theme_flag_admin_listing($variables) { foreach ($flags as $flag) { $ops = array( 'flags_edit' => array('title' => t('edit'), 'href' => $flag->admin_path('edit')), + 'flags_fields' => array('title' => t('manage fields'), 'href' => $flag->admin_path('fields')), 'flags_delete' => array('title' => t('delete'), 'href' => $flag->admin_path('delete')), 'flags_export' => array('title' => t('export'), 'href' => $flag->admin_path('export')), ); - + if (!module_exists('field_ui')) { + unset($ops['flags_fields']); + } $roles = array_flip(array_intersect(array_flip(user_roles()), $flag->roles['flag'])); $row = array( $flag->name, diff --git a/includes/flag.entity.inc b/includes/flag.entity.inc new file mode 100644 index 0000000..6fee9b5 --- /dev/null +++ b/includes/flag.entity.inc @@ -0,0 +1,24 @@ +flaggings fieldable, not the flags. + * (In the same way that Drupal makes nodes fieldable, not node + * types). + */ + +/** + * Controller class for flaggings. + */ +class FlaggingController extends DrupalDefaultEntityController { + + protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { + $query = parent::buildQuery($ids, $conditions, $revision_id); + // Add the flag name, which determines the bundle. + $query->innerJoin('flags', 'flags', 'base.fid = flags.fid'); + $query->addField('flags', 'name', 'flag_name'); + return $query; + } +} From 99ea9cbb3d94f5dd3994ae2fbb846dd95bfa5b18 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 09:22:28 +0100 Subject: [PATCH 086/629] by joachim: Added API documentation to hook_flag_link(). --- flag.api.php | 90 +++++++++++++++++++++++++++++++++------------------- flag.module | 14 -------- 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/flag.api.php b/flag.api.php index 9ef94ed..452d9e1 100644 --- a/flag.api.php +++ b/flag.api.php @@ -46,38 +46,6 @@ function hook_flag_definitions_alter(&$definitions) { } -/** - * Define one or more flag link types. - * - * @see flag_get_link_types() - * @see hook_flag_link_types_alter() - * - * @return - * An array of one or more types, keyed by the machine name of the type, and - * where each value is a link type definition as an array with the following - * properties: - * - 'title': The human-readable name of the type. - * - 'description': The description of the link type. - * - 'options': An array of extra options for the link type. - * - 'uses standard js': Boolean, indicates whether the link requires Flag - * module's own JS file for links. - * - 'uses standard css': Boolean, indicates whether the link requires Flag - * module's own CSS file for links. - */ -function hook_flag_link_types() { - -} - -/** - * Alter other modules' definitions of flag link types. - * - * @see flag_get_link_types() - * @see hook_flag_link_types() - */ -function hook_flag_link_types_alter(&$link_types) { - -} - /** * Define default flags. */ @@ -175,7 +143,65 @@ function hook_flag_access_multiple($flag, $content_ids, $account) { } /** + * Define one or more flag link types. + * + * Link types defined here must be returned by this module's hook_flag_link(). * + * @return + * An array of one or more types, keyed by the machine name of the type, and + * where each value is a link type definition as an array with the following + * properties: + * - 'title': The human-readable name of the type. + * - 'description': The description of the link type. + * - 'options': An array of extra options for the link type. + * - 'uses standard js': Boolean, indicates whether the link requires Flag + * module's own JS file for links. + * - 'uses standard css': Boolean, indicates whether the link requires Flag + * module's own CSS file for links. + * + * @see flag_get_link_types() + * @see hook_flag_link_types_alter() + */ +function hook_flag_link_types() { + +} + +/** + * Alter other modules' definitions of flag link types. + * + * @param $link_types + * An array of the link types defined by all modules. + * + * @see flag_get_link_types() + * @see hook_flag_link_types() + */ +function hook_flag_link_types_alter(&$link_types) { + +} + +/** + * Return the link for the link types this module defines. + * + * The type of link to be produced is given by $flag->link_type. + * + * When Flag uses a link type provided by this module, it will call this + * implementation of hook_flag_link(). This should return a single link's + * attributes, using the same structure as hook_link(). Note that "title" is + * provided by the Flag configuration if not specified here. + * + * @param $flag + * The full flag object for the flag link being generated. + * @param $action + * The action this link should perform. Either 'flag' or 'unflag'. + * @param $content_id + * The ID of the node, comment, user, or other object being flagged. The type + * of the object can be deduced from the flag type. + * + * @return + * An array defining properties of the link. + * + * @see hook_flag_link_types() + * @see template_preprocess_flag() */ function hook_flag_link() { diff --git a/flag.module b/flag.module index 5d69b73..6490599 100644 --- a/flag.module +++ b/flag.module @@ -368,20 +368,6 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { /** * Implements hook_flag_link(). - * - * When Flag uses a link type provided by this module, it will call this - * implementation of hook_flag_link(). It returns a single link's attributes, - * using the same structure as hook_link(). Note that "title" is provided by - * the Flag configuration if not specified here. - * - * @param $flag - * The full flag object of for the flag link being generated. - * @param $action - * The action this link will perform. Either 'flag' or 'unflag'. - * @param $content_id - * The ID of the node, comment, user, or other object being flagged. - * @return - * An array defining properties of the link. */ function flag_flag_link($flag, $action, $content_id) { $token = flag_get_token($content_id); From 9e1f031a3af808f72540017b00bbbb75576d00e4 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 12:50:39 +0100 Subject: [PATCH 087/629] Issue #926252 by mooffie, snufkin: Added hook_flag_javascript_info_alter() to alter JavaScript info building and helper function to invoke it. --- flag.api.php | 13 +++++++++++++ flag.module | 27 ++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/flag.api.php b/flag.api.php index 452d9e1..f48f23e 100644 --- a/flag.api.php +++ b/flag.api.php @@ -221,3 +221,16 @@ function hook_flag_reset() { } +/** + * Alter the javascript structure that describes the flag operation. + * + * @param $flag + * The full flag object. + * @param $content_id + * The ID of the node, comment, user or other object being flagged. + * + * @see flag_build_javascript_info() + */ +function hook_flag_javascript_info_alter() { + +} diff --git a/flag.module b/flag.module index 6490599..3996704 100644 --- a/flag.module +++ b/flag.module @@ -1062,15 +1062,7 @@ function flag_page($action, $flag, $content_id) { if ($js) { drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); $flag->link_type = 'toggle'; - print drupal_json_encode(array( - 'status' => TRUE, - 'newLink' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id, TRUE), - // Further information for the benefit of custom JavaScript event handlers: - 'contentId' => $content_id, - 'contentType' => $flag->content_type, - 'flagName' => $flag->name, - 'flagStatus' => $flag->is_flagged($content_id) ? 'flagged' : 'unflagged', - )); + print drupal_json_encode(flag_build_javascript_info($flag, $content_id)); drupal_exit(); } else { @@ -1079,6 +1071,23 @@ function flag_page($action, $flag, $content_id) { } } +/** + * Builds the JavaScript structure describing the flagging operation. + */ +function flag_build_javascript_info($flag, $content_id) { + $info = array( + 'status' => TRUE, + 'newLink' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id, TRUE), + // Further information for the benefit of custom JavaScript event handlers: + 'contentId' => $content_id, + 'contentType' => $flag->content_type, + 'flagName' => $flag->name, + 'flagStatus' => $flag->is_flagged($content_id) ? 'flagged' : 'unflagged', + ); + drupal_alter('flag_javascript_info', $info); + return $info; +} + /** * Form for confirming the (un)flagging of a piece of content. * From aa3bbd27cfda3348fbc0de8aa00fde2265b932b8 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 13:00:21 +0100 Subject: [PATCH 088/629] Issue #1693644 by snufkin, canucked: Fixed flag_reset_flag() not updating the {flag_counts} table. --- flag.module | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flag.module b/flag.module index 3996704..12b6298 100644 --- a/flag.module +++ b/flag.module @@ -1386,9 +1386,13 @@ function flag_reset_flag($flag, $content_id = NULL) { module_invoke_all('flag_reset', $flag, $content_id, $rows); $query = db_delete('flag_content')->condition('fid' , $flag->fid); + // Update the flag_counts table. + $count_query = db_delete('flag_counts')->condition('fid', $flag->fid); if ($content_id) { $query->condition('content_id', $content_id); + $count_query->condition('content_id', $content_id); } + $count_query->execute(); return $query->execute(); } From d4c09485404ee2e0207f4f1f078a31db4afdb8a9 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 13:07:55 +0100 Subject: [PATCH 089/629] Issue #1701208 by firfin, snufkin: Added Rules action to get nodes flagged by a user. --- flag.rules.inc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/flag.rules.inc b/flag.rules.inc index a50d8bf..fcdfa40 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -190,6 +190,29 @@ function flag_rules_action_info() { 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), + 'flag_fetch_entity_by_user' => array( + 'label' => t('Fetch content flagged by user'), + 'base' => 'flag_rules_action_fetch_entity_by_user', + 'parameter' => array( + 'flag' => array( + 'type' => 'flag', + 'label' => t('Flag'), + ), + 'flagging_user' => array( + 'type' => 'user', + 'label' => t('User who flagged the content'), + 'description' => t('For non-global flags, this is the user who flagged the content. (For global flags, this argument is ignored.)'), + ), + ), + 'provides' => array( + 'content_flagged_by_user' => array( + 'label' => t('Content flagged by user'), + 'type' => 'list', + ), + ), + 'group' => t('Flag'), + 'access callback' => 'flag_rules_integration_access', + ), ); $param_defaults = array( 'flagging_user' => array( @@ -309,6 +332,21 @@ function flag_rules_action_fetch_users($flag, $entity) { return array('users' => array_filter($uids)); } +/** + * Base action implementation: Fetch entities who were flagged a user. + */ +function flag_rules_action_fetch_entity_by_user($flag, $user) { + $result = db_select('flag_content', 'fc') + ->fields('fc', array('content_id')) + ->condition('content_type', $flag->content_type) + ->condition('uid', $user->uid) + ->condition('fid', $flag->fid) + ->execute(); + + $flagged = $result->fetchCol(); + return array('content_flagged_by_user' => $flagged); +} + /** * Implements hook_rules_condition_info(). */ From 5b5d754a8a7a71885088530308c4d88205f93a52 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 13:18:58 +0100 Subject: [PATCH 090/629] Issue #1650512 by dsnopek, snufkin: Added index to {flag_content} to improve Views performance. --- flag.install | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/flag.install b/flag.install index 782b291..79e72ad 100644 --- a/flag.install +++ b/flag.install @@ -254,6 +254,7 @@ function flag_schema() { 'indexes' => array( 'content_type_uid_sid' => array('content_type', 'uid', 'sid'), 'content_type_content_id_uid_sid' => array('content_type', 'content_id', 'uid', 'sid'), + 'content_id_fid' => array('content_id', 'fid'), ), ); @@ -479,3 +480,10 @@ function flag_update_7202() { db_query("DELETE FROM {flag_counts} WHERE content_type = 'comment' AND NOT EXISTS (SELECT 1 FROM {comment} c WHERE content_id = c.cid)"); } } + +/** + * Add an index to help with view's flag_handler_relationship when not required. + */ +function flag_update_7203() { + db_add_index('flag_content', 'content_id_fid', array('content_id', 'fid')); +} From 6240d4fdf7470971a6bfa8ac96aebf6b6eb5f6ab Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 13:23:02 +0100 Subject: [PATCH 091/629] Issue #1395034 by Amitaibu: Fixed flag_get_content_flags() static cache not cleared on flag. --- flag.inc | 1 + flag.module | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flag.inc b/flag.inc index 4f73efe..414a9e5 100644 --- a/flag.inc +++ b/flag.inc @@ -646,6 +646,7 @@ class flag_flag { // wrong counts or false flaggings. flag_get_counts(NULL, NULL, TRUE); flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_content_flags'); // Find out which user id to use. $uid = $this->global ? 0 : $account->uid; diff --git a/flag.module b/flag.module index 12b6298..8d4fcb8 100644 --- a/flag.module +++ b/flag.module @@ -2044,18 +2044,17 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si * The content ID to check for flagging. * @param $flag_name * Optional. The name of a flag if wanting a list specific to a single flag. - * @param $reset - * Reset the internal cache of flagged content. + * * @return * If no flag name is given, an array of flagged content, keyed by the user * ID that flagged the content. Each flagged content array is structured as * an array of flag information for each flag, keyed by the flag name. If * a flag name is specified, only the information for that flag is returned. */ -function flag_get_content_flags($content_type, $content_id, $flag_name = NULL, $reset = FALSE) { - static $content_flags; +function flag_get_content_flags($content_type, $content_id, $flag_name = NULL) { + $content_flags = &drupal_static(__FUNCTION__, array()); - if (!isset($content_flags[$content_type][$content_id]) || $reset) { + if (!isset($content_flags[$content_type][$content_id])) { $flag_names = _flag_get_flag_names(); $result = db_select('flag_content', 'fc') ->fields('fc') From 64f36a5549d2b83fa209798835d3cfc695f52333 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 27 Jul 2012 20:21:52 +0100 Subject: [PATCH 092/629] Issue #1699328 by socketwench: Moved the bookmark flag to its own sub-module. --- flag.install | 51 --------------- flag_bookmark/flag_bookmark.info | 5 ++ flag_bookmark/flag_bookmark.install | 65 +++++++++++++++++++ flag_bookmark/flag_bookmark.module | 19 ++++++ .../includes/flag_bookmark.views_default.inc | 2 +- 5 files changed, 90 insertions(+), 52 deletions(-) create mode 100644 flag_bookmark/flag_bookmark.info create mode 100644 flag_bookmark/flag_bookmark.install create mode 100644 flag_bookmark/flag_bookmark.module rename includes/flag.views_default.inc => flag_bookmark/includes/flag_bookmark.views_default.inc (99%) diff --git a/flag.install b/flag.install index 79e72ad..48f223b 100644 --- a/flag.install +++ b/flag.install @@ -26,57 +26,6 @@ function flag_uninstall() { drupal_set_message(t('Flag has been uninstalled.')); } -/** - * Implements hook_enable(). - * - * We create the demonstration flag on enable, so hook implementations in flag - * module will fire correctly, as the APIs are not available on install. - */ -function flag_enable() { - // Load the flag API in case we want to use it when enabling. - include_once(drupal_get_path('module', 'flag') . '/flag.module'); - - if (!flag_get_flags()) { - // Install a demonstration flag only if no flag exists. This is to prevent - // a case where a disables and enables the module, and the demonstration - // flag is overwritten or re-created. - $flag = flag_flag::factory_by_content_type('node'); - $configuration = array( - 'name' => 'bookmarks', - 'global' => 0, - 'show_on_page' => 1, - 'show_on_teaser' => 1, - 'show_on_form' => 1, - // The following UI labels aren't wrapped in t() because they are written - // to the DB in English. They are passed to t() later, thus allowing for - // multilingual sites. - 'title' => 'Bookmarks', - 'flag_short' => 'Bookmark this', - 'flag_long' => 'Add this post to your bookmarks', - 'flag_message' => 'This post has been added to your bookmarks', - 'unflag_short' => 'Unbookmark this', - 'unflag_long' => 'Remove this post from your bookmarks', - 'unflag_message' => 'This post has been removed from your bookmarks', - 'types' => _flag_install_get_suggested_node_types(), - ); - $flag->form_input($configuration); - $flag->save(); - } -} - -/** - * Returns some node types to which the demonstration 'bookmarks' flag will apply. - */ -function _flag_install_get_suggested_node_types() { - $preferred = array('article', 'story', 'forum', 'blog'); - $existing = array_intersect($preferred, array_keys(node_type_get_types())); - if (!$existing) { - // As a last resort, take the first preference. - return array($preferred[0]); - } - return $existing; -} - /** * Implements hook_requirements(). * diff --git a/flag_bookmark/flag_bookmark.info b/flag_bookmark/flag_bookmark.info new file mode 100644 index 0000000..6c16066 --- /dev/null +++ b/flag_bookmark/flag_bookmark.info @@ -0,0 +1,5 @@ +name = Flag Bookmark +description = Provides an example bookmark flag and supporting views. +core = 7.x +dependencies[] = flag +package = Flags diff --git a/flag_bookmark/flag_bookmark.install b/flag_bookmark/flag_bookmark.install new file mode 100644 index 0000000..38c9f47 --- /dev/null +++ b/flag_bookmark/flag_bookmark.install @@ -0,0 +1,65 @@ + 'bookmarks', + 'global' => 0, + 'show_on_page' => 1, + 'show_on_teaser' => 1, + 'show_on_form' => 1, + // The following UI labels aren't wrapped in t() because they are written + // to the DB in English. They are passed to t() later, thus allowing for + // multilingual sites. + 'title' => 'Bookmarks', + 'flag_short' => 'Bookmark this', + 'flag_long' => 'Add this post to your bookmarks', + 'flag_message' => 'This post has been added to your bookmarks', + 'unflag_short' => 'Unbookmark this', + 'unflag_long' => 'Remove this post from your bookmarks', + 'unflag_message' => 'This post has been removed from your bookmarks', + 'types' => _flag_bookmark_install_get_suggested_node_types(), + ); + $flag->form_input($configuration); + $flag->save(); + } +} + +/** + * Returns some node types to which the demonstration 'bookmarks' flag will apply. + */ +function _flag_bookmark_install_get_suggested_node_types() { + $preferred = array('article', 'story', 'forum', 'blog'); + $existing = array_intersect($preferred, array_keys(node_type_get_types())); + if (!$existing) { + // As a last resort, take the first preference. + return array($preferred[0]); + } + return $existing; +} + diff --git a/flag_bookmark/flag_bookmark.module b/flag_bookmark/flag_bookmark.module new file mode 100644 index 0000000..d182cf4 --- /dev/null +++ b/flag_bookmark/flag_bookmark.module @@ -0,0 +1,19 @@ + 2.0, + 'path' => drupal_get_path('module', 'flag_bookmark') . '/includes', + ); +} diff --git a/includes/flag.views_default.inc b/flag_bookmark/includes/flag_bookmark.views_default.inc similarity index 99% rename from includes/flag.views_default.inc rename to flag_bookmark/includes/flag_bookmark.views_default.inc index f57a916..6673b11 100644 --- a/includes/flag.views_default.inc +++ b/flag_bookmark/includes/flag_bookmark.views_default.inc @@ -8,7 +8,7 @@ /** * Implements hook_views_default_views(). */ -function flag_views_default_views() { +function flag_bookmark_views_default_views() { // Only setup views for the "bookmarks" flag. // If it's been deleted, don't create any views. $flag = flag_get_flag('bookmarks'); From 3aebd64322714647369da666108b59b935f7b136 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 28 Jul 2012 18:21:09 +0100 Subject: [PATCH 093/629] Issue #1650512, follow-up, by joachim: Added check for existence prior to adding new index to {flag_content}. --- flag.install | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 48f223b..665c4fa 100644 --- a/flag.install +++ b/flag.install @@ -434,5 +434,8 @@ function flag_update_7202() { * Add an index to help with view's flag_handler_relationship when not required. */ function flag_update_7203() { - db_add_index('flag_content', 'content_id_fid', array('content_id', 'fid')); + // Skip if this index was also added by the 6.x-2.x branch. + if (!db_index_exists('flag_content', 'content_id_fid')) { + db_add_index('flag_content', 'content_id_fid', array('content_id', 'fid')); + } } From 53596dc23a41c5639f666166adfe6f583542a209 Mon Sep 17 00:00:00 2001 From: Tess Date: Sat, 28 Jul 2012 18:50:16 -0500 Subject: [PATCH 094/629] Issue #1699752 by joachim, socketwench: split flag.inc into different classes --- flag.inc | 1969 ------------------------------ flag.info | 9 +- flag.install | 7 + includes/flag.cookie_storage.inc | 170 +++ includes/flag/flag_comment.inc | 112 ++ includes/flag/flag_entity.inc | 158 +++ includes/flag/flag_flag.inc | 1299 ++++++++++++++++++++ includes/flag/flag_node.inc | 155 +++ includes/flag/flag_user.inc | 106 ++ 9 files changed, 2015 insertions(+), 1970 deletions(-) create mode 100644 includes/flag.cookie_storage.inc create mode 100644 includes/flag/flag_comment.inc create mode 100644 includes/flag/flag_entity.inc create mode 100644 includes/flag/flag_flag.inc create mode 100644 includes/flag/flag_node.inc create mode 100644 includes/flag/flag_user.inc diff --git a/flag.inc b/flag.inc index 414a9e5..9e91db9 100644 --- a/flag.inc +++ b/flag.inc @@ -1,11 +1,5 @@ content_type); - - // Lump all data unto the object... - foreach ($row as $field => $value) { - $flag->$field = $value; - } - // ...but skip the following two. - unset($flag->options, $flag->type); - - // Populate the options with the defaults. - $options = (array) unserialize($row->options); - $options += $flag->options(); - - // Make the unserialized options accessible as normal properties. - foreach ($options as $option => $value) { - $flag->$option = $value; - } - - if (!empty($row->type)) { - // The loop loading from the database should further populate this property. - $flag->types[] = $row->type; - } - - return $flag; - } - - /** - * Create a complete flag (except an FID) from an array definition. - */ - static function factory_by_array($config) { - $flag = flag_create_handler($config['content_type']); - - foreach ($config as $option => $value) { - $flag->$option = $value; - } - - if (isset($config['locked']) && is_array($config['locked'])) { - $flag->locked = drupal_map_assoc($config['locked']); - } - - return $flag; - } - - /** - * Another factory method. Returns a new, "empty" flag; e.g., one suitable for - * the "Add new flag" page. - */ - static function factory_by_content_type($content_type) { - return flag_create_handler($content_type); - } - - /** - * Declares the options this flag supports, and their default values. - * - * Derived classes should want to override this. - */ - function options() { - $options = array( - // The text for the "flag this" link for this flag. - 'flag_short' => '', - // The description of the "flag this" link. - 'flag_long' => '', - // Message displayed after flagging content. - 'flag_message' => '', - // Likewise but for unflagged. - 'unflag_short' => '', - 'unflag_long' => '', - 'unflag_message' => '', - 'unflag_denied_text' => '', - // The link type used by the flag, as defined in hook_flag_link_types(). - 'link_type' => 'toggle', - 'roles' => array( - 'flag' => array(DRUPAL_AUTHENTICATED_RID), - 'unflag' => array(DRUPAL_AUTHENTICATED_RID), - ), - 'weight' => 0, - ); - - // Merge in options from the current link type. - $link_type = $this->get_link_type(); - $options = array_merge($options, $link_type['options']); - - // Allow other modules to change the flag options. - drupal_alter('flag_options', $options, $this); - return $options; - } - /** - * Provides a form for setting options. - * - * Derived classes should want to override this. - */ - function options_form(&$form) { - } - - /** - * Default constructor. Loads the default options. - */ - function construct() { - $options = $this->options(); - foreach ($options as $option => $value) { - $this->$option = $value; - } - } - - /** - * Update the flag with settings entered in a form. - */ - function form_input($form_values) { - // Load the form fields indiscriminately unto the flag (we don't care about - // stray FormAPI fields because we aren't touching unknown properties anyway. - foreach ($form_values as $field => $value) { - $this->$field = $value; - } - // But checkboxes need some massaging: - $this->roles['flag'] = array_values(array_filter($this->roles['flag'])); - $this->roles['unflag'] = array_values(array_filter($this->roles['unflag'])); - $this->types = array_values(array_filter($this->types)); - // Clear internal titles cache: - $this->get_title(NULL, TRUE); - } - - /** - * Validates this flag's options. - * - * @return - * A list of errors encountered while validating this flag's options. - */ - function validate() { - // TODO: It might be nice if this used automatic method discovery rather - // than hard-coding the list of validate functions. - return array_merge_recursive( - $this->validate_name(), - $this->validate_access() - ); - } - - /** - * Validates that the current flag's name is valid. - * - * @return - * A list of errors encountered while validating this flag's name. - */ - function validate_name() { - $errors = array(); - - // Ensure a safe machine name. - if (!preg_match('/^[a-z_][a-z0-9_]*$/', $this->name)) { - $errors['name'][] = array( - 'error' => 'flag_name_characters', - 'message' => t('The flag name may only contain lowercase letters, underscores, and numbers.'), - ); - } - // Ensure the machine name is unique. - $flag = flag_get_flag($this->name); - if (!empty($flag) && (!isset($this->fid) || $flag->fid != $this->fid)) { - $errors['name'][] = array( - 'error' => 'flag_name_unique', - 'message' => t('Flag names must be unique. This flag name is already in use.'), - ); - } - - return $errors; - } - - /** - * Validates that the current flag's access settings are valid. - */ - function validate_access() { - $errors = array(); - - // Require an unflag access denied message a role is not allowed to unflag. - if (empty($this->unflag_denied_text)) { - foreach ($this->roles['flag'] as $key => $rid) { - if ($rid && empty($this->roles['unflag'][$key])) { - $errors['unflag_denied_text'][] = array( - 'error' => 'flag_denied_text_required', - 'message' => t('The "Unflag not allowed text" is required if any user roles are not allowed to unflag.'), - ); - break; - } - } - } - - // Do not allow unflag access without flag access. - foreach ($this->roles['unflag'] as $key => $rid) { - if ($rid && empty($this->roles['flag'][$key])) { - $errors['roles'][] = array( - 'error' => 'flag_roles_unflag', - 'message' => t('Any user role that has the ability to unflag must also have the ability to flag.'), - ); - break; - } - } - - return $errors; - } - - /** - * Fetches, possibly from some cache, a content object this flag works with. - */ - function fetch_content($content_id, $object_to_remember = NULL) { - static $cache = array(); - if (isset($object_to_remember)) { - $cache[$content_id] = $object_to_remember; - } - if (!array_key_exists($content_id, $cache)) { - $content = $this->_load_content($content_id); - $cache[$content_id] = $content ? $content : NULL; - } - return $cache[$content_id]; - } - - /** - * Loads a content object this flag works with. - * Derived classes must implement this. - * - * @abstract - * @private - * @static - */ - function _load_content($content_id) { - return NULL; - } - - /** - * Stores some object in fetch_content()'s cache, so subsequenet calls to - * fetch_content() return it. - * - * This is needed because otherwise fetch_object() loads the object from the - * database (by calling _load_content()), whereas sometimes we want to fetch - * an object that hasn't yet been saved to the database. See flag_nodeapi(). - */ - function remember_content($content_id, $object) { - $this->fetch_content($content_id, $object); - } - - /** - * @defgroup access Access control - * @{ - */ - - /** - * Returns TRUE if the flag applies to the given content. - * - * Derived classes must implement this. - * - * @abstract - */ - function applies_to_content_object($content) { - return FALSE; - } - - /** - * Returns TRUE if the flag applies to the content with the given ID. - * - * This is a convenience method that simply loads the object and calls - * applies_to_content_object(). If you already have the object, don't call - * this function: call applies_to_content_object() directly. - */ - function applies_to_content_id($content_id) { - return $this->applies_to_content_object($this->fetch_content($content_id)); - } - - /** - * Determines whether the user has access to use this flag. - * - * @param $action - * Optional. The action to test, either "flag" or "unflag". If none given, - * "flag" will be tested, which is the minimum permission to use a flag. - * @param $account - * Optional. The user object. If none given, the current user will be used. - * - * @return - * Boolean TRUE if the user is allowed to flag/unflag. FALSE otherwise. - */ - function user_access($action = 'flag', $account = NULL) { - if (!isset($account)) { - $account = $GLOBALS['user']; - } - - // Anonymous user can't use this system unless Session API is installed. - if ($account->uid == 0 && !module_exists('session_api')) { - return FALSE; - } - - $matched_roles = array_intersect($this->roles[$action], array_keys($account->roles)); - return !empty($matched_roles) || $account->uid == 1; - } - - /** - * Determines whether the user may flag, or unflag, the given content. - * - * This method typically should not be overridden by child classes. Instead - * they should implement type_access(), which is called by this method. - * - * @param $content_id - * The content ID to flag/unflag. - * @param $action - * The action to test. Either 'flag' or 'unflag'. Leave NULL to determine - * by flag status. - * @param $account - * The user on whose behalf to test the flagging action. Leave NULL for the - * current user. - * - * @return - * Boolean TRUE if the user is allowed to flag/unflag the given content. - * FALSE otherwise. - */ - function access($content_id, $action = NULL, $account = NULL) { - if (!isset($account)) { - $account = $GLOBALS['user']; - } - - if (isset($content_id) && !$this->applies_to_content_id($content_id)) { - // Flag does not apply to this content. - return FALSE; - } - - if (!isset($action)) { - $uid = $account->uid; - $sid = flag_get_sid($uid); - $action = $this->is_flagged($content_id, $uid, $sid) ? 'unflag' : 'flag'; - } - - // Base initial access on the user's basic permission to use this flag. - $access = $this->user_access($action, $account); - - // Check for additional access rules provided by sub-classes. - $child_access = $this->type_access($content_id, $action, $account); - if (isset($child_access)) { - $access = $child_access; - } - - // Allow modules to disallow (or allow) access to flagging. - $access_array = module_invoke_all('flag_access', $this, $content_id, $action, $account); - - foreach ($access_array as $set_access) { - if (isset($set_access)) { - $access = $set_access; - } - } - - return $access; - } - - /** - * Determine access to multiple objects. - * - * Similar to user_access() but works on multiple IDs at once. Called in the - * pre_render() stage of the 'Flag links' field within Views to find out where - * that link applies. The reason we do a separate DB query, and not lump this - * test in the Views query, is to make 'many to one' tests possible without - * interfering with the rows, and also to reduce the complexity of the code. - * - * This method typically should not be overridden by child classes. Instead - * they should implement type_access_multiple(), which is called by this - * method. - * - * @param $content_ids - * The array of content IDs to check. The keys are the content IDs, the - * values are the actions to test: either 'flag' or 'unflag'. - * @param $account - * Optional. The account for which the actions will be compared against. - * If left empty, the current user will be used. - * - * @return - * An array whose keys are the object IDs and values are booleans indicating - * access. - * - * @see hook_flag_access_multiple() - */ - function access_multiple($content_ids, $account = NULL) { - $account = isset($account) ? $account : $GLOBALS['user']; - $access = array(); - - // First check basic user access for this action. - foreach ($content_ids as $content_id => $action) { - $access[$content_id] = $this->user_access($content_ids[$content_id], $account); - } - - // Check for additional access rules provided by sub-classes. - $child_access = $this->type_access_multiple($content_ids, $account); - if (isset($child_access)) { - foreach ($child_access as $content_id => $content_access) { - if (isset($content_access)) { - $access[$content_id] = $content_access; - } - } - } - - // Merge in module-defined access. - foreach (module_implements('flag_access_multiple') as $module) { - $module_access = module_invoke($module, 'flag_access_multiple', $this, $content_ids, $account); - foreach ($module_access as $content_id => $content_access) { - if (isset($content_access)) { - $access[$content_id] = $content_access; - } - } - } - - return $access; - } - - /** - * Implements access() implemented by each child class. - * - * @abstract - */ - function type_access($content_id, $action, $account) { - return NULL; - } - - /** - * Implements access_multiple() implemented by each child class. - * - * @abstract - */ - function type_access_multiple($content_ids, $account) { - return array(); - } - - /** - * @} End of "defgroup access". - */ - - /** - * Given a content object, returns its ID. - * Derived classes must implement this. - * - * @abstract - */ - function get_content_id($content) { - return NULL; - } - - /** - * Returns TRUE if the flag is configured to show the flag-link using hook_link. - * Derived classes are likely to implement this. - */ - function uses_hook_link($teaser) { - return FALSE; - } - - /** - * Returns TRUE if this flag requires anonymous user cookies. - */ - function uses_anonymous_cookies() { - global $user; - return $user->uid == 0 && variable_get('cache', 0); - } - - /** - * Flags, or unflags, an item. - * - * @param $action - * Either 'flag' or 'unflag'. - * @param $content_id - * The ID of the item to flag or unflag. - * @param $account - * The user on whose behalf to flag. Leave empty for the current user. - * @param $skip_permission_check - * Flag the item even if the $account user don't have permission to do so. - * @param $flagging - * Optional. This method works in tandem with Drupal's Field subsystem. - * Pass in a flagging entity if you want operate on it as well. - * - * @return - * FALSE if some error occured (e.g., user has no permission, flag isn't - * applicable to the item, etc.), TRUE otherwise. - */ - function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { - // Get the user. - if (!isset($account)) { - $account = $GLOBALS['user']; - } - if (!$account) { - return FALSE; - } - - // Check access and applicability. - if (!$skip_permission_check) { - if (!$this->access($content_id, $action, $account)) { - // User has no permission to flag/unflag this object. - return FALSE; - } - } - else { - // We are skipping permission checks. However, at a minimum we must make - // sure the flag applies to this content type: - if (!$this->applies_to_content_id($content_id)) { - return FALSE; - } - } - - // Clear various caches; We don't want code running after us to report - // wrong counts or false flaggings. - flag_get_counts(NULL, NULL, TRUE); - flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE); - drupal_static_reset('flag_get_content_flags'); - - // Find out which user id to use. - $uid = $this->global ? 0 : $account->uid; - - // Find out which session id to use. - if ($this->global) { - $sid = 0; - } - else { - $sid = flag_get_sid($uid, TRUE); - // Anonymous users must always have a session id. - if ($sid == 0 && $account->uid == 0) { - return FALSE; - } - } - - // Set our uid and sid to the flagging object. - if (isset($flagging)) { - $flagging->uid = $uid; - $flagging->sid = $sid; - } - - // @todo: Discuss: Should we call field_attach_validate()? None of the - // entities in core does this (fields entered through forms are already - // validated). - // - // @todo: Discuss: Core wraps everything in a try { }, should we? - - // Perform the flagging or unflagging of this flag. - $existing_fcid = $this->_is_flagged($content_id, $uid, $sid); - $flagged = (bool) $existing_fcid; - if ($action == 'unflag') { - if ($this->uses_anonymous_cookies()) { - $this->_unflag_anonymous($content_id); - } - if ($flagged) { - // Note the order: We delete the entity before calling _unflag() to - // delete the {flag_content} record. - $this->_delete_flagging($existing_fcid); - $this->_unflag($content_id, $uid, $sid); - module_invoke_all('flag', 'unflag', $this, $content_id, $account, $existing_fcid); - } - } - elseif ($action == 'flag') { - if ($this->uses_anonymous_cookies()) { - $this->_flag_anonymous($content_id); - } - if (!$flagged) { - if (!isset($flagging)) { - // Construct a new flagging object if we don't have one. - $flagging = $this->new_flagging($content_id, $uid, $sid); - } - $fcid = $this->_flag($content_id, $uid, $sid); - // We're writing out a flagging entity even when we aren't passed one - // (e.g., when flagging via JavaScript toggle links); in this case - // Field API will assign the fields their default values. - $this->_insert_flagging($flagging, $content_id, $fcid); - module_invoke_all('flag', 'flag', $this, $content_id, $account, $fcid); - } - else { - // Nothing to do. Item is already flagged. - // - // Except in the case a $flagging object is passed in: in this case - // we're, for example, arriving from an editing form and need to update - // the entity. - if ($flagging) { - $this->_update_flagging($flagging); - } - } - } - - return TRUE; - } - - /** - * The entity CRUD methods _{insert,update,delete}_flagging() are for private - * use by the flag() method. - * - * The reason programmers should not call them directly is because a flagging - * operation is also accompanied by some bookkeeping (calling hooks, updating - * counters) or access control. These tasks are handled by the flag() method. - */ - private function _insert_flagging($flagging, $content_id, $fcid) { - $flagging->fcid = $fcid; - field_attach_presave('flagging', $flagging); - field_attach_insert('flagging', $flagging); - } - private function _update_flagging($flagging) { - field_attach_presave('flagging', $flagging); - field_attach_update('flagging', $flagging); - // Update the cache. - flagging_load($flagging->fcid, TRUE); - } - private function _delete_flagging($fcid) { - if (($flagging = flagging_load($fcid))) { - field_attach_delete('flagging', $flagging); - // Remove from the cache. - flagging_load($fcid, TRUE); - } - } - - /** - * Construct a new, empty flagging entity object. - * - * @param mixed $content_id - * The unique identifier of the content being flagged. - * @param int $uid - * Optional. The user id of the user doing the flagging. - * @param mixed $sid - * Optional. The user SID (provided by Session API) who is doing the - * flagging. The SID is 0 for logged in users. - * - * @return stdClass - * The returned object has at least the 'flag_name' property set, which - * enables Field API to figure out the bundle, but it's your responsibility - * to eventually populate 'content_id' and 'fcid'. - */ - function new_flagging($content_id = NULL, $uid = NULL, $sid = NULL) { - return (object) array( - 'fcid' => NULL, - 'flag_name' => $this->name, - 'content_id' => $content_id, - 'uid' => $uid, - 'sid' => $sid, - ); - } - - /** - * Determines if a certain user has flagged this content. - * - * Thanks to using a cache, inquiring several different flags about the same - * item results in only one SQL query. - * - * @param $uid - * Optional. The user ID whose flags we're checking. If none given, the - * current user will be used. - * - * @return - * TRUE if the content is flagged, FALSE otherwise. - */ - function is_flagged($content_id, $uid = NULL, $sid = NULL) { - return (bool) $this->get_flagging_record($content_id, $uid, $sid); - } - - /** - * Returns the flagging record. - * - * This method returns the "flagging record": the {flag_content} record that - * exists for each flagged item (for a certain user). If the item isn't - * flagged, returns NULL. This method could be useful, for example, when you - * want to find out the 'fcid' or 'timestamp' values. - * - * Thanks to using a cache, inquiring several different flags about the same - * item results in only one SQL query. - * - * Parameters are the same as is_flagged()'s. - */ - function get_flagging_record($content_id, $uid = NULL, $sid = NULL) { - $uid = $this->global ? 0 : (!isset($uid) ? $GLOBALS['user']->uid : $uid); - $sid = $this->global ? 0 : (!isset($sid) ? flag_get_sid($uid) : $sid); - - // flag_get_user_flags() does caching. - $user_flags = flag_get_user_flags($this->content_type, $content_id, $uid, $sid); - return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL; - } - - /** - * Similar to is_flagged() excepts it returns the flagging entity. - */ - function get_flagging($content_id, $uid = NULL, $sid = NULL) { - if (($record = $this->get_flagging_record($content_id, $uid, $sid))) { - return flagging_load($record->fcid); - } - } - - /** - * Determines if a certain user has flagged this content. - * - * You probably shouldn't call this raw private method: call the - * is_flagged() method instead. - * - * This method is similar to is_flagged() except that it does direct SQL and - * doesn't do caching. Use it when you want to not affect the cache, or to - * bypass it. - * - * @return - * If the content is flagged, returns the value of the 'fcid' column. - * Else, returns FALSE. - * - * @private - */ - function _is_flagged($content_id, $uid, $sid) { - return db_select('flag_content', 'fc') - ->fields('fc', array('fcid')) - ->condition('fid', $this->fid) - ->condition('uid', $uid) - ->condition('sid', $sid) - ->condition('content_id', $content_id) - ->execute() - ->fetchField(); - } - - /** - * A low-level method to flag content. - * - * You probably shouldn't call this raw private method: call the flag() - * function instead. - * - * @return - * The 'fcid' column of the new {flag_content} record. - * - * @private - */ - function _flag($content_id, $uid, $sid) { - $fcid = db_insert('flag_content') - ->fields(array( - 'fid' => $this->fid, - 'content_type' => $this->content_type, - 'content_id' => $content_id, - 'uid' => $uid, - 'sid' => $sid, - 'timestamp' => REQUEST_TIME, - )) - ->execute(); - $this->_increase_count($content_id); - return $fcid; - } - - /** - * A low-level method to unflag content. - * - * You probably shouldn't call this raw private method: call the flag() - * function instead. - * - * @return - * If the content was flagged, returns the value of the now deleted 'fcid' - * column. Else, returns FALSE. - * - * @private - */ - function _unflag($content_id, $uid, $sid) { - $fcid = db_select('flag_content', 'fc') - ->fields('fc', array('fcid')) - ->condition('fid', $this->fid) - ->condition('uid', $uid) - ->condition('sid', $sid) - ->condition('content_id', $content_id) - ->execute() - ->fetchField(); - if ($fcid) { - db_delete('flag_content')->condition('fcid', $fcid)->execute(); - $this->_decrease_count($content_id); - } - return $fcid; - } - - /** - * Increases the flag count for a piece of content. - * - * @param $content_id - * For which item should the count be increased. - * @param $number - * The amount of counts to increasing. Defaults to 1. - * - * @private - */ - function _increase_count($content_id, $number = 1) { - db_merge('flag_counts') - ->key(array( - 'fid' => $this->fid, - 'content_id' => $content_id, - )) - ->fields(array( - 'content_type' => $this->content_type, - 'count' => $number, - 'last_updated' => REQUEST_TIME, - )) - ->updateFields(array( - 'last_updated' => REQUEST_TIME, - )) - ->expression('count', 'count + :inc', array(':inc' => $number)) - ->execute(); - } - - /** - * Decreases the flag count for a piece of content. - * - * @param $content_id - * For which item should the count be descreased. - * @param $number - * The amount of counts to decrease. Defaults to 1. - * - * @private - */ - function _decrease_count($content_id, $number = 1) { - // Delete rows with count 0, for data consistency and space-saving. - // Done before the db_update() to prevent out-of-bounds errors on "count". - db_delete('flag_counts') - ->condition('fid', $this->fid) - ->condition('content_id', $content_id) - ->condition('count', $number, '<=') - ->execute(); - - // Update the count with the new value otherwise. - db_update('flag_counts') - ->expression('count', 'count - :inc', array(':inc' => $number)) - ->fields(array( - 'last_updated' => REQUEST_TIME, - )) - ->condition('fid', $this->fid) - ->condition('content_id', $content_id) - ->execute(); - } - - /** - * Set a cookie for anonymous users to record their flagging. - * - * @private - */ - function _flag_anonymous($content_id) { - $storage = FlagCookieStorage::factory($this); - $storage->flag($content_id); - } - - /** - * Remove the cookie for anonymous users to record their unflagging. - * - * @private - */ - function _unflag_anonymous($content_id) { - $storage = FlagCookieStorage::factory($this); - $storage->unflag($content_id); - } - - /** - * Returns the number of times an item is flagged. - * - * Thanks to using a cache, inquiring several different flags about the same - * item results in only one SQL query. - */ - function get_count($content_id) { - $counts = flag_get_counts($this->content_type, $content_id); - return isset($counts[$this->name]) ? $counts[$this->name] : 0; - } - - /** - * Returns the number of items a user has flagged. - * - * For global flags, pass '0' as the user ID and session ID. - */ - function get_user_count($uid, $sid = NULL) { - if (!isset($sid)) { - $sid = flag_get_sid($uid); - } - return db_select('flag_content', 'fc')->fields('fc', array('fcid')) - ->condition('fid', $this->fid)->condition('uid', $uid)->condition('sid', $sid) - ->countQuery()->execute()->fetchField(); - } - - /** - * Processes a flag label for display. This means language translation and - * token replacements. - * - * You should always call this function and not get at the label directly. - * E.g., do `print $flag->get_label('title')` instead of `print - * $flag->title`. - * - * @param $label - * The label to get, e.g. 'title', 'flag_short', 'unflag_short', etc. - * @param $content_id - * The ID in whose context to interpret tokens. If not given, only global - * tokens will be substituted. - * @return - * The processed label. - */ - function get_label($label, $content_id = NULL) { - if (!isset($this->$label)) { - return; - } - $label = t($this->$label); - if (strpos($label, '[') !== FALSE) { - $label = $this->replace_tokens($label, array(), array('sanitize' => FALSE), $content_id); - } - return filter_xss_admin($label); - } - - /** - * Get the link type for this flag. - */ - function get_link_type() { - $link_types = flag_get_link_types(); - return (isset($this->link_type) && isset($link_types[$this->link_type])) ? $link_types[$this->link_type] : $link_types['normal']; - } - - /** - * Replaces tokens in a label. Only the 'global' token context is recognized - * by default, so derived classes should override this method to add all - * token contexts they understand. - */ - function replace_tokens($label, $contexts, $options, $content_id) { - if (strpos($label , 'flagging:') !== FALSE) { - if (($flagging = $this->get_flagging($content_id))) { - $contexts['flagging'] = $flagging; - } - } - return token_replace($label, $contexts, $options); - } - - /** - * Returns the token types this flag understands in labels. These are used - * for narrowing down the token list shown in the help box to only the - * relevant ones. - * - * Derived classes should override this. - */ - function get_labels_token_types() { - return array('flagging'); - } - - /** - * A convenience method for getting the flag title. - * - * `$flag->get_title()` is shorthand for `$flag->get_label('title')`. - */ - function get_title($content_id = NULL, $reset = FALSE) { - static $titles = array(); - if ($reset) { - $titles = array(); - } - $slot = intval($content_id); // Convert NULL to 0. - if (!isset($titles[$this->fid][$slot])) { - $titles[$this->fid][$slot] = $this->get_label('title', $content_id); - } - return $titles[$this->fid][$slot]; - } - - /** - * Returns a 'flag action' object. It exists only for the sake of its - * informative tokens. Currently, it's utilized only for the 'mail' action. - * - * Derived classes should populate the 'content_title' and 'content_url' - * slots. - */ - function get_flag_action($content_id) { - $flag_action = new stdClass(); - $flag_action->flag = $this->name; - $flag_action->content_type = $this->content_type; - $flag_action->content_id = $content_id; - return $flag_action; - } - - /** - * @addtogroup actions - * @{ - * Methods that can be overridden to support Actions. - */ - - /** - * Returns an array of all actions that are executable with this flag. - */ - function get_valid_actions() { - $actions = module_invoke_all('action_info'); - foreach ($actions as $callback => $action) { - if ($action['type'] != $this->content_type && !in_array('any', $action['triggers'])) { - unset($actions[$callback]); - } - } - return $actions; - } - - /** - * Returns objects the action may possibly need. This method should return at - * least the 'primary' object the action operates on. - * - * This method is needed because get_valid_actions() returns actions that - * don't necessarily operate on an object of a type this flag manages. For - * example, flagging a comment may trigger an 'Unpublish post' action on a - * node; So the comment flag needs to tell the action about some node. - * - * Derived classes must implement this. - * - * @abstract - */ - function get_relevant_action_objects($content_id) { - return array(); - } - - /** - * @} End of "addtogroup actions". - */ - - /** - * @addtogroup views - * @{ - * Methods that can be overridden to support the Views module. - */ - - /** - * Returns information needed for Views integration. E.g., the Views table - * holding the flagged content, its primary key, and various labels. See - * derived classes for examples. - * - * @static - */ - function get_views_info() { - return array(); - } - - /** - * @} End of "addtogroup views". - */ - - /** - * Saves a flag to the database. It is a wrapper around update() and insert(). - */ - function save() { - if (isset($this->fid)) { - $this->update(); - $this->is_new = FALSE; - } - else { - $this->insert(); - $this->is_new = TRUE; - } - // Clear the page cache for anonymous users. - cache_clear_all('*', 'cache_page', TRUE); - } - - /** - * Saves an existing flag to the database. Better use save(). - */ - function update() { - db_update('flags')->fields(array( - 'name' => $this->name, - 'title' => $this->title, - 'global' => $this->global, - 'options' => $this->get_serialized_options())) - ->condition('fid', $this->fid) - ->execute(); - db_delete('flag_types')->condition('fid', $this->fid)->execute(); - foreach ($this->types as $type) { - db_insert('flag_types')->fields(array( - 'fid' => $this->fid, - 'type' => $type)) - ->execute(); - } - } - - /** - * Saves a new flag to the database. Better use save(). - */ - function insert() { - $this->fid = db_insert('flags') - ->fields(array( - 'content_type' => $this->content_type, - 'name' => $this->name, - 'title' => $this->title, - 'global' => $this->global, - 'options' => $this->get_serialized_options(), - )) - ->execute(); - foreach ($this->types as $type) { - db_insert('flag_types') - ->fields(array( - 'fid' => $this->fid, - 'type' => $type, - )) - ->execute(); - } - } - - /** - * Options are stored serialized in the database. - */ - function get_serialized_options() { - $option_names = array_keys($this->options()); - $options = array(); - foreach ($option_names as $option) { - $options[$option] = $this->$option; - } - return serialize($options); - } - - /** - * Deletes a flag from the database. - */ - function delete() { - db_delete('flags')->condition('fid', $this->fid)->execute(); - db_delete('flag_content')->condition('fid', $this->fid)->execute(); - db_delete('flag_types')->condition('fid', $this->fid)->execute(); - db_delete('flag_counts')->condition('fid', $this->fid)->execute(); - module_invoke_all('flag_delete', $this); - } - - /** - * Returns TRUE if this flag's declared API version is compatible with this - * module. - * - * An "incompatible" flag is one exported (and now being imported or exposed - * via hook_flag_default_flags()) by a different version of the Flag module. - * An incompatible flag should be treated as a "black box": it should not be - * saved or exported because our code may not know to handle its internal - * structure. - */ - function is_compatible() { - if (isset($this->fid)) { - // Database flags are always compatible. - return TRUE; - } - else { - if (!isset($this->api_version)) { - $this->api_version = 1; - } - return $this->api_version == FLAG_API_VERSION; - } - } - - /** - * Finds the "default flag" corresponding to this flag. - * - * Flags defined in code ("default flags") can be overridden. This method - * returns the default flag that is being overridden by $this. Returns NULL - * if $this overrides no default flag. - */ - function find_default_flag() { - if ($this->fid) { - $default_flags = flag_get_default_flags(TRUE); - if (isset($default_flags[$this->name])) { - return $default_flags[$this->name]; - } - } - } - - /** - * Reverts an overriding flag to its default state. - * - * Note that $this isn't altered. To see the reverted flag you'll have to - * call flag_get_flag($this->name) again. - * - * @return - * TRUE if the flag was reverted successfully; FALSE if there was an error; - * NULL if this flag overrides no default flag. - */ - function revert() { - if (($default_flag = $this->find_default_flag())) { - if ($default_flag->is_compatible()) { - $default_flag = clone $default_flag; - $default_flag->fid = $this->fid; - $default_flag->save(); - flag_get_flags(NULL, NULL, NULL, TRUE); - return TRUE; - } - else { - return FALSE; - } - } - } - - /** - * Disable a flag provided by a module. - */ - function disable() { - if (isset($this->module)) { - $flag_status = variable_get('flag_default_flag_status', array()); - $flag_status[$this->name] = FALSE; - variable_set('flag_default_flag_status', $flag_status); - } - } - - /** - * Enable a flag provided by a module. - */ - function enable() { - if (isset($this->module)) { - $flag_status = variable_get('flag_default_flag_status', array()); - $flag_status[$this->name] = TRUE; - variable_set('flag_default_flag_status', $flag_status); - } - } - - /** - * Returns administrative menu path for carrying out some action. - */ - function admin_path($action) { - if ($action == 'edit') { - // Since 'edit' is the default tab, we omit the action. - return FLAG_ADMIN_PATH . '/manage/' . $this->name; - } - else { - return FLAG_ADMIN_PATH . '/manage/' . $this->name . '/' . $action; - } - } - - /** - * Renders a flag/unflag link. This is a wrapper around theme('flag') that, - * in Drupal 6, easily channels the call to the right template file. - * - * For parameters docmentation, see theme_flag(). - */ - function theme($action, $content_id, $after_flagging = FALSE) { - static $js_added = array(); - global $user; - - // If the flagging user is anonymous, set a boolean for the benefit of - // JavaScript code. Currently, only our "anti-crawlers" mechanism uses it. - if ($user->uid == 0 && !isset($js_added['anonymous'])) { - $js_added['anonymous'] = TRUE; - drupal_add_js(array('flag' => array('anonymous' => TRUE)), 'setting'); - } - - // If the flagging user is anonymous and the page cache is enabled, we - // update the links through JavaScript. - if ($this->uses_anonymous_cookies() && !$after_flagging) { - if ($this->global) { - // In case of global flags, the JavaScript template is to contain - // the opposite of the current state. - $js_action = ($action == 'flag' ? 'unflag' : 'flag'); - } - else { - // In case of non-global flags, we always show the "flag!" link, - // and then replace it with the "unflag!" link through JavaScript. - $js_action = 'unflag'; - $action = 'flag'; - } - if (!isset($js_added[$this->name . '_' . $content_id])) { - $js_added[$this->name . '_' . $content_id] = TRUE; - $js_template = theme($this->theme_suggestions(), array('flag' => $this, 'action' => $js_action, 'content_id' => $content_id, 'after_flagging' => $after_flagging)); - drupal_add_js(array('flag' => array('templates' => array($this->name . '_' . $content_id => $js_template))), 'setting'); - } - } - - return theme($this->theme_suggestions(), array('flag' => $this, 'action' => $action, 'content_id' => $content_id, 'after_flagging' => $after_flagging)); - } - - /** - * Provides an array of possible themes to try for a given flag. - */ - function theme_suggestions() { - $suggestions = array(); - $suggestions[] = 'flag__' . $this->name; - $suggestions[] = 'flag'; - return $suggestions; - } -} - -/** - * Base entity flag handler. - */ -class flag_entity extends flag_flag { - /** - * Adds additional options that are common for all entity types. - */ - function options() { - $options = parent::options(); - $options += array( - // Output the flag in the entity links. - // @see hook_entity_view(). - 'show_on_entity' => TRUE, - // Add a checkbox for the flag in the entity form. - // @see hook_field_attach_form(). - 'show_on_form' => FALSE, - 'access_author' => '', - ); - return $options; - } - - /** - * Options form extras for the generic entity flag. - */ - function options_form(&$form) { - $bundles = array(); - $entity_info = entity_get_info($this->content_type); - foreach ($entity_info['bundles'] as $bundle_key => $bundle) { - $bundles[$bundle_key] = check_plain($bundle['label']); - } - $form['access']['types'] = array( - '#type' => 'checkboxes', - '#title' => t('Bundles'), - '#options' => $bundles, - '#description' => t('Check any bundle that this flag may be used on. You must check at least one bundle.'), - '#default_value' => $this->types, - '#required' => TRUE, - ); - // Handlers may want to unset this option if they provide their own more - // specific ways to show links. - $form['display']['show_on_entity'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on entity'), - '#default_value' => isset($this->show_on_entity) ? $this->show_on_entity : TRUE, - '#access' => empty($this->locked['show_on_entity']), - ); - $form['display']['show_on_form'] = array( - '#type' => 'checkbox', - '#title' => t('Display checkbox on entity edit form'), - '#default_value' => $this->show_on_form, - '#access' => empty($this->locked['show_on_form']), - ); - } - - /** - * Loads the entity object. - */ - function _load_content($content_id) { - if (is_numeric($content_id)) { - $entity = entity_load($this->content_type, array($content_id)); - return reset($entity); - } - return NULL; - } - - /** - * Checks whether the flag applies for the current entity bundle. - */ - function applies_to_content_object($entity) { - $entity_info = entity_get_info($this->content_type); - if (empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { - return TRUE; - } - return FALSE; - } - - /** - * Returns the entity id, if it already exists. - */ - function get_content_id($entity) { - $entity_info = entity_get_info($this->content_type); - if ($entity && isset($entity->{$entity_info['entity keys']['id']})) { - return $entity->{$entity_info['entity keys']['id']}; - } - } - - /** - * Returns TRUE if the link should be displayed. - */ - function uses_hook_link($teaser) { - if ($this->show_on_entity) { - return TRUE; - } - return FALSE; - } - - /** - * Returns token types for the current entity type. - */ - function get_labels_token_types() { - // The token type name might be different to the entity type name. If so, - // an own flag entity handler can be used for overriding this. - return array_merge(array($this->content_type), parent::get_labels_token_types()); - } - - /** - * Replaces tokens. - */ - function replace_tokens($label, $contexts, $options, $content_id) { - if ($content_id && ($entity = $this->fetch_content($content_id))) { - $contexts[$this->content_type] = $entity; - } - return parent::replace_tokens($label, $contexts, $options, $content_id); - } - - /** - * Returns a 'flag action' object. - */ - function get_flag_action($content_id) { - $flag_action = parent::get_flag_action($content_id); - $entity = $this->fetch_content($content_id); - $flag_action->content_title = entity_label($this->content_type, $entity); - $flag_action->content_url = _flag_url($this->content_type . '/' . $this->get_content_id($entity)); - return $flag_action; - } - - /** - * Returns objects the action may possible need. - */ - function get_relevant_action_objects($content_id) { - return array( - $this->content_type => $this->fetch_content($content_id), - ); - } - - /** - * Returns information for the Views integration. - */ - function get_views_info() { - $entity_info = entity_get_info($this->content_type); - return array( - 'views table' => $entity_info['base table'], - 'join field' => $entity_info['entity keys']['id'], - 'title field' => isset($entity_info['entity keys']['label']) ? $entity_info['entity keys']['label'] : '', - 'title' => t('@entity_label flag', array('@entity_label' => $entity_info['label'])), - 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), - 'counter title' => t('@entity_label flag counter', array('@entity_label' => $entity_info['label'])), - 'counter help' => t('Include this to gain access to the flag counter field.'), - ); - } -} - -/** - * Implements a node flag. - */ -class flag_node extends flag_entity { - function options() { - $options = parent::options(); - // Use own display settings in the meanwhile. - unset($options['show_on_entity']); - $options += array( - 'show_on_page' => TRUE, - 'show_on_teaser' => TRUE, - 'show_on_form' => FALSE, - 'show_contextual_link' => FALSE, - 'i18n' => 0, - ); - return $options; - } - - /** - * Options form extras for node flags. - */ - function options_form(&$form) { - parent::options_form($form); - - $form['access']['access_author'] = array( - '#type' => 'radios', - '#title' => t('Flag access by content authorship'), - '#options' => array( - '' => t('No additional restrictions'), - 'own' => t('Users may only flag content they own'), - 'others' => t('Users may only flag content of others'), - ), - '#default_value' => $this->access_author, - '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), - ); - - // Support for i18n flagging requires Translation helpers module. - $form['i18n'] = array( - '#type' => 'radios', - '#title' => t('Internationalization'), - '#options' => array( - '1' => t('Flag translations of content as a group'), - '0' => t('Flag each translation of content separately'), - ), - '#default_value' => $this->i18n, - '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), - '#access' => module_exists('translation_helpers'), - '#weight' => 5, - ); - - $form['display']['show_on_teaser'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on node teaser'), - '#default_value' => $this->show_on_teaser, - '#access' => empty($this->locked['show_on_teaser']), - ); - - $form['display']['show_on_page'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on node page'), - '#default_value' => $this->show_on_page, - '#access' => empty($this->locked['show_on_page']), - ); - // Override the UI texts for nodes. - $form['display']['show_on_form'] = array( - '#title' => t('Display checkbox on node edit form'), - '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), - ) + $form['display']['show_on_form']; - $form['display']['show_contextual_link'] = array( - '#type' => 'checkbox', - '#title' => t('Display in contextual links'), - '#default_value' => $this->show_contextual_link, - '#access' => empty($this->locked['show_contextual_link']) && module_exists('contextual'), - ); - - unset($form['display']['show_on_entity']); - } - - function type_access_multiple($content_ids, $account = NULL) { - $access = array(); - - // Ensure that only flaggable node types are granted access. This avoids a - // node_load() on every type, usually done by applies_to_content_id(). - $result = db_select('node', 'n')->fields('n', array('nid')) - ->condition('nid', array_keys($content_ids), 'IN') - ->condition('type', $this->types, 'NOT IN') - ->execute(); - foreach ($result as $row) { - $access[$row->nid] = FALSE; - } - - return $access; - } - - /** - * Adjust the Content ID to find the translation parent if i18n-enabled. - * - * @param $content_id - * The nid for the content. - * @return - * The tnid if available, the nid otherwise. - */ - function get_translation_id($content_id) { - if ($this->i18n) { - $node = $this->fetch_content($content_id); - if (!empty($node->tnid)) { - $content_id = $node->tnid; - } - } - return $content_id; - } - - function uses_hook_link($teaser) { - if ($teaser && $this->show_on_teaser || !$teaser && $this->show_on_page) { - return TRUE; - } - return FALSE; - } - - function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { - $content_id = $this->get_translation_id($content_id); - return parent::flag($action, $content_id, $account, $skip_permission_check, $flagging); - } - - // Instead of overriding is_flagged() we override get_flagging_record(), - // which is the underlying method. - function get_flagging_record($content_id, $uid = NULL, $sid = NULL) { - $content_id = $this->get_translation_id($content_id); - return parent::get_flagging_record($content_id, $uid, $sid); - } - - function replace_tokens($label, $contexts, $options, $content_id) { - if (is_numeric($content_id) && ($node = $this->fetch_content($content_id))) { - $contexts['node'] = $node; - } - // Nodes accept the node-type as a $content_id in the case that a new node - // is being created and a full node object does not yet exist. - elseif (!empty($content_id) && ($type = node_type_get_type($content_id))) { - $content_id = NULL; - $contexts['node'] = (object) array( - 'nid' => NULL, - 'type' => $type->type, - 'title' => '', - ); - } - return parent::replace_tokens($label, $contexts, $options, $content_id); - } -} - -/** - * Implements a comment flag. - */ -class flag_comment extends flag_entity { - function options() { - $options = parent::options(); - // Use own display settings in the meanwhile. - unset($options['show_on_entity']); - $options += array( - 'access_author' => '', - 'show_on_comment' => TRUE, - ); - return $options; - } - - /** - * Options form extras for comment flags. - */ - function options_form(&$form) { - parent::options_form($form); - - $form['access']['access_author'] = array( - '#type' => 'radios', - '#title' => t('Flag access by content authorship'), - '#options' => array( - '' => t('No additional restrictions'), - 'comment_own' => t('Users may only flag own comments'), - 'comment_others' => t('Users may only flag comments by others'), - 'node_own' => t('Users may only flag comments of nodes they own'), - 'node_others' => t('Users may only flag comments of nodes by others'), - ), - '#default_value' => $this->access_author, - '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), - ); - - $form['display']['show_on_comment'] = array( - '#type' => 'checkbox', - '#title' => t('Display link under comment'), - '#default_value' => $this->show_on_comment, - '#access' => empty($this->locked['show_on_comment']), - ); - - unset($form['display']['show_on_entity']); - } - - function type_access_multiple($content_ids, $account) { - $access = array(); - - // Ensure node types are granted access. This avoids a - // node_load() on every type, usually done by applies_to_content_id(). - $query = db_select('comment', 'c'); - $query->innerJoin('node', 'n', 'c.nid = n.nid'); - $result = $query - ->fields('c', array('cid')) - ->condition('c.cid', $content_ids, 'IN') - ->condition('n.type', $this->types, 'NOT IN') - ->execute(); - foreach ($result as $row) { - $access[$row->nid] = FALSE; - } - - return $access; - } - - function get_content_id($comment) { - // Store the comment object in the static cache, to avoid getting it - // again unneedlessly. - $this->remember_content($comment->cid, $comment); - return $comment->cid; - } - - function uses_hook_link($teaser) { - return $this->show_on_comment; - } - - function get_labels_token_types() { - return array_merge(array('comment', 'node'), parent::get_labels_token_types()); - } - - function replace_tokens($label, $contexts, $options, $content_id) { - if ($content_id) { - if (($comment = $this->fetch_content($content_id)) && ($node = node_load($comment->nid))) { - $contexts['node'] = $node; - $contexts['comment'] = $comment; - } - } - return parent::replace_tokens($label, $contexts, $options, $content_id); - } - - function get_flag_action($content_id) { - $flag_action = parent::get_flag_action($content_id); - $comment = $this->fetch_content($content_id); - $flag_action->content_title = $comment->subject; - $flag_action->content_url = _flag_url("comment/$comment->cid", "comment-$comment->cid"); - return $flag_action; - } - - function get_relevant_action_objects($content_id) { - $comment = $this->fetch_content($content_id); - return array( - 'comment' => $comment, - 'node' => node_load($comment->nid), - ); - } -} - -/** - * Implements a user flag. - */ -class flag_user extends flag_entity { - function options() { - $options = parent::options(); - // Use own display settings in the meanwhile. - unset($options['show_on_entity']); - $options += array( - 'show_on_profile' => TRUE, - 'access_uid' => '', - ); - return $options; - } - - /** - * Options form extras for user flags. - */ - function options_form(&$form) { - parent::options_form($form); - $form['access']['types'] = array( - // A user flag doesn't support node types. - // TODO: Maybe support roles instead of node types. - '#type' => 'value', - '#value' => array(0 => 0), - ); - $form['access']['access_uid'] = array( - '#type' => 'checkbox', - '#title' => t('Users may flag themselves'), - '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themself does not make sense.'), - '#default_value' => $this->access_uid ? 0 : 1, - ); - $form['display']['show_on_profile'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on user profile page'), - '#default_value' => $this->show_on_profile, - '#access' => empty($this->locked['show_on_profile']), - ); - - unset($form['display']['show_on_entity']); - } - - function form_input($form_values) { - parent::form_input($form_values); - // The access_uid value is intentionally backwards from the UI, to avoid - // confusion caused by checking a box to disable a feature. - $this->access_uid = empty($form_values['access_uid']) ? 'others' : ''; - } - - function type_access($content_id, $action, $account) { - // Prevent users from flagging themselves. - if ($this->access_uid == 'others' && $content_id == $account->uid) { - return FALSE; - } - } - - function type_access_multiple($content_ids, $account) { - $access = array(); - - // Exclude anonymous. - if (array_key_exists(0, $content_ids)) { - $access[0] = FALSE; - } - - // Prevent users from flagging themselves. - if ($this->access_uid == 'others' && array_key_exists($account->uid, $content_ids)) { - $access[$account->uid] = FALSE; - } - - return $access; - } - - function uses_hook_link($teaser) { - if ($this->show_on_profile) { - return TRUE; - } - return FALSE; - } - - function get_flag_action($content_id) { - $flag_action = parent::get_flag_action($content_id); - $user = $this->fetch_content($content_id); - $flag_action->content_title = $user->name; - $flag_action->content_url = _flag_url('user/' . $user->uid); - return $flag_action; - } - - function get_relevant_action_objects($content_id) { - return array( - 'user' => $this->fetch_content($content_id), - ); - } - - function get_views_info() { - $views_info = parent::get_views_info(); - $views_info['title field'] = 'name'; - return $views_info; - } -} - -/** - * A dummy flag to be used where the real implementation can't be found. - */ -class flag_broken extends flag_flag { - function options_form(&$form) { - $form = array(); - $form['error'] = array( - '#markup' => '
' . t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->content_type)) . '
', - ); - } -} - /** * A shortcut function to output the link URL. */ function _flag_url($path, $fragment = NULL, $absolute = TRUE) { return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); } - - -/** - * Utility class to handle cookies. - * - * Cookies are used to record flaggings for anonymous users on cached pages. - * - * This class contains only two instance methods. Usage example: - * @code - * $storage = FlagCookieStorage::factory($flag); - * $storage->flag(145); - * $storage->unflag(17); - * @endcode - * - * You may delete all the cookies with FlagCookieStorage::drop(). - */ -abstract class FlagCookieStorage { - - /** - * Returns the actual storage object compatible with the flag. - */ - static function factory($flag) { - if ($flag->global) { - return new FlagGlobalCookieStorage($flag); - } - else { - return new FlagNonGlobalCookieStorage($flag); - } - } - - function __construct($flag) { - $this->flag = $flag; - } - - /** - * "Flags" an item. - * - * It just records this fact in a cookie. - */ - abstract function flag($content_id); - - /** - * "Unflags" an item. - * - * It just records this fact in a cookie. - */ - abstract function unflag($content_id); - - /** - * Deletes all the cookies. - * - * (Etymology: "drop" as in "drop database".) - */ - static function drop() { - FlagGlobalCookieStorage::drop(); - FlagNonGlobalCookieStorage::drop(); - } -} - -/** - * Storage handler for global flags. - */ -class FlagGlobalCookieStorage extends FlagCookieStorage { - - function flag($content_id) { - $cookie_key = $this->cookie_key($content_id); - setcookie($cookie_key, 1, REQUEST_TIME + $this->get_lifetime(), base_path()); - $_COOKIE[$cookie_key] = 1; - } - - function unflag($content_id) { - $cookie_key = $this->cookie_key($content_id); - setcookie($cookie_key, 0, REQUEST_TIME + $this->get_lifetime(), base_path()); - $_COOKIE[$cookie_key] = 0; - } - - // Global flags persist for the length of the minimum cache lifetime. - protected function get_lifetime() { - $cookie_lifetime = variable_get('cache', 0) ? variable_get('cache_lifetime', 0) : -1; - // Do not let the cookie lifetime be 0 (which is the no cache limit on - // anonymous page caching), since it would expire immediately. Usually - // the no cache limit means caches are cleared on cron, which usually runs - // at least once an hour. - if ($cookie_lifetime == 0) { - $cookie_lifetime = 3600; - } - return $cookie_lifetime; - } - - protected function cookie_key($content_id) { - return 'flag_global_' . $this->flag->name . '_' . $content_id; - } - - /** - * Deletes all the global cookies. - */ - static function drop() { - foreach ($_COOKIE as $key => $value) { - if (strpos($key, 'flag_global_') === 0) { - setcookie($key, FALSE, 0, base_path()); - unset($_COOKIE[$key]); - } - } - } -} - -/** - * Storage handler for non-global flags. - */ -class FlagNonGlobalCookieStorage extends FlagCookieStorage { - - // The anonymous per-user flaggings are stored in a single cookie, so that - // all of them persist as long as the Drupal cookie lifetime. - - function __construct($flag) { - parent::__construct($flag); - $this->flaggings = isset($_COOKIE['flags']) ? explode(' ', $_COOKIE['flags']) : array(); - } - - function flag($content_id) { - if (!$this->is_flagged($content_id)) { - $this->flaggings[] = $this->cookie_key($content_id); - $this->write(); - } - } - - function unflag($content_id) { - if (($index = $this->index_of($content_id)) !== FALSE) { - unset($this->flaggings[$index]); - $this->write(); - } - } - - protected function get_lifetime() { - return min((int) ini_get('session.cookie_lifetime'), (int) ini_get('session.gc_maxlifetime')); - } - - protected function cookie_key($content_id) { - return $this->flag->name . '_' . $content_id; - } - - protected function write() { - $serialized = implode(' ', array_filter($this->flaggings)); - setcookie('flags', $serialized, REQUEST_TIME + $this->get_lifetime(), base_path()); - $_COOKIE['flags'] = $serialized; - } - - protected function is_flagged($content_id) { - return $this->index_of($content_id) !== FALSE; - } - - protected function index_of($content_id) { - return array_search($this->cookie_key($content_id), $this->flaggings); - } - - /** - * Deletes the cookie. - */ - static function drop() { - if (isset($_COOKIE['flags'])) { - setcookie('flags', FALSE, 0, base_path()); - unset($_COOKIE['flags']); - } - } -} diff --git a/flag.info b/flag.info index 23e9009..0c3b65a 100644 --- a/flag.info +++ b/flag.info @@ -5,7 +5,14 @@ package = Flags configure = admin/structure/flags ; Files that contain classes. -files[] = flag.inc +; Flag classes +files[] = includes/flag/flag_flag.inc +files[] = includes/flag/flag_entity.inc +files[] = includes/flag/flag_node.inc +files[] = includes/flag/flag_comment.inc +files[] = includes/flag/flag_user.inc +files[] = includes/flag.cookie_storage.inc + files[] = includes/flag.entity.inc files[] = flag.rules.inc files[] = includes/flag_handler_argument_content_id.inc diff --git a/flag.install b/flag.install index 665c4fa..e46382c 100644 --- a/flag.install +++ b/flag.install @@ -439,3 +439,10 @@ function flag_update_7203() { db_add_index('flag_content', 'content_id_fid', array('content_id', 'fid')); } } + +/** + * Rebuild the class registry due to classes moving files. + */ +function flag_update_7300() { + registry_rebuild(); +} diff --git a/includes/flag.cookie_storage.inc b/includes/flag.cookie_storage.inc new file mode 100644 index 0000000..a7c7ac1 --- /dev/null +++ b/includes/flag.cookie_storage.inc @@ -0,0 +1,170 @@ +flag(145); + * $storage->unflag(17); + * @endcode + * + * You may delete all the cookies with FlagCookieStorage::drop(). + */ +abstract class FlagCookieStorage { + + /** + * Returns the actual storage object compatible with the flag. + */ + static function factory($flag) { + if ($flag->global) { + return new FlagGlobalCookieStorage($flag); + } + else { + return new FlagNonGlobalCookieStorage($flag); + } + } + + function __construct($flag) { + $this->flag = $flag; + } + + /** + * "Flags" an item. + * + * It just records this fact in a cookie. + */ + abstract function flag($content_id); + + /** + * "Unflags" an item. + * + * It just records this fact in a cookie. + */ + abstract function unflag($content_id); + + /** + * Deletes all the cookies. + * + * (Etymology: "drop" as in "drop database".) + */ + static function drop() { + FlagGlobalCookieStorage::drop(); + FlagNonGlobalCookieStorage::drop(); + } +} + +/** + * Storage handler for global flags. + */ +class FlagGlobalCookieStorage extends FlagCookieStorage { + + function flag($content_id) { + $cookie_key = $this->cookie_key($content_id); + setcookie($cookie_key, 1, REQUEST_TIME + $this->get_lifetime(), base_path()); + $_COOKIE[$cookie_key] = 1; + } + + function unflag($content_id) { + $cookie_key = $this->cookie_key($content_id); + setcookie($cookie_key, 0, REQUEST_TIME + $this->get_lifetime(), base_path()); + $_COOKIE[$cookie_key] = 0; + } + + // Global flags persist for the length of the minimum cache lifetime. + protected function get_lifetime() { + $cookie_lifetime = variable_get('cache', 0) ? variable_get('cache_lifetime', 0) : -1; + // Do not let the cookie lifetime be 0 (which is the no cache limit on + // anonymous page caching), since it would expire immediately. Usually + // the no cache limit means caches are cleared on cron, which usually runs + // at least once an hour. + if ($cookie_lifetime == 0) { + $cookie_lifetime = 3600; + } + return $cookie_lifetime; + } + + protected function cookie_key($content_id) { + return 'flag_global_' . $this->flag->name . '_' . $content_id; + } + + /** + * Deletes all the global cookies. + */ + static function drop() { + foreach ($_COOKIE as $key => $value) { + if (strpos($key, 'flag_global_') === 0) { + setcookie($key, FALSE, 0, base_path()); + unset($_COOKIE[$key]); + } + } + } +} + +/** + * Storage handler for non-global flags. + */ +class FlagNonGlobalCookieStorage extends FlagCookieStorage { + + // The anonymous per-user flaggings are stored in a single cookie, so that + // all of them persist as long as the Drupal cookie lifetime. + + function __construct($flag) { + parent::__construct($flag); + $this->flaggings = isset($_COOKIE['flags']) ? explode(' ', $_COOKIE['flags']) : array(); + } + + function flag($content_id) { + if (!$this->is_flagged($content_id)) { + $this->flaggings[] = $this->cookie_key($content_id); + $this->write(); + } + } + + function unflag($content_id) { + if (($index = $this->index_of($content_id)) !== FALSE) { + unset($this->flaggings[$index]); + $this->write(); + } + } + + protected function get_lifetime() { + return min((int) ini_get('session.cookie_lifetime'), (int) ini_get('session.gc_maxlifetime')); + } + + protected function cookie_key($content_id) { + return $this->flag->name . '_' . $content_id; + } + + protected function write() { + $serialized = implode(' ', array_filter($this->flaggings)); + setcookie('flags', $serialized, REQUEST_TIME + $this->get_lifetime(), base_path()); + $_COOKIE['flags'] = $serialized; + } + + protected function is_flagged($content_id) { + return $this->index_of($content_id) !== FALSE; + } + + protected function index_of($content_id) { + return array_search($this->cookie_key($content_id), $this->flaggings); + } + + /** + * Deletes the cookie. + */ + static function drop() { + if (isset($_COOKIE['flags'])) { + setcookie('flags', FALSE, 0, base_path()); + unset($_COOKIE['flags']); + } + } +} diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc new file mode 100644 index 0000000..48bf370 --- /dev/null +++ b/includes/flag/flag_comment.inc @@ -0,0 +1,112 @@ + '', + 'show_on_comment' => TRUE, + ); + return $options; + } + + /** + * Options form extras for comment flags. + */ + function options_form(&$form) { + parent::options_form($form); + + $form['access']['access_author'] = array( + '#type' => 'radios', + '#title' => t('Flag access by content authorship'), + '#options' => array( + '' => t('No additional restrictions'), + 'comment_own' => t('Users may only flag own comments'), + 'comment_others' => t('Users may only flag comments by others'), + 'node_own' => t('Users may only flag comments of nodes they own'), + 'node_others' => t('Users may only flag comments of nodes by others'), + ), + '#default_value' => $this->access_author, + '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), + ); + + $form['display']['show_on_comment'] = array( + '#type' => 'checkbox', + '#title' => t('Display link under comment'), + '#default_value' => $this->show_on_comment, + '#access' => empty($this->locked['show_on_comment']), + ); + + unset($form['display']['show_on_entity']); + } + + function type_access_multiple($content_ids, $account) { + $access = array(); + + // Ensure node types are granted access. This avoids a + // node_load() on every type, usually done by applies_to_content_id(). + $query = db_select('comment', 'c'); + $query->innerJoin('node', 'n', 'c.nid = n.nid'); + $result = $query + ->fields('c', array('cid')) + ->condition('c.cid', $content_ids, 'IN') + ->condition('n.type', $this->types, 'NOT IN') + ->execute(); + foreach ($result as $row) { + $access[$row->nid] = FALSE; + } + + return $access; + } + + function get_content_id($comment) { + // Store the comment object in the static cache, to avoid getting it + // again unneedlessly. + $this->remember_content($comment->cid, $comment); + return $comment->cid; + } + + function uses_hook_link($teaser) { + return $this->show_on_comment; + } + + function get_labels_token_types() { + return array_merge(array('comment', 'node'), parent::get_labels_token_types()); + } + + function replace_tokens($label, $contexts, $options, $content_id) { + if ($content_id) { + if (($comment = $this->fetch_content($content_id)) && ($node = node_load($comment->nid))) { + $contexts['node'] = $node; + $contexts['comment'] = $comment; + } + } + return parent::replace_tokens($label, $contexts, $options, $content_id); + } + + function get_flag_action($content_id) { + $flag_action = parent::get_flag_action($content_id); + $comment = $this->fetch_content($content_id); + $flag_action->content_title = $comment->subject; + $flag_action->content_url = _flag_url("comment/$comment->cid", "comment-$comment->cid"); + return $flag_action; + } + + function get_relevant_action_objects($content_id) { + $comment = $this->fetch_content($content_id); + return array( + 'comment' => $comment, + 'node' => node_load($comment->nid), + ); + } +} diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc new file mode 100644 index 0000000..9002142 --- /dev/null +++ b/includes/flag/flag_entity.inc @@ -0,0 +1,158 @@ + TRUE, + // Add a checkbox for the flag in the entity form. + // @see hook_field_attach_form(). + 'show_on_form' => FALSE, + 'access_author' => '', + ); + return $options; + } + + /** + * Options form extras for the generic entity flag. + */ + function options_form(&$form) { + $bundles = array(); + $entity_info = entity_get_info($this->content_type); + foreach ($entity_info['bundles'] as $bundle_key => $bundle) { + $bundles[$bundle_key] = check_plain($bundle['label']); + } + $form['access']['types'] = array( + '#type' => 'checkboxes', + '#title' => t('Bundles'), + '#options' => $bundles, + '#description' => t('Check any bundle that this flag may be used on. You must check at least one bundle.'), + '#default_value' => $this->types, + '#required' => TRUE, + ); + // Handlers may want to unset this option if they provide their own more + // specific ways to show links. + $form['display']['show_on_entity'] = array( + '#type' => 'checkbox', + '#title' => t('Display link on entity'), + '#default_value' => isset($this->show_on_entity) ? $this->show_on_entity : TRUE, + '#access' => empty($this->locked['show_on_entity']), + ); + $form['display']['show_on_form'] = array( + '#type' => 'checkbox', + '#title' => t('Display checkbox on entity edit form'), + '#default_value' => $this->show_on_form, + '#access' => empty($this->locked['show_on_form']), + ); + } + + /** + * Loads the entity object. + */ + function _load_content($content_id) { + if (is_numeric($content_id)) { + $entity = entity_load($this->content_type, array($content_id)); + return reset($entity); + } + return NULL; + } + + /** + * Checks whether the flag applies for the current entity bundle. + */ + function applies_to_content_object($entity) { + $entity_info = entity_get_info($this->content_type); + if (empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { + return TRUE; + } + return FALSE; + } + + /** + * Returns the entity id, if it already exists. + */ + function get_content_id($entity) { + $entity_info = entity_get_info($this->content_type); + if ($entity && isset($entity->{$entity_info['entity keys']['id']})) { + return $entity->{$entity_info['entity keys']['id']}; + } + } + + /** + * Returns TRUE if the link should be displayed. + */ + function uses_hook_link($teaser) { + if ($this->show_on_entity) { + return TRUE; + } + return FALSE; + } + + /** + * Returns token types for the current entity type. + */ + function get_labels_token_types() { + // The token type name might be different to the entity type name. If so, + // an own flag entity handler can be used for overriding this. + return array_merge(array($this->content_type), parent::get_labels_token_types()); + } + + /** + * Replaces tokens. + */ + function replace_tokens($label, $contexts, $options, $content_id) { + if ($content_id && ($entity = $this->fetch_content($content_id))) { + $contexts[$this->content_type] = $entity; + } + return parent::replace_tokens($label, $contexts, $options, $content_id); + } + + /** + * Returns a 'flag action' object. + */ + function get_flag_action($content_id) { + $flag_action = parent::get_flag_action($content_id); + $entity = $this->fetch_content($content_id); + $flag_action->content_title = entity_label($this->content_type, $entity); + $flag_action->content_url = _flag_url($this->content_type . '/' . $this->get_content_id($entity)); + return $flag_action; + } + + /** + * Returns objects the action may possible need. + */ + function get_relevant_action_objects($content_id) { + return array( + $this->content_type => $this->fetch_content($content_id), + ); + } + + /** + * Returns information for the Views integration. + */ + function get_views_info() { + $entity_info = entity_get_info($this->content_type); + return array( + 'views table' => $entity_info['base table'], + 'join field' => $entity_info['entity keys']['id'], + 'title field' => isset($entity_info['entity keys']['label']) ? $entity_info['entity keys']['label'] : '', + 'title' => t('@entity_label flag', array('@entity_label' => $entity_info['label'])), + 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), + 'counter title' => t('@entity_label flag counter', array('@entity_label' => $entity_info['label'])), + 'counter help' => t('Include this to gain access to the flag counter field.'), + ); + } +} diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc new file mode 100644 index 0000000..0c4c3cb --- /dev/null +++ b/includes/flag/flag_flag.inc @@ -0,0 +1,1299 @@ +content_type); + + // Lump all data unto the object... + foreach ($row as $field => $value) { + $flag->$field = $value; + } + // ...but skip the following two. + unset($flag->options, $flag->type); + + // Populate the options with the defaults. + $options = (array) unserialize($row->options); + $options += $flag->options(); + + // Make the unserialized options accessible as normal properties. + foreach ($options as $option => $value) { + $flag->$option = $value; + } + + if (!empty($row->type)) { + // The loop loading from the database should further populate this property. + $flag->types[] = $row->type; + } + + return $flag; + } + + /** + * Create a complete flag (except an FID) from an array definition. + */ + static function factory_by_array($config) { + $flag = flag_create_handler($config['content_type']); + + foreach ($config as $option => $value) { + $flag->$option = $value; + } + + if (isset($config['locked']) && is_array($config['locked'])) { + $flag->locked = drupal_map_assoc($config['locked']); + } + + return $flag; + } + + /** + * Another factory method. Returns a new, "empty" flag; e.g., one suitable for + * the "Add new flag" page. + */ + static function factory_by_content_type($content_type) { + return flag_create_handler($content_type); + } + + /** + * Declares the options this flag supports, and their default values. + * + * Derived classes should want to override this. + */ + function options() { + $options = array( + // The text for the "flag this" link for this flag. + 'flag_short' => '', + // The description of the "flag this" link. + 'flag_long' => '', + // Message displayed after flagging content. + 'flag_message' => '', + // Likewise but for unflagged. + 'unflag_short' => '', + 'unflag_long' => '', + 'unflag_message' => '', + 'unflag_denied_text' => '', + // The link type used by the flag, as defined in hook_flag_link_types(). + 'link_type' => 'toggle', + 'roles' => array( + 'flag' => array(DRUPAL_AUTHENTICATED_RID), + 'unflag' => array(DRUPAL_AUTHENTICATED_RID), + ), + 'weight' => 0, + ); + + // Merge in options from the current link type. + $link_type = $this->get_link_type(); + $options = array_merge($options, $link_type['options']); + + // Allow other modules to change the flag options. + drupal_alter('flag_options', $options, $this); + return $options; + } + /** + * Provides a form for setting options. + * + * Derived classes should want to override this. + */ + function options_form(&$form) { + } + + /** + * Default constructor. Loads the default options. + */ + function construct() { + $options = $this->options(); + foreach ($options as $option => $value) { + $this->$option = $value; + } + } + + /** + * Update the flag with settings entered in a form. + */ + function form_input($form_values) { + // Load the form fields indiscriminately unto the flag (we don't care about + // stray FormAPI fields because we aren't touching unknown properties anyway. + foreach ($form_values as $field => $value) { + $this->$field = $value; + } + // But checkboxes need some massaging: + $this->roles['flag'] = array_values(array_filter($this->roles['flag'])); + $this->roles['unflag'] = array_values(array_filter($this->roles['unflag'])); + $this->types = array_values(array_filter($this->types)); + // Clear internal titles cache: + $this->get_title(NULL, TRUE); + } + + /** + * Validates this flag's options. + * + * @return + * A list of errors encountered while validating this flag's options. + */ + function validate() { + // TODO: It might be nice if this used automatic method discovery rather + // than hard-coding the list of validate functions. + return array_merge_recursive( + $this->validate_name(), + $this->validate_access() + ); + } + + /** + * Validates that the current flag's name is valid. + * + * @return + * A list of errors encountered while validating this flag's name. + */ + function validate_name() { + $errors = array(); + + // Ensure a safe machine name. + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $this->name)) { + $errors['name'][] = array( + 'error' => 'flag_name_characters', + 'message' => t('The flag name may only contain lowercase letters, underscores, and numbers.'), + ); + } + // Ensure the machine name is unique. + $flag = flag_get_flag($this->name); + if (!empty($flag) && (!isset($this->fid) || $flag->fid != $this->fid)) { + $errors['name'][] = array( + 'error' => 'flag_name_unique', + 'message' => t('Flag names must be unique. This flag name is already in use.'), + ); + } + + return $errors; + } + + /** + * Validates that the current flag's access settings are valid. + */ + function validate_access() { + $errors = array(); + + // Require an unflag access denied message a role is not allowed to unflag. + if (empty($this->unflag_denied_text)) { + foreach ($this->roles['flag'] as $key => $rid) { + if ($rid && empty($this->roles['unflag'][$key])) { + $errors['unflag_denied_text'][] = array( + 'error' => 'flag_denied_text_required', + 'message' => t('The "Unflag not allowed text" is required if any user roles are not allowed to unflag.'), + ); + break; + } + } + } + + // Do not allow unflag access without flag access. + foreach ($this->roles['unflag'] as $key => $rid) { + if ($rid && empty($this->roles['flag'][$key])) { + $errors['roles'][] = array( + 'error' => 'flag_roles_unflag', + 'message' => t('Any user role that has the ability to unflag must also have the ability to flag.'), + ); + break; + } + } + + return $errors; + } + + /** + * Fetches, possibly from some cache, a content object this flag works with. + */ + function fetch_content($content_id, $object_to_remember = NULL) { + static $cache = array(); + if (isset($object_to_remember)) { + $cache[$content_id] = $object_to_remember; + } + if (!array_key_exists($content_id, $cache)) { + $content = $this->_load_content($content_id); + $cache[$content_id] = $content ? $content : NULL; + } + return $cache[$content_id]; + } + + /** + * Loads a content object this flag works with. + * Derived classes must implement this. + * + * @abstract + * @private + * @static + */ + function _load_content($content_id) { + return NULL; + } + + /** + * Stores some object in fetch_content()'s cache, so subsequenet calls to + * fetch_content() return it. + * + * This is needed because otherwise fetch_object() loads the object from the + * database (by calling _load_content()), whereas sometimes we want to fetch + * an object that hasn't yet been saved to the database. See flag_nodeapi(). + */ + function remember_content($content_id, $object) { + $this->fetch_content($content_id, $object); + } + + /** + * @defgroup access Access control + * @{ + */ + + /** + * Returns TRUE if the flag applies to the given content. + * + * Derived classes must implement this. + * + * @abstract + */ + function applies_to_content_object($content) { + return FALSE; + } + + /** + * Returns TRUE if the flag applies to the content with the given ID. + * + * This is a convenience method that simply loads the object and calls + * applies_to_content_object(). If you already have the object, don't call + * this function: call applies_to_content_object() directly. + */ + function applies_to_content_id($content_id) { + return $this->applies_to_content_object($this->fetch_content($content_id)); + } + + /** + * Determines whether the user has access to use this flag. + * + * @param $action + * Optional. The action to test, either "flag" or "unflag". If none given, + * "flag" will be tested, which is the minimum permission to use a flag. + * @param $account + * Optional. The user object. If none given, the current user will be used. + * + * @return + * Boolean TRUE if the user is allowed to flag/unflag. FALSE otherwise. + */ + function user_access($action = 'flag', $account = NULL) { + if (!isset($account)) { + $account = $GLOBALS['user']; + } + + // Anonymous user can't use this system unless Session API is installed. + if ($account->uid == 0 && !module_exists('session_api')) { + return FALSE; + } + + $matched_roles = array_intersect($this->roles[$action], array_keys($account->roles)); + return !empty($matched_roles) || $account->uid == 1; + } + + /** + * Determines whether the user may flag, or unflag, the given content. + * + * This method typically should not be overridden by child classes. Instead + * they should implement type_access(), which is called by this method. + * + * @param $content_id + * The content ID to flag/unflag. + * @param $action + * The action to test. Either 'flag' or 'unflag'. Leave NULL to determine + * by flag status. + * @param $account + * The user on whose behalf to test the flagging action. Leave NULL for the + * current user. + * + * @return + * Boolean TRUE if the user is allowed to flag/unflag the given content. + * FALSE otherwise. + */ + function access($content_id, $action = NULL, $account = NULL) { + if (!isset($account)) { + $account = $GLOBALS['user']; + } + + if (isset($content_id) && !$this->applies_to_content_id($content_id)) { + // Flag does not apply to this content. + return FALSE; + } + + if (!isset($action)) { + $uid = $account->uid; + $sid = flag_get_sid($uid); + $action = $this->is_flagged($content_id, $uid, $sid) ? 'unflag' : 'flag'; + } + + // Base initial access on the user's basic permission to use this flag. + $access = $this->user_access($action, $account); + + // Check for additional access rules provided by sub-classes. + $child_access = $this->type_access($content_id, $action, $account); + if (isset($child_access)) { + $access = $child_access; + } + + // Allow modules to disallow (or allow) access to flagging. + $access_array = module_invoke_all('flag_access', $this, $content_id, $action, $account); + + foreach ($access_array as $set_access) { + if (isset($set_access)) { + $access = $set_access; + } + } + + return $access; + } + + /** + * Determine access to multiple objects. + * + * Similar to user_access() but works on multiple IDs at once. Called in the + * pre_render() stage of the 'Flag links' field within Views to find out where + * that link applies. The reason we do a separate DB query, and not lump this + * test in the Views query, is to make 'many to one' tests possible without + * interfering with the rows, and also to reduce the complexity of the code. + * + * This method typically should not be overridden by child classes. Instead + * they should implement type_access_multiple(), which is called by this + * method. + * + * @param $content_ids + * The array of content IDs to check. The keys are the content IDs, the + * values are the actions to test: either 'flag' or 'unflag'. + * @param $account + * Optional. The account for which the actions will be compared against. + * If left empty, the current user will be used. + * + * @return + * An array whose keys are the object IDs and values are booleans indicating + * access. + * + * @see hook_flag_access_multiple() + */ + function access_multiple($content_ids, $account = NULL) { + $account = isset($account) ? $account : $GLOBALS['user']; + $access = array(); + + // First check basic user access for this action. + foreach ($content_ids as $content_id => $action) { + $access[$content_id] = $this->user_access($content_ids[$content_id], $account); + } + + // Check for additional access rules provided by sub-classes. + $child_access = $this->type_access_multiple($content_ids, $account); + if (isset($child_access)) { + foreach ($child_access as $content_id => $content_access) { + if (isset($content_access)) { + $access[$content_id] = $content_access; + } + } + } + + // Merge in module-defined access. + foreach (module_implements('flag_access_multiple') as $module) { + $module_access = module_invoke($module, 'flag_access_multiple', $this, $content_ids, $account); + foreach ($module_access as $content_id => $content_access) { + if (isset($content_access)) { + $access[$content_id] = $content_access; + } + } + } + + return $access; + } + + /** + * Implements access() implemented by each child class. + * + * @abstract + */ + function type_access($content_id, $action, $account) { + return NULL; + } + + /** + * Implements access_multiple() implemented by each child class. + * + * @abstract + */ + function type_access_multiple($content_ids, $account) { + return array(); + } + + /** + * @} End of "defgroup access". + */ + + /** + * Given a content object, returns its ID. + * Derived classes must implement this. + * + * @abstract + */ + function get_content_id($content) { + return NULL; + } + + /** + * Returns TRUE if the flag is configured to show the flag-link using hook_link. + * Derived classes are likely to implement this. + */ + function uses_hook_link($teaser) { + return FALSE; + } + + /** + * Returns TRUE if this flag requires anonymous user cookies. + */ + function uses_anonymous_cookies() { + global $user; + return $user->uid == 0 && variable_get('cache', 0); + } + + /** + * Flags, or unflags, an item. + * + * @param $action + * Either 'flag' or 'unflag'. + * @param $content_id + * The ID of the item to flag or unflag. + * @param $account + * The user on whose behalf to flag. Leave empty for the current user. + * @param $skip_permission_check + * Flag the item even if the $account user don't have permission to do so. + * @param $flagging + * Optional. This method works in tandem with Drupal's Field subsystem. + * Pass in a flagging entity if you want operate on it as well. + * + * @return + * FALSE if some error occured (e.g., user has no permission, flag isn't + * applicable to the item, etc.), TRUE otherwise. + */ + function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { + // Get the user. + if (!isset($account)) { + $account = $GLOBALS['user']; + } + if (!$account) { + return FALSE; + } + + // Check access and applicability. + if (!$skip_permission_check) { + if (!$this->access($content_id, $action, $account)) { + // User has no permission to flag/unflag this object. + return FALSE; + } + } + else { + // We are skipping permission checks. However, at a minimum we must make + // sure the flag applies to this content type: + if (!$this->applies_to_content_id($content_id)) { + return FALSE; + } + } + + // Clear various caches; We don't want code running after us to report + // wrong counts or false flaggings. + flag_get_counts(NULL, NULL, TRUE); + flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_content_flags'); + + // Find out which user id to use. + $uid = $this->global ? 0 : $account->uid; + + // Find out which session id to use. + if ($this->global) { + $sid = 0; + } + else { + $sid = flag_get_sid($uid, TRUE); + // Anonymous users must always have a session id. + if ($sid == 0 && $account->uid == 0) { + return FALSE; + } + } + + // Set our uid and sid to the flagging object. + if (isset($flagging)) { + $flagging->uid = $uid; + $flagging->sid = $sid; + } + + // @todo: Discuss: Should we call field_attach_validate()? None of the + // entities in core does this (fields entered through forms are already + // validated). + // + // @todo: Discuss: Core wraps everything in a try { }, should we? + + // Perform the flagging or unflagging of this flag. + $existing_fcid = $this->_is_flagged($content_id, $uid, $sid); + $flagged = (bool) $existing_fcid; + if ($action == 'unflag') { + if ($this->uses_anonymous_cookies()) { + $this->_unflag_anonymous($content_id); + } + if ($flagged) { + // Note the order: We delete the entity before calling _unflag() to + // delete the {flag_content} record. + $this->_delete_flagging($existing_fcid); + $this->_unflag($content_id, $uid, $sid); + module_invoke_all('flag', 'unflag', $this, $content_id, $account, $existing_fcid); + } + } + elseif ($action == 'flag') { + if ($this->uses_anonymous_cookies()) { + $this->_flag_anonymous($content_id); + } + if (!$flagged) { + if (!isset($flagging)) { + // Construct a new flagging object if we don't have one. + $flagging = $this->new_flagging($content_id, $uid, $sid); + } + $fcid = $this->_flag($content_id, $uid, $sid); + // We're writing out a flagging entity even when we aren't passed one + // (e.g., when flagging via JavaScript toggle links); in this case + // Field API will assign the fields their default values. + $this->_insert_flagging($flagging, $content_id, $fcid); + module_invoke_all('flag', 'flag', $this, $content_id, $account, $fcid); + } + else { + // Nothing to do. Item is already flagged. + // + // Except in the case a $flagging object is passed in: in this case + // we're, for example, arriving from an editing form and need to update + // the entity. + if ($flagging) { + $this->_update_flagging($flagging); + } + } + } + + return TRUE; + } + + /** + * The entity CRUD methods _{insert,update,delete}_flagging() are for private + * use by the flag() method. + * + * The reason programmers should not call them directly is because a flagging + * operation is also accompanied by some bookkeeping (calling hooks, updating + * counters) or access control. These tasks are handled by the flag() method. + */ + private function _insert_flagging($flagging, $content_id, $fcid) { + $flagging->fcid = $fcid; + field_attach_presave('flagging', $flagging); + field_attach_insert('flagging', $flagging); + } + private function _update_flagging($flagging) { + field_attach_presave('flagging', $flagging); + field_attach_update('flagging', $flagging); + // Update the cache. + flagging_load($flagging->fcid, TRUE); + } + private function _delete_flagging($fcid) { + if (($flagging = flagging_load($fcid))) { + field_attach_delete('flagging', $flagging); + // Remove from the cache. + flagging_load($fcid, TRUE); + } + } + + /** + * Construct a new, empty flagging entity object. + * + * @param mixed $content_id + * The unique identifier of the content being flagged. + * @param int $uid + * Optional. The user id of the user doing the flagging. + * @param mixed $sid + * Optional. The user SID (provided by Session API) who is doing the + * flagging. The SID is 0 for logged in users. + * + * @return stdClass + * The returned object has at least the 'flag_name' property set, which + * enables Field API to figure out the bundle, but it's your responsibility + * to eventually populate 'content_id' and 'fcid'. + */ + function new_flagging($content_id = NULL, $uid = NULL, $sid = NULL) { + return (object) array( + 'fcid' => NULL, + 'flag_name' => $this->name, + 'content_id' => $content_id, + 'uid' => $uid, + 'sid' => $sid, + ); + } + + /** + * Determines if a certain user has flagged this content. + * + * Thanks to using a cache, inquiring several different flags about the same + * item results in only one SQL query. + * + * @param $uid + * Optional. The user ID whose flags we're checking. If none given, the + * current user will be used. + * + * @return + * TRUE if the content is flagged, FALSE otherwise. + */ + function is_flagged($content_id, $uid = NULL, $sid = NULL) { + return (bool) $this->get_flagging_record($content_id, $uid, $sid); + } + + /** + * Returns the flagging record. + * + * This method returns the "flagging record": the {flag_content} record that + * exists for each flagged item (for a certain user). If the item isn't + * flagged, returns NULL. This method could be useful, for example, when you + * want to find out the 'fcid' or 'timestamp' values. + * + * Thanks to using a cache, inquiring several different flags about the same + * item results in only one SQL query. + * + * Parameters are the same as is_flagged()'s. + */ + function get_flagging_record($content_id, $uid = NULL, $sid = NULL) { + $uid = $this->global ? 0 : (!isset($uid) ? $GLOBALS['user']->uid : $uid); + $sid = $this->global ? 0 : (!isset($sid) ? flag_get_sid($uid) : $sid); + + // flag_get_user_flags() does caching. + $user_flags = flag_get_user_flags($this->content_type, $content_id, $uid, $sid); + return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL; + } + + /** + * Similar to is_flagged() excepts it returns the flagging entity. + */ + function get_flagging($content_id, $uid = NULL, $sid = NULL) { + if (($record = $this->get_flagging_record($content_id, $uid, $sid))) { + return flagging_load($record->fcid); + } + } + + /** + * Determines if a certain user has flagged this content. + * + * You probably shouldn't call this raw private method: call the + * is_flagged() method instead. + * + * This method is similar to is_flagged() except that it does direct SQL and + * doesn't do caching. Use it when you want to not affect the cache, or to + * bypass it. + * + * @return + * If the content is flagged, returns the value of the 'fcid' column. + * Else, returns FALSE. + * + * @private + */ + function _is_flagged($content_id, $uid, $sid) { + return db_select('flag_content', 'fc') + ->fields('fc', array('fcid')) + ->condition('fid', $this->fid) + ->condition('uid', $uid) + ->condition('sid', $sid) + ->condition('content_id', $content_id) + ->execute() + ->fetchField(); + } + + /** + * A low-level method to flag content. + * + * You probably shouldn't call this raw private method: call the flag() + * function instead. + * + * @return + * The 'fcid' column of the new {flag_content} record. + * + * @private + */ + function _flag($content_id, $uid, $sid) { + $fcid = db_insert('flag_content') + ->fields(array( + 'fid' => $this->fid, + 'content_type' => $this->content_type, + 'content_id' => $content_id, + 'uid' => $uid, + 'sid' => $sid, + 'timestamp' => REQUEST_TIME, + )) + ->execute(); + $this->_increase_count($content_id); + return $fcid; + } + + /** + * A low-level method to unflag content. + * + * You probably shouldn't call this raw private method: call the flag() + * function instead. + * + * @return + * If the content was flagged, returns the value of the now deleted 'fcid' + * column. Else, returns FALSE. + * + * @private + */ + function _unflag($content_id, $uid, $sid) { + $fcid = db_select('flag_content', 'fc') + ->fields('fc', array('fcid')) + ->condition('fid', $this->fid) + ->condition('uid', $uid) + ->condition('sid', $sid) + ->condition('content_id', $content_id) + ->execute() + ->fetchField(); + if ($fcid) { + db_delete('flag_content')->condition('fcid', $fcid)->execute(); + $this->_decrease_count($content_id); + } + return $fcid; + } + + /** + * Increases the flag count for a piece of content. + * + * @param $content_id + * For which item should the count be increased. + * @param $number + * The amount of counts to increasing. Defaults to 1. + * + * @private + */ + function _increase_count($content_id, $number = 1) { + db_merge('flag_counts') + ->key(array( + 'fid' => $this->fid, + 'content_id' => $content_id, + )) + ->fields(array( + 'content_type' => $this->content_type, + 'count' => $number, + 'last_updated' => REQUEST_TIME, + )) + ->updateFields(array( + 'last_updated' => REQUEST_TIME, + )) + ->expression('count', 'count + :inc', array(':inc' => $number)) + ->execute(); + } + + /** + * Decreases the flag count for a piece of content. + * + * @param $content_id + * For which item should the count be descreased. + * @param $number + * The amount of counts to decrease. Defaults to 1. + * + * @private + */ + function _decrease_count($content_id, $number = 1) { + // Delete rows with count 0, for data consistency and space-saving. + // Done before the db_update() to prevent out-of-bounds errors on "count". + db_delete('flag_counts') + ->condition('fid', $this->fid) + ->condition('content_id', $content_id) + ->condition('count', $number, '<=') + ->execute(); + + // Update the count with the new value otherwise. + db_update('flag_counts') + ->expression('count', 'count - :inc', array(':inc' => $number)) + ->fields(array( + 'last_updated' => REQUEST_TIME, + )) + ->condition('fid', $this->fid) + ->condition('content_id', $content_id) + ->execute(); + } + + /** + * Set a cookie for anonymous users to record their flagging. + * + * @private + */ + function _flag_anonymous($content_id) { + $storage = FlagCookieStorage::factory($this); + $storage->flag($content_id); + } + + /** + * Remove the cookie for anonymous users to record their unflagging. + * + * @private + */ + function _unflag_anonymous($content_id) { + $storage = FlagCookieStorage::factory($this); + $storage->unflag($content_id); + } + + /** + * Returns the number of times an item is flagged. + * + * Thanks to using a cache, inquiring several different flags about the same + * item results in only one SQL query. + */ + function get_count($content_id) { + $counts = flag_get_counts($this->content_type, $content_id); + return isset($counts[$this->name]) ? $counts[$this->name] : 0; + } + + /** + * Returns the number of items a user has flagged. + * + * For global flags, pass '0' as the user ID and session ID. + */ + function get_user_count($uid, $sid = NULL) { + if (!isset($sid)) { + $sid = flag_get_sid($uid); + } + return db_select('flag_content', 'fc')->fields('fc', array('fcid')) + ->condition('fid', $this->fid)->condition('uid', $uid)->condition('sid', $sid) + ->countQuery()->execute()->fetchField(); + } + + /** + * Processes a flag label for display. This means language translation and + * token replacements. + * + * You should always call this function and not get at the label directly. + * E.g., do `print $flag->get_label('title')` instead of `print + * $flag->title`. + * + * @param $label + * The label to get, e.g. 'title', 'flag_short', 'unflag_short', etc. + * @param $content_id + * The ID in whose context to interpret tokens. If not given, only global + * tokens will be substituted. + * @return + * The processed label. + */ + function get_label($label, $content_id = NULL) { + if (!isset($this->$label)) { + return; + } + $label = t($this->$label); + if (strpos($label, '[') !== FALSE) { + $label = $this->replace_tokens($label, array(), array('sanitize' => FALSE), $content_id); + } + return filter_xss_admin($label); + } + + /** + * Get the link type for this flag. + */ + function get_link_type() { + $link_types = flag_get_link_types(); + return (isset($this->link_type) && isset($link_types[$this->link_type])) ? $link_types[$this->link_type] : $link_types['normal']; + } + + /** + * Replaces tokens in a label. Only the 'global' token context is recognized + * by default, so derived classes should override this method to add all + * token contexts they understand. + */ + function replace_tokens($label, $contexts, $options, $content_id) { + if (strpos($label , 'flagging:') !== FALSE) { + if (($flagging = $this->get_flagging($content_id))) { + $contexts['flagging'] = $flagging; + } + } + return token_replace($label, $contexts, $options); + } + + /** + * Returns the token types this flag understands in labels. These are used + * for narrowing down the token list shown in the help box to only the + * relevant ones. + * + * Derived classes should override this. + */ + function get_labels_token_types() { + return array('flagging'); + } + + /** + * A convenience method for getting the flag title. + * + * `$flag->get_title()` is shorthand for `$flag->get_label('title')`. + */ + function get_title($content_id = NULL, $reset = FALSE) { + static $titles = array(); + if ($reset) { + $titles = array(); + } + $slot = intval($content_id); // Convert NULL to 0. + if (!isset($titles[$this->fid][$slot])) { + $titles[$this->fid][$slot] = $this->get_label('title', $content_id); + } + return $titles[$this->fid][$slot]; + } + + /** + * Returns a 'flag action' object. It exists only for the sake of its + * informative tokens. Currently, it's utilized only for the 'mail' action. + * + * Derived classes should populate the 'content_title' and 'content_url' + * slots. + */ + function get_flag_action($content_id) { + $flag_action = new stdClass(); + $flag_action->flag = $this->name; + $flag_action->content_type = $this->content_type; + $flag_action->content_id = $content_id; + return $flag_action; + } + + /** + * @addtogroup actions + * @{ + * Methods that can be overridden to support Actions. + */ + + /** + * Returns an array of all actions that are executable with this flag. + */ + function get_valid_actions() { + $actions = module_invoke_all('action_info'); + foreach ($actions as $callback => $action) { + if ($action['type'] != $this->content_type && !in_array('any', $action['triggers'])) { + unset($actions[$callback]); + } + } + return $actions; + } + + /** + * Returns objects the action may possibly need. This method should return at + * least the 'primary' object the action operates on. + * + * This method is needed because get_valid_actions() returns actions that + * don't necessarily operate on an object of a type this flag manages. For + * example, flagging a comment may trigger an 'Unpublish post' action on a + * node; So the comment flag needs to tell the action about some node. + * + * Derived classes must implement this. + * + * @abstract + */ + function get_relevant_action_objects($content_id) { + return array(); + } + + /** + * @} End of "addtogroup actions". + */ + + /** + * @addtogroup views + * @{ + * Methods that can be overridden to support the Views module. + */ + + /** + * Returns information needed for Views integration. E.g., the Views table + * holding the flagged content, its primary key, and various labels. See + * derived classes for examples. + * + * @static + */ + function get_views_info() { + return array(); + } + + /** + * @} End of "addtogroup views". + */ + + /** + * Saves a flag to the database. It is a wrapper around update() and insert(). + */ + function save() { + if (isset($this->fid)) { + $this->update(); + $this->is_new = FALSE; + } + else { + $this->insert(); + $this->is_new = TRUE; + } + // Clear the page cache for anonymous users. + cache_clear_all('*', 'cache_page', TRUE); + } + + /** + * Saves an existing flag to the database. Better use save(). + */ + function update() { + db_update('flags')->fields(array( + 'name' => $this->name, + 'title' => $this->title, + 'global' => $this->global, + 'options' => $this->get_serialized_options())) + ->condition('fid', $this->fid) + ->execute(); + db_delete('flag_types')->condition('fid', $this->fid)->execute(); + foreach ($this->types as $type) { + db_insert('flag_types')->fields(array( + 'fid' => $this->fid, + 'type' => $type)) + ->execute(); + } + } + + /** + * Saves a new flag to the database. Better use save(). + */ + function insert() { + $this->fid = db_insert('flags') + ->fields(array( + 'content_type' => $this->content_type, + 'name' => $this->name, + 'title' => $this->title, + 'global' => $this->global, + 'options' => $this->get_serialized_options(), + )) + ->execute(); + foreach ($this->types as $type) { + db_insert('flag_types') + ->fields(array( + 'fid' => $this->fid, + 'type' => $type, + )) + ->execute(); + } + } + + /** + * Options are stored serialized in the database. + */ + function get_serialized_options() { + $option_names = array_keys($this->options()); + $options = array(); + foreach ($option_names as $option) { + $options[$option] = $this->$option; + } + return serialize($options); + } + + /** + * Deletes a flag from the database. + */ + function delete() { + db_delete('flags')->condition('fid', $this->fid)->execute(); + db_delete('flag_content')->condition('fid', $this->fid)->execute(); + db_delete('flag_types')->condition('fid', $this->fid)->execute(); + db_delete('flag_counts')->condition('fid', $this->fid)->execute(); + module_invoke_all('flag_delete', $this); + } + + /** + * Returns TRUE if this flag's declared API version is compatible with this + * module. + * + * An "incompatible" flag is one exported (and now being imported or exposed + * via hook_flag_default_flags()) by a different version of the Flag module. + * An incompatible flag should be treated as a "black box": it should not be + * saved or exported because our code may not know to handle its internal + * structure. + */ + function is_compatible() { + if (isset($this->fid)) { + // Database flags are always compatible. + return TRUE; + } + else { + if (!isset($this->api_version)) { + $this->api_version = 1; + } + return $this->api_version == FLAG_API_VERSION; + } + } + + /** + * Finds the "default flag" corresponding to this flag. + * + * Flags defined in code ("default flags") can be overridden. This method + * returns the default flag that is being overridden by $this. Returns NULL + * if $this overrides no default flag. + */ + function find_default_flag() { + if ($this->fid) { + $default_flags = flag_get_default_flags(TRUE); + if (isset($default_flags[$this->name])) { + return $default_flags[$this->name]; + } + } + } + + /** + * Reverts an overriding flag to its default state. + * + * Note that $this isn't altered. To see the reverted flag you'll have to + * call flag_get_flag($this->name) again. + * + * @return + * TRUE if the flag was reverted successfully; FALSE if there was an error; + * NULL if this flag overrides no default flag. + */ + function revert() { + if (($default_flag = $this->find_default_flag())) { + if ($default_flag->is_compatible()) { + $default_flag = clone $default_flag; + $default_flag->fid = $this->fid; + $default_flag->save(); + flag_get_flags(NULL, NULL, NULL, TRUE); + return TRUE; + } + else { + return FALSE; + } + } + } + + /** + * Disable a flag provided by a module. + */ + function disable() { + if (isset($this->module)) { + $flag_status = variable_get('flag_default_flag_status', array()); + $flag_status[$this->name] = FALSE; + variable_set('flag_default_flag_status', $flag_status); + } + } + + /** + * Enable a flag provided by a module. + */ + function enable() { + if (isset($this->module)) { + $flag_status = variable_get('flag_default_flag_status', array()); + $flag_status[$this->name] = TRUE; + variable_set('flag_default_flag_status', $flag_status); + } + } + + /** + * Returns administrative menu path for carrying out some action. + */ + function admin_path($action) { + if ($action == 'edit') { + // Since 'edit' is the default tab, we omit the action. + return FLAG_ADMIN_PATH . '/manage/' . $this->name; + } + else { + return FLAG_ADMIN_PATH . '/manage/' . $this->name . '/' . $action; + } + } + + /** + * Renders a flag/unflag link. This is a wrapper around theme('flag') that, + * in Drupal 6, easily channels the call to the right template file. + * + * For parameters docmentation, see theme_flag(). + */ + function theme($action, $content_id, $after_flagging = FALSE) { + static $js_added = array(); + global $user; + + // If the flagging user is anonymous, set a boolean for the benefit of + // JavaScript code. Currently, only our "anti-crawlers" mechanism uses it. + if ($user->uid == 0 && !isset($js_added['anonymous'])) { + $js_added['anonymous'] = TRUE; + drupal_add_js(array('flag' => array('anonymous' => TRUE)), 'setting'); + } + + // If the flagging user is anonymous and the page cache is enabled, we + // update the links through JavaScript. + if ($this->uses_anonymous_cookies() && !$after_flagging) { + if ($this->global) { + // In case of global flags, the JavaScript template is to contain + // the opposite of the current state. + $js_action = ($action == 'flag' ? 'unflag' : 'flag'); + } + else { + // In case of non-global flags, we always show the "flag!" link, + // and then replace it with the "unflag!" link through JavaScript. + $js_action = 'unflag'; + $action = 'flag'; + } + if (!isset($js_added[$this->name . '_' . $content_id])) { + $js_added[$this->name . '_' . $content_id] = TRUE; + $js_template = theme($this->theme_suggestions(), array('flag' => $this, 'action' => $js_action, 'content_id' => $content_id, 'after_flagging' => $after_flagging)); + drupal_add_js(array('flag' => array('templates' => array($this->name . '_' . $content_id => $js_template))), 'setting'); + } + } + + return theme($this->theme_suggestions(), array('flag' => $this, 'action' => $action, 'content_id' => $content_id, 'after_flagging' => $after_flagging)); + } + + /** + * Provides an array of possible themes to try for a given flag. + */ + function theme_suggestions() { + $suggestions = array(); + $suggestions[] = 'flag__' . $this->name; + $suggestions[] = 'flag'; + return $suggestions; + } +} + +/** + * A dummy flag to be used where the real implementation can't be found. + */ +class flag_broken extends flag_flag { + function options_form(&$form) { + $form = array(); + $form['error'] = array( + '#markup' => '
' . t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->content_type)) . '
', + ); + } +} diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc new file mode 100644 index 0000000..6ecf757 --- /dev/null +++ b/includes/flag/flag_node.inc @@ -0,0 +1,155 @@ + TRUE, + 'show_on_teaser' => TRUE, + 'show_on_form' => FALSE, + 'show_contextual_link' => FALSE, + 'i18n' => 0, + ); + return $options; + } + + /** + * Options form extras for node flags. + */ + function options_form(&$form) { + parent::options_form($form); + + $form['access']['access_author'] = array( + '#type' => 'radios', + '#title' => t('Flag access by content authorship'), + '#options' => array( + '' => t('No additional restrictions'), + 'own' => t('Users may only flag content they own'), + 'others' => t('Users may only flag content of others'), + ), + '#default_value' => $this->access_author, + '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), + ); + + // Support for i18n flagging requires Translation helpers module. + $form['i18n'] = array( + '#type' => 'radios', + '#title' => t('Internationalization'), + '#options' => array( + '1' => t('Flag translations of content as a group'), + '0' => t('Flag each translation of content separately'), + ), + '#default_value' => $this->i18n, + '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), + '#access' => module_exists('translation_helpers'), + '#weight' => 5, + ); + + $form['display']['show_on_teaser'] = array( + '#type' => 'checkbox', + '#title' => t('Display link on node teaser'), + '#default_value' => $this->show_on_teaser, + '#access' => empty($this->locked['show_on_teaser']), + ); + + $form['display']['show_on_page'] = array( + '#type' => 'checkbox', + '#title' => t('Display link on node page'), + '#default_value' => $this->show_on_page, + '#access' => empty($this->locked['show_on_page']), + ); + // Override the UI texts for nodes. + $form['display']['show_on_form'] = array( + '#title' => t('Display checkbox on node edit form'), + '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), + ) + $form['display']['show_on_form']; + $form['display']['show_contextual_link'] = array( + '#type' => 'checkbox', + '#title' => t('Display in contextual links'), + '#default_value' => $this->show_contextual_link, + '#access' => empty($this->locked['show_contextual_link']) && module_exists('contextual'), + ); + + unset($form['display']['show_on_entity']); + } + + function type_access_multiple($content_ids, $account = NULL) { + $access = array(); + + // Ensure that only flaggable node types are granted access. This avoids a + // node_load() on every type, usually done by applies_to_content_id(). + $result = db_select('node', 'n')->fields('n', array('nid')) + ->condition('nid', array_keys($content_ids), 'IN') + ->condition('type', $this->types, 'NOT IN') + ->execute(); + foreach ($result as $row) { + $access[$row->nid] = FALSE; + } + + return $access; + } + + /** + * Adjust the Content ID to find the translation parent if i18n-enabled. + * + * @param $content_id + * The nid for the content. + * @return + * The tnid if available, the nid otherwise. + */ + function get_translation_id($content_id) { + if ($this->i18n) { + $node = $this->fetch_content($content_id); + if (!empty($node->tnid)) { + $content_id = $node->tnid; + } + } + return $content_id; + } + + function uses_hook_link($teaser) { + if ($teaser && $this->show_on_teaser || !$teaser && $this->show_on_page) { + return TRUE; + } + return FALSE; + } + + function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { + $content_id = $this->get_translation_id($content_id); + return parent::flag($action, $content_id, $account, $skip_permission_check, $flagging); + } + + // Instead of overriding is_flagged() we override get_flagging_record(), + // which is the underlying method. + function get_flagging_record($content_id, $uid = NULL, $sid = NULL) { + $content_id = $this->get_translation_id($content_id); + return parent::get_flagging_record($content_id, $uid, $sid); + } + + function replace_tokens($label, $contexts, $options, $content_id) { + if (is_numeric($content_id) && ($node = $this->fetch_content($content_id))) { + $contexts['node'] = $node; + } + // Nodes accept the node-type as a $content_id in the case that a new node + // is being created and a full node object does not yet exist. + elseif (!empty($content_id) && ($type = node_type_get_type($content_id))) { + $content_id = NULL; + $contexts['node'] = (object) array( + 'nid' => NULL, + 'type' => $type->type, + 'title' => '', + ); + } + return parent::replace_tokens($label, $contexts, $options, $content_id); + } +} diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc new file mode 100644 index 0000000..b302393 --- /dev/null +++ b/includes/flag/flag_user.inc @@ -0,0 +1,106 @@ + TRUE, + 'access_uid' => '', + ); + return $options; + } + + /** + * Options form extras for user flags. + */ + function options_form(&$form) { + parent::options_form($form); + $form['access']['types'] = array( + // A user flag doesn't support node types. + // TODO: Maybe support roles instead of node types. + '#type' => 'value', + '#value' => array(0 => 0), + ); + $form['access']['access_uid'] = array( + '#type' => 'checkbox', + '#title' => t('Users may flag themselves'), + '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themself does not make sense.'), + '#default_value' => $this->access_uid ? 0 : 1, + ); + $form['display']['show_on_profile'] = array( + '#type' => 'checkbox', + '#title' => t('Display link on user profile page'), + '#default_value' => $this->show_on_profile, + '#access' => empty($this->locked['show_on_profile']), + ); + + unset($form['display']['show_on_entity']); + } + + function form_input($form_values) { + parent::form_input($form_values); + // The access_uid value is intentionally backwards from the UI, to avoid + // confusion caused by checking a box to disable a feature. + $this->access_uid = empty($form_values['access_uid']) ? 'others' : ''; + } + + function type_access($content_id, $action, $account) { + // Prevent users from flagging themselves. + if ($this->access_uid == 'others' && $content_id == $account->uid) { + return FALSE; + } + } + + function type_access_multiple($content_ids, $account) { + $access = array(); + + // Exclude anonymous. + if (array_key_exists(0, $content_ids)) { + $access[0] = FALSE; + } + + // Prevent users from flagging themselves. + if ($this->access_uid == 'others' && array_key_exists($account->uid, $content_ids)) { + $access[$account->uid] = FALSE; + } + + return $access; + } + + function uses_hook_link($teaser) { + if ($this->show_on_profile) { + return TRUE; + } + return FALSE; + } + + function get_flag_action($content_id) { + $flag_action = parent::get_flag_action($content_id); + $user = $this->fetch_content($content_id); + $flag_action->content_title = $user->name; + $flag_action->content_url = _flag_url('user/' . $user->uid); + return $flag_action; + } + + function get_relevant_action_objects($content_id) { + return array( + 'user' => $this->fetch_content($content_id), + ); + } + + function get_views_info() { + $views_info = parent::get_views_info(); + $views_info['title field'] = 'name'; + return $views_info; + } +} From f14ce82e7e56b2291e2f71bac4a9e227ad3fbd46 Mon Sep 17 00:00:00 2001 From: joachim Date: Sat, 28 Jul 2012 21:59:03 -0500 Subject: [PATCH 095/629] Issue #1703468 by joachim: move views files to includes/views --- flag.info | 12 +++++++----- includes/{ => views}/flag.views.inc | 0 includes/{ => views}/flag.views_convert.inc | 0 .../{ => views}/flag_handler_argument_content_id.inc | 0 includes/{ => views}/flag_handler_field_ops.inc | 0 includes/{ => views}/flag_handler_filter_flagged.inc | 0 includes/{ => views}/flag_handler_relationships.inc | 0 .../flag_plugin_argument_validate_flaggability.inc | 0 8 files changed, 7 insertions(+), 5 deletions(-) rename includes/{ => views}/flag.views.inc (100%) rename includes/{ => views}/flag.views_convert.inc (100%) rename includes/{ => views}/flag_handler_argument_content_id.inc (100%) rename includes/{ => views}/flag_handler_field_ops.inc (100%) rename includes/{ => views}/flag_handler_filter_flagged.inc (100%) rename includes/{ => views}/flag_handler_relationships.inc (100%) rename includes/{ => views}/flag_plugin_argument_validate_flaggability.inc (100%) diff --git a/flag.info b/flag.info index 0c3b65a..a5c4055 100644 --- a/flag.info +++ b/flag.info @@ -15,9 +15,11 @@ files[] = includes/flag.cookie_storage.inc files[] = includes/flag.entity.inc files[] = flag.rules.inc -files[] = includes/flag_handler_argument_content_id.inc -files[] = includes/flag_handler_field_ops.inc -files[] = includes/flag_handler_filter_flagged.inc -files[] = includes/flag_handler_relationships.inc -files[] = includes/flag_plugin_argument_validate_flaggability.inc + +; Views +files[] = includes/views/flag_handler_argument_content_id.inc +files[] = includes/views/flag_handler_field_ops.inc +files[] = includes/views/flag_handler_filter_flagged.inc +files[] = includes/views/flag_handler_relationships.inc +files[] = includes/views/flag_plugin_argument_validate_flaggability.inc files[] = tests/flag.test diff --git a/includes/flag.views.inc b/includes/views/flag.views.inc similarity index 100% rename from includes/flag.views.inc rename to includes/views/flag.views.inc diff --git a/includes/flag.views_convert.inc b/includes/views/flag.views_convert.inc similarity index 100% rename from includes/flag.views_convert.inc rename to includes/views/flag.views_convert.inc diff --git a/includes/flag_handler_argument_content_id.inc b/includes/views/flag_handler_argument_content_id.inc similarity index 100% rename from includes/flag_handler_argument_content_id.inc rename to includes/views/flag_handler_argument_content_id.inc diff --git a/includes/flag_handler_field_ops.inc b/includes/views/flag_handler_field_ops.inc similarity index 100% rename from includes/flag_handler_field_ops.inc rename to includes/views/flag_handler_field_ops.inc diff --git a/includes/flag_handler_filter_flagged.inc b/includes/views/flag_handler_filter_flagged.inc similarity index 100% rename from includes/flag_handler_filter_flagged.inc rename to includes/views/flag_handler_filter_flagged.inc diff --git a/includes/flag_handler_relationships.inc b/includes/views/flag_handler_relationships.inc similarity index 100% rename from includes/flag_handler_relationships.inc rename to includes/views/flag_handler_relationships.inc diff --git a/includes/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc similarity index 100% rename from includes/flag_plugin_argument_validate_flaggability.inc rename to includes/views/flag_plugin_argument_validate_flaggability.inc From 142e7589274a6a19bd216ddeb6fb0c23a5d731cf Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:57:32 +0100 Subject: [PATCH 096/629] Issue #1703468, fixup, by joachim: Fixed broken path in hook_views_api(). --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 8d4fcb8..c00aa4b 100644 --- a/flag.module +++ b/flag.module @@ -290,7 +290,7 @@ function flag_init() { function flag_views_api() { return array( 'api' => 2.0, - 'path' => drupal_get_path('module', 'flag') . '/includes', + 'path' => drupal_get_path('module', 'flag') . '/includes/views', ); } From 5c0284bafa4e54369dca134fe9b1b8b2a092e790 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 2 Aug 2012 19:38:54 +0100 Subject: [PATCH 097/629] Issue #1704806 by joachim: Fixed flag_field_extra_fields() attempting to act on flags that are on non-entity objects. --- flag.module | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flag.module b/flag.module index c00aa4b..cbe8b1d 100644 --- a/flag.module +++ b/flag.module @@ -415,6 +415,11 @@ function flag_field_extra_fields() { $flags = flag_get_flags(); foreach ($flags as $name => $flag) { + // Skip flags that aren't on entities. + if (!is_subclass_of($flag, 'flag_entity')) { + continue; + } + // In order to make sense with this hook's structure, we use D7 lingo, hence // some translation is required... $entity_type = $flag->content_type; From 50379b10c066c065a3d7cdd14fcfd94bce08a7a7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 2 Aug 2012 20:07:56 +0100 Subject: [PATCH 098/629] Issue #1710302 by havran: Fixed missing curly braces in query. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index cbe8b1d..fcd6841 100644 --- a/flag.module +++ b/flag.module @@ -1008,7 +1008,7 @@ function flag_session_api_cleanup($arg = 'run') { function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { // This query can't use db_delete() because that doesn't support a // subquery: see http://drupal.org/node/1267508. - db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM flags WHERE content_type = :entity_type)", array( + db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flags} WHERE content_type = :entity_type)", array( ':bundle' => $bundle, ':entity_type' => $entity_type, )); From ed26176bb6f8a4aea6cc31d54a167a1e97e9b766 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 3 Aug 2012 08:49:11 +0100 Subject: [PATCH 099/629] Issue #1709498 by joachim: Changed lengths of db columns for entity and bundle names to 128. --- flag.install | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flag.install b/flag.install index e46382c..63e3fd3 100644 --- a/flag.install +++ b/flag.install @@ -105,7 +105,7 @@ function flag_schema() { 'content_type' => array( 'description' => 'The flag type, such as one of "node", "comment", or "user".', 'type' => 'varchar', - 'length' => '32', + 'length' => '128', 'not null' => TRUE, 'default' => '', ), @@ -162,7 +162,7 @@ function flag_schema() { 'content_type' => array( 'description' => 'The flag type, one of "node", "comment", "user".', 'type' => 'varchar', - 'length' => '32', + 'length' => '128', 'not null' => TRUE, 'default' => '', ), @@ -221,7 +221,7 @@ function flag_schema() { 'type' => array( 'description' => 'The types (usually from {node_type}) that can be flagged by this fid.', 'type' => 'varchar', - 'length' => '32', + 'length' => '128', 'not null' => TRUE, 'default' => '', ), @@ -244,7 +244,7 @@ function flag_schema() { 'content_type' => array( 'description' => 'The flag type, usually one of "node", "comment", "user".', 'type' => 'varchar', - 'length' => '32', + 'length' => '128', 'not null' => TRUE, 'default' => '', ), From 2127cdda334fbcce413600ce24b9258a40fa3b73 Mon Sep 17 00:00:00 2001 From: scyther Date: Sat, 4 Aug 2012 18:18:56 -0500 Subject: [PATCH 100/629] Issue #1689400 by Scyther: make use of machine name field in admin UI --- includes/flag.admin.inc | 63 ++++++++++++++++------------------------- tests/flag.test | 6 ++-- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 0aa6066..5a9a929 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -195,30 +195,21 @@ function theme_flag_admin_page($variables) { /** * Menu callback for adding a new flag. */ -function flag_add_page($type = NULL, $name = NULL) { +function flag_add_page($entity_type = NULL) { drupal_set_title(t('Add new flag')); - if (isset($type) && isset($name)) { - $flag = flag_flag::factory_by_content_type($type); - $flag->name = $name; + + if (isset($entity_type)) { + $flag = flag_flag::factory_by_content_type($entity_type); return drupal_get_form('flag_form', $flag); } - else { - return drupal_get_form('flag_add_form'); - } + + return drupal_get_form('flag_add_form'); } /** * Present a form for creating a new flag, setting the type of flag. */ function flag_add_form($form, &$form_state) { - $form['name'] = array( - '#type' => 'textfield', - '#title' => t('Flag name'), - '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#maxlength' => 32, - '#required' => TRUE, - ); - $types = array(); foreach (flag_fetch_definition() as $type => $info) { $types[$type] = $info['title'] . '
' . $info['description'] . '
'; @@ -239,7 +230,7 @@ function flag_add_form($form, &$form_state) { $form['actions']['submit'] = array( '#type' => 'submit', - '#value' => t('Add flag'), + '#value' => t('Add flag'), // @todo: maybe a new text here for the submit button? ); return $form; @@ -247,17 +238,14 @@ function flag_add_form($form, &$form_state) { function flag_add_form_validate($form, &$form_state) { $flag = flag_flag::factory_by_content_type($form_state['values']['type']); - $flag->name = $form_state['values']['name']; - $errors = $flag->validate_name(); - foreach ($errors as $field => $field_errors) { - foreach ($field_errors as $error) { - form_set_error($field, $error['message']); - } + + if (get_class($flag) == 'flag_broken') { + form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); } } function flag_add_form_submit($form, &$form_state) { - $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type'] . '/' . $form_state['values']['name']; + $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type']; } /** @@ -266,21 +254,6 @@ function flag_add_form_submit($form, &$form_state) { function flag_form($form, &$form_state, $flag) { $form['#flag'] = $flag; - $form['name'] = array( - '#type' => 'textfield', - '#title' => t('Name'), - '#default_value' => $flag->name, - '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#maxlength' => 32, - '#required' => TRUE, - '#access' => empty($flag->locked['name']), - '#weight' => -3, - ); - - if (!empty($flag->fid)) { - $form['name']['#description'] .= ' ' . t('Change this value only with great care.') . ''; - } - $form['title'] = array( '#type' => 'textfield', '#title' => t('Title'), @@ -289,7 +262,21 @@ function flag_form($form, &$form_state, $flag) { '#maxlength' => 255, '#required' => TRUE, '#access' => empty($flag->locked['title']), + '#weight' => -3, + ); + + $form['name'] = array( + '#type' => 'machine_name', + '#title' => t('Machine name'), + '#default_value' => $flag->name, + '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), + '#maxlength' => 32, + '#access' => empty($flag->locked['name']), '#weight' => -2, + '#machine_name' => array( + 'exists' => 'flag_get_flag', + 'source' => array('title'), + ), ); $form['global'] = array( diff --git a/tests/flag.test b/tests/flag.test index 4580d7f..8803507 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -36,7 +36,7 @@ class FlagTestCase extends DrupalWebTestCase { function testFlagAdmin() { // Add a new flag using the UI. $edit = array( - 'name' => strtolower($this->randomName()), + 'name' => drupal_strtolower($this->randomName()), 'title' => $this->randomName(), 'flag_short' => 'flag short [node:nid]', 'flag_long' => 'flag long [node:nid]', @@ -58,7 +58,7 @@ class FlagTestCase extends DrupalWebTestCase { $saved['types'] = array('page'); unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); - $this->drupalPost(FLAG_ADMIN_PATH . '/add/node/' . $edit['name'], $edit, t('Save flag')); + $this->drupalPost(FLAG_ADMIN_PATH . '/add/node', $edit, t('Save flag')); flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); @@ -73,7 +73,7 @@ class FlagTestCase extends DrupalWebTestCase { // Edit the flag through the UI. $edit = array( - 'name' => strtolower($this->randomName()), + 'name' => drupal_strtolower($this->randomName()), 'title' => $this->randomName(), 'flag_short' => 'flag 2 short [node:nid]', 'flag_long' => 'flag 2 long [node:nid]', From c9830e5b9438c89dba85750b9c9e8fdc286486f1 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 5 Aug 2012 10:20:34 +0100 Subject: [PATCH 101/629] Revert "Issue #1689400 by Scyther: make use of machine name field in admin UI" This reverts commit 2127cdda334fbcce413600ce24b9258a40fa3b73. Allow patch at http://drupal.org/node/1689400 to be committed first. --- includes/flag.admin.inc | 63 +++++++++++++++++++++++++---------------- tests/flag.test | 6 ++-- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 5a9a929..0aa6066 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -195,21 +195,30 @@ function theme_flag_admin_page($variables) { /** * Menu callback for adding a new flag. */ -function flag_add_page($entity_type = NULL) { +function flag_add_page($type = NULL, $name = NULL) { drupal_set_title(t('Add new flag')); - - if (isset($entity_type)) { - $flag = flag_flag::factory_by_content_type($entity_type); + if (isset($type) && isset($name)) { + $flag = flag_flag::factory_by_content_type($type); + $flag->name = $name; return drupal_get_form('flag_form', $flag); } - - return drupal_get_form('flag_add_form'); + else { + return drupal_get_form('flag_add_form'); + } } /** * Present a form for creating a new flag, setting the type of flag. */ function flag_add_form($form, &$form_state) { + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Flag name'), + '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), + '#maxlength' => 32, + '#required' => TRUE, + ); + $types = array(); foreach (flag_fetch_definition() as $type => $info) { $types[$type] = $info['title'] . '
' . $info['description'] . '
'; @@ -230,7 +239,7 @@ function flag_add_form($form, &$form_state) { $form['actions']['submit'] = array( '#type' => 'submit', - '#value' => t('Add flag'), // @todo: maybe a new text here for the submit button? + '#value' => t('Add flag'), ); return $form; @@ -238,14 +247,17 @@ function flag_add_form($form, &$form_state) { function flag_add_form_validate($form, &$form_state) { $flag = flag_flag::factory_by_content_type($form_state['values']['type']); - - if (get_class($flag) == 'flag_broken') { - form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); + $flag->name = $form_state['values']['name']; + $errors = $flag->validate_name(); + foreach ($errors as $field => $field_errors) { + foreach ($field_errors as $error) { + form_set_error($field, $error['message']); + } } } function flag_add_form_submit($form, &$form_state) { - $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type']; + $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type'] . '/' . $form_state['values']['name']; } /** @@ -254,6 +266,21 @@ function flag_add_form_submit($form, &$form_state) { function flag_form($form, &$form_state, $flag) { $form['#flag'] = $flag; + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Name'), + '#default_value' => $flag->name, + '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), + '#maxlength' => 32, + '#required' => TRUE, + '#access' => empty($flag->locked['name']), + '#weight' => -3, + ); + + if (!empty($flag->fid)) { + $form['name']['#description'] .= ' ' . t('Change this value only with great care.') . ''; + } + $form['title'] = array( '#type' => 'textfield', '#title' => t('Title'), @@ -262,21 +289,7 @@ function flag_form($form, &$form_state, $flag) { '#maxlength' => 255, '#required' => TRUE, '#access' => empty($flag->locked['title']), - '#weight' => -3, - ); - - $form['name'] = array( - '#type' => 'machine_name', - '#title' => t('Machine name'), - '#default_value' => $flag->name, - '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#maxlength' => 32, - '#access' => empty($flag->locked['name']), '#weight' => -2, - '#machine_name' => array( - 'exists' => 'flag_get_flag', - 'source' => array('title'), - ), ); $form['global'] = array( diff --git a/tests/flag.test b/tests/flag.test index 8803507..4580d7f 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -36,7 +36,7 @@ class FlagTestCase extends DrupalWebTestCase { function testFlagAdmin() { // Add a new flag using the UI. $edit = array( - 'name' => drupal_strtolower($this->randomName()), + 'name' => strtolower($this->randomName()), 'title' => $this->randomName(), 'flag_short' => 'flag short [node:nid]', 'flag_long' => 'flag long [node:nid]', @@ -58,7 +58,7 @@ class FlagTestCase extends DrupalWebTestCase { $saved['types'] = array('page'); unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); - $this->drupalPost(FLAG_ADMIN_PATH . '/add/node', $edit, t('Save flag')); + $this->drupalPost(FLAG_ADMIN_PATH . '/add/node/' . $edit['name'], $edit, t('Save flag')); flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); @@ -73,7 +73,7 @@ class FlagTestCase extends DrupalWebTestCase { // Edit the flag through the UI. $edit = array( - 'name' => drupal_strtolower($this->randomName()), + 'name' => strtolower($this->randomName()), 'title' => $this->randomName(), 'flag_short' => 'flag 2 short [node:nid]', 'flag_long' => 'flag 2 long [node:nid]', From a45605aa751108c5443d1f381dc8420ff5e8bb6d Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:23:12 +0100 Subject: [PATCH 102/629] Changed name of 'flag_content' table to 'flagging'. --- flag.api.php | 2 +- flag.install | 2 +- flag.module | 38 +++++++++---------- flag.rules.inc | 4 +- .../includes/flag_bookmark.views_default.inc | 4 +- includes/flag/flag_flag.inc | 18 ++++----- includes/views/flag.views.inc | 19 ++++++---- includes/views/flag.views_convert.inc | 10 ++--- includes/views/flag_handler_field_ops.inc | 8 ++-- ..._plugin_argument_validate_flaggability.inc | 2 +- 10 files changed, 55 insertions(+), 52 deletions(-) diff --git a/flag.api.php b/flag.api.php index f48f23e..1bf4e20 100644 --- a/flag.api.php +++ b/flag.api.php @@ -93,7 +93,7 @@ function hook_flag_options_alter(&$options, $flag) { * @param $account * The user account performing the action. * @param $fcid - * The id of the flagging in the {flag_content} table. + * The id of the flagging in the {flagging} table. */ function hook_flag($op, $flag, $content_id, $account, $fcid) { diff --git a/flag.install b/flag.install index 63e3fd3..d989e46 100644 --- a/flag.install +++ b/flag.install @@ -142,7 +142,7 @@ function flag_schema() { ), ); - $schema['flag_content'] = array( + $schema['flagging'] = array( 'description' => 'Content that has been flagged.', 'fields' => array( 'fcid' => array( diff --git a/flag.module b/flag.module index fcd6841..009c52d 100644 --- a/flag.module +++ b/flag.module @@ -29,7 +29,7 @@ function flag_entity_info() { 'flagging' => array( 'label' => t('Flagging'), 'controller class' => 'FlaggingController', - 'base table' => 'flag_content', + 'base table' => 'flagging', 'fieldable' => TRUE, 'entity keys' => array( 'id' => 'fcid', @@ -800,7 +800,7 @@ function flag_node_translation_change($node) { $content_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid']; foreach (flag_get_flags('node') as $flag) { if ($flag->i18n) { - db_update('flag_content')->fields(array('content_id' => $content_id)) + db_update('flagging')->fields(array('content_id' => $content_id)) ->condition('fid', $flag->fid) ->condition('content_id', $node->translation_change['old_tnid']) ->execute(); @@ -824,7 +824,7 @@ function flag_node_translation_change($node) { * The flag id */ function _flag_content_delete($entity_type, $entity_id, $fid = NULL) { - $query_content = db_delete('flag_content') + $query_content = db_delete('flagging') ->condition('content_type', $entity_type) ->condition('content_id', $entity_id); $query_counts = db_delete('flag_counts') @@ -844,9 +844,9 @@ function _flag_content_delete($entity_type, $entity_id, $fid = NULL) { function flag_user_login(&$edit, &$account) { // Migrate anonymous flags to this user's account. if (module_exists('session_api') && ($sid = flag_get_sid(0))) { - // Get a list of flag_content IDs that will be moved over. + // Get a list of flagging IDs that will be moved over. $duplicate_flaggings = array(); - $flaggings = db_select('flag_content', 'fc') + $flaggings = db_select('flagging', 'fc') ->fields('fc', array('fcid', 'fid', 'content_id')) ->condition('uid', 0) ->condition('sid', $sid) @@ -859,7 +859,7 @@ function flag_user_login(&$edit, &$account) { // Any duplicate content that was flagged as anonoymous is deleted in the // subsequent db_delete() call. try { - db_update('flag_content') + db_update('flagging') ->fields(array( 'uid' => $account->uid, 'sid' => 0, @@ -905,7 +905,7 @@ function flag_user_delete($account) { */ function flag_user_account_removal($account) { // Remove flags by this user. - $query = db_select('flag_content', 'fc'); + $query = db_select('flagging', 'fc'); $query->leftJoin('flag_counts', 'c', 'fc.content_id = c.content_id AND fc.content_type = c.content_type'); $result = $query ->fields('fc', array('fid', 'content_id')) @@ -932,7 +932,7 @@ function flag_user_account_removal($account) { ->execute(); } } - db_delete('flag_content') + db_delete('flagging') ->condition('uid', $account->uid) ->execute(); @@ -980,7 +980,7 @@ function flag_user_view($account, $view_mode) { function flag_session_api_cleanup($arg = 'run') { // Session API 1.1 version: if ($arg == 'run') { - $query = db_select('flag_content', 'fc'); + $query = db_select('flagging', 'fc'); $query->leftJoin('session_api', 's', 'fc.sid = s.sid'); $result = $query ->fields('fc', array('sid')) @@ -988,7 +988,7 @@ function flag_session_api_cleanup($arg = 'run') { ->isNull('s.sid') ->execute(); foreach ($result as $row) { - db_delete('flag_content') + db_delete('flagging') ->condition('sid', $row->sid) ->execute(); } @@ -996,7 +996,7 @@ function flag_session_api_cleanup($arg = 'run') { // Session API 1.2+ version. elseif (is_array($arg)) { $outdated_sids = $arg; - db_delete('flag_content')->condition('sid', $outdated_sids, 'IN')->execute(); + db_delete('flagging')->condition('sid', $outdated_sids, 'IN')->execute(); } } @@ -1351,7 +1351,7 @@ function flag_flag_access_multiple($flag, $content_ids, $account) { * The number of flaggings allowed. Any flaggings beyond that will be trimmed. */ function flag_trim_flag($flag, $account, $cutoff_size) { - $result = db_select('flag_content', 'fc') + $result = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid) ->condition(db_or()->condition('uid', $account->uid)->condition('uid', 0)) @@ -1375,7 +1375,7 @@ function flag_trim_flag($flag, $account, $cutoff_size) { * empty, this will remove all of this flag's content. */ function flag_reset_flag($flag, $content_id = NULL) { - $query = db_select('flag_content', 'fc') + $query = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid); @@ -1390,7 +1390,7 @@ function flag_reset_flag($flag, $content_id = NULL) { } module_invoke_all('flag_reset', $flag, $content_id, $rows); - $query = db_delete('flag_content')->condition('fid' , $flag->fid); + $query = db_delete('flagging')->condition('fid' , $flag->fid); // Update the flag_counts table. $count_query = db_delete('flag_counts')->condition('fid', $flag->fid); if ($content_id) { @@ -1932,7 +1932,7 @@ function flag_get_default_flags($include_disabled = FALSE) { function flag_get_flagged_content($flag_name) { $return = array(); $flag = flag_get_flag($flag_name); - $result = db_select('flag_content', 'fc') + $result = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid) ->execute(); @@ -1949,7 +1949,7 @@ function flag_get_flagged_content($flag_name) { * The flag content ID for which to look up the content ID. */ function flag_get_content_id($fcid) { - return db_select('flag_content', 'fc') + return db_select('flagging', 'fc') ->fields('fc', array('content_id')) ->condition('fcid', $fcid) ->execute() @@ -2000,7 +2000,7 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si if (!isset($flagged_content[$uid][$sid][$content_type][$content_id])) { $flag_names = _flag_get_flag_names(); $flagged_content[$uid][$sid][$content_type][$content_id] = array(); - $result = db_select('flag_content', 'fc') + $result = db_select('flagging', 'fc') ->fields('fc') ->condition('content_type', $content_type) ->condition('content_id', $content_id) @@ -2022,7 +2022,7 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si if (!isset($flagged_content[$uid][$sid][$content_type]['all'])) { $flag_names = _flag_get_flag_names(); $flagged_content[$uid][$sid][$content_type]['all'] = array(); - $result = db_select('flag_content', 'fc') + $result = db_select('flagging', 'fc') ->fields('fc') ->condition('content_type', $content_type) ->condition(db_or() @@ -2061,7 +2061,7 @@ function flag_get_content_flags($content_type, $content_id, $flag_name = NULL) { if (!isset($content_flags[$content_type][$content_id])) { $flag_names = _flag_get_flag_names(); - $result = db_select('flag_content', 'fc') + $result = db_select('flagging', 'fc') ->fields('fc') ->condition('content_type', $content_type) ->condition('content_id', $content_id) diff --git a/flag.rules.inc b/flag.rules.inc index fcdfa40..4570162 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -321,7 +321,7 @@ function flag_rules_action_trim($flag, $flagging_user, $cutoff_size) { * Base action implementation: Fetch users who flagged an entity. */ function flag_rules_action_fetch_users($flag, $entity) { - $result = db_select('flag_content', 'fc') + $result = db_select('flagging', 'fc') ->fields('fc', array('uid')) ->condition('content_type', $flag->content_type) ->condition('content_id', $flag->get_content_id($entity)) @@ -336,7 +336,7 @@ function flag_rules_action_fetch_users($flag, $entity) { * Base action implementation: Fetch entities who were flagged a user. */ function flag_rules_action_fetch_entity_by_user($flag, $user) { - $result = db_select('flag_content', 'fc') + $result = db_select('flagging', 'fc') ->fields('fc', array('content_id')) ->condition('content_type', $flag->content_type) ->condition('uid', $user->uid) diff --git a/flag_bookmark/includes/flag_bookmark.views_default.inc b/flag_bookmark/includes/flag_bookmark.views_default.inc index 6673b11..808d59d 100644 --- a/flag_bookmark/includes/flag_bookmark.views_default.inc +++ b/flag_bookmark/includes/flag_bookmark.views_default.inc @@ -157,7 +157,7 @@ function flag_bookmark_views_default_views() { 'label' => 'bookmarks_user', 'required' => 1, 'id' => 'uid', - 'table' => 'flag_content', + 'table' => 'flagging', 'field' => 'uid', 'relationship' => 'flag_content_rel', ), @@ -239,7 +239,7 @@ function flag_bookmark_views_default_views() { 'ops' => array( 'label' => 'Ops', 'id' => 'ops', - 'table' => 'flag_content', + 'table' => 'flagging', 'field' => 'ops', 'relationship' => 'flag_content_rel', ), diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 0c4c3cb..77aba60 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -578,7 +578,7 @@ class flag_flag { } if ($flagged) { // Note the order: We delete the entity before calling _unflag() to - // delete the {flag_content} record. + // delete the {flagging} record. $this->_delete_flagging($existing_fcid); $this->_unflag($content_id, $uid, $sid); module_invoke_all('flag', 'unflag', $this, $content_id, $account, $existing_fcid); @@ -688,7 +688,7 @@ class flag_flag { /** * Returns the flagging record. * - * This method returns the "flagging record": the {flag_content} record that + * This method returns the "flagging record": the {flagging} record that * exists for each flagged item (for a certain user). If the item isn't * flagged, returns NULL. This method could be useful, for example, when you * want to find out the 'fcid' or 'timestamp' values. @@ -733,7 +733,7 @@ class flag_flag { * @private */ function _is_flagged($content_id, $uid, $sid) { - return db_select('flag_content', 'fc') + return db_select('flagging', 'fc') ->fields('fc', array('fcid')) ->condition('fid', $this->fid) ->condition('uid', $uid) @@ -750,12 +750,12 @@ class flag_flag { * function instead. * * @return - * The 'fcid' column of the new {flag_content} record. + * The 'fcid' column of the new {flagging} record. * * @private */ function _flag($content_id, $uid, $sid) { - $fcid = db_insert('flag_content') + $fcid = db_insert('flagging') ->fields(array( 'fid' => $this->fid, 'content_type' => $this->content_type, @@ -782,7 +782,7 @@ class flag_flag { * @private */ function _unflag($content_id, $uid, $sid) { - $fcid = db_select('flag_content', 'fc') + $fcid = db_select('flagging', 'fc') ->fields('fc', array('fcid')) ->condition('fid', $this->fid) ->condition('uid', $uid) @@ -791,7 +791,7 @@ class flag_flag { ->execute() ->fetchField(); if ($fcid) { - db_delete('flag_content')->condition('fcid', $fcid)->execute(); + db_delete('flagging')->condition('fcid', $fcid)->execute(); $this->_decrease_count($content_id); } return $fcid; @@ -895,7 +895,7 @@ class flag_flag { if (!isset($sid)) { $sid = flag_get_sid($uid); } - return db_select('flag_content', 'fc')->fields('fc', array('fcid')) + return db_select('flagging', 'fc')->fields('fc', array('fcid')) ->condition('fid', $this->fid)->condition('uid', $uid)->condition('sid', $sid) ->countQuery()->execute()->fetchField(); } @@ -1129,7 +1129,7 @@ class flag_flag { */ function delete() { db_delete('flags')->condition('fid', $this->fid)->execute(); - db_delete('flag_content')->condition('fid', $this->fid)->execute(); + db_delete('flagging')->condition('fid', $this->fid)->execute(); db_delete('flag_types')->condition('fid', $this->fid)->execute(); db_delete('flag_counts')->condition('fid', $this->fid)->execute(); module_invoke_all('flag_delete', $this); diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index 2c3402d..d7c3e5c 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -35,10 +35,13 @@ function flag_views_plugins() { function flag_views_data() { $data = array(); - $data['flag_content']['table']['group'] = t('Flags'); + $data['flagging']['table']['group'] = t('Flags'); $data['flag_counts']['table']['group'] = t('Flags'); - $data['flag_content']['uid'] = array( + // Notify views from flag 2.x of our changes to views data. + // @see flag_update_7301(). + $data['flag_content']['moved to'] = 'flagging'; + $data['flagging']['uid'] = array( 'title' => t('User uid'), 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), 'relationship' => array( @@ -59,7 +62,7 @@ function flag_views_data() { ), ); - $data['flag_content']['timestamp'] = array( + $data['flagging']['timestamp'] = array( 'title' => t('Flagged time'), 'help' => t('Display the time the content was flagged by a user.'), 'field' => array( @@ -78,7 +81,7 @@ function flag_views_data() { ); // Argument for content ID, used for "Who's flagged this" views. - $data['flag_content']['content_id'] = array( + $data['flagging']['content_id'] = array( 'title' => t('Content ID'), 'help' => t('The unique ID of the object that has been flagged.'), 'argument' => array( @@ -87,7 +90,7 @@ function flag_views_data() { ); // Specialized is null/is not null filter. - $data['flag_content']['flagged'] = array( + $data['flagging']['flagged'] = array( 'title' => t('Flagged'), 'help' => t('Filter to ensure content has or has not been flagged.'), 'real field' => 'uid', @@ -98,7 +101,7 @@ function flag_views_data() { ); // Flag content links. - $data['flag_content']['ops'] = array( + $data['flagging']['ops'] = array( 'title' => t('Flag link'), 'help' => t('Display flag/unflag link.'), 'field' => array( @@ -164,7 +167,7 @@ function flag_views_data_alter(&$data) { 'flag type' => $flag_type, 'handler' => 'flag_handler_relationship_content', 'label' => t('flag'), - 'base' => 'flag_content', + 'base' => 'flagging', 'base field' => 'content_id', 'relationship field' => $info['join field'], ), @@ -193,7 +196,7 @@ function flag_views_data_alter(&$data) { 'title' => t("User's flagged content"), 'help' => t('Limit results to users that have flagged certain content.'), 'relationship' => array( - 'base' => 'flag_content', + 'base' => 'flagging', 'base field' => 'uid', 'relationship field' => 'uid', 'handler' => 'flag_handler_relationship_user_content', diff --git a/includes/views/flag.views_convert.inc b/includes/views/flag.views_convert.inc index d7e0d07..ed8910d 100644 --- a/includes/views/flag.views_convert.inc +++ b/includes/views/flag.views_convert.inc @@ -50,7 +50,7 @@ function flag_views_convert($display, $type, &$view, $field, $id) { $new_field = array( 'label' => $field['label'], 'id' => 'ops', - 'table' => 'flag_content', + 'table' => 'flagging', 'field' => 'ops', 'relationship' => 'flag_content_rel', ); @@ -85,7 +85,7 @@ function flag_views_convert($display, $type, &$view, $field, $id) { case 'exposed_filter': switch ($id) { case 'uid': - // The flag_content uid filter means "Include content only flagged by + // The flagging uid filter means "Include content only flagged by // the current user". In D6, this is no longer a filter, but instead // part of the relationship. Make the relationship join on the uid. if ($field['value'] == '***CURRENT_USER***') { @@ -101,7 +101,7 @@ function flag_views_convert($display, $type, &$view, $field, $id) { 'value' => flag_views_convert_timestamp_value($field['value']), 'group' => 0, 'id' => 'timestamp', - 'table' => 'flag_content', + 'table' => 'flagging', 'field' => 'timestamp', 'relationship' => 'flag_content_rel', 'exposed' => $type == 'exposed_filter' ? 1 : 0, @@ -155,7 +155,7 @@ function flag_views_convert($display, $type, &$view, $field, $id) { $new_field = array( 'order' => $field['sortorder'], 'id' => 'timestamp', - 'table' => 'flag_content', + 'table' => 'flagging', 'field' => 'timestamp', 'relationship' => 'flag_content_rel', ); @@ -203,7 +203,7 @@ function flag_views_convert($display, $type, &$view, $field, $id) { 'label' => isset($flag_name) ? $flag_name . ' user' : 'user', 'required' => 0, 'id' => 'uid', - 'table' => 'flag_content', + 'table' => 'flagging', 'field' => 'uid', 'relationship' => 'flag_content_rel', ); diff --git a/includes/views/flag_handler_field_ops.inc b/includes/views/flag_handler_field_ops.inc index aaa8f2b..cf29a67 100644 --- a/includes/views/flag_handler_field_ops.inc +++ b/includes/views/flag_handler_field_ops.inc @@ -73,9 +73,9 @@ class flag_handler_field_ops extends views_handler_field { // Find out if the content is flagged. We can't just peek at some field in // our loaded table because it doesn't always reflect the user browsing the - // page. So we explicitly add the flag_content table to find this out. + // page. So we explicitly add the flagging table to find this out. $join = new views_join(); - $join->construct('flag_content', $info['views table'], $info['join field'], 'content_id'); + $join->construct('flagging', $info['views table'], $info['join field'], 'content_id'); $join->extra[] = array( 'field' => 'fid', 'value' => $flag->fid, @@ -93,11 +93,11 @@ class flag_handler_field_ops extends views_handler_field { 'numeric' => TRUE, ); } - $flag_table = $this->query->add_table('flag_content', $parent, $join); + $flag_table = $this->query->add_table('flagging', $parent, $join); $this->aliases['is_flagged'] = $this->query->add_field($flag_table, 'content_id'); // Next, find out the content ID. We can't add_field() on this table - // (flag_content), because its content_id may be NULL (in case no user has + // (flagging), because its content_id may be NULL (in case no user has // flagged this content, and it's a LEFT JOIN). So we reach to the parent // relationship and add_field() *its* content ID column. $left_table = $this->view->relationship[$this->options['relationship']]->table_alias; diff --git a/includes/views/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc index cb3587a..3863bed 100644 --- a/includes/views/flag_plugin_argument_validate_flaggability.inc +++ b/includes/views/flag_plugin_argument_validate_flaggability.inc @@ -222,7 +222,7 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v return array(); } $flattened_ids = implode(',', $ids); - return $this->_test_by_sql("SELECT content_id FROM {flag_content} WHERE fid = :fid AND content_id IN ($flattened_ids) AND uid = :uid", array(':fid' => $flag->fid, ':uid' => $user->uid)); + return $this->_test_by_sql("SELECT content_id FROM {flagging} WHERE fid = :fid AND content_id IN ($flattened_ids) AND uid = :uid", array(':fid' => $flag->fid, ':uid' => $user->uid)); } // Helper: executes an SQL query and returns all the content_id's. From 849782389cbcfe2fbe5d537a595abae550f9e938 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 13:09:50 +0100 Subject: [PATCH 103/629] Added flag_update_7301() to rename {flag_content} table to {flagging}. --- flag.install | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/flag.install b/flag.install index d989e46..2e196d6 100644 --- a/flag.install +++ b/flag.install @@ -446,3 +446,12 @@ function flag_update_7203() { function flag_update_7300() { registry_rebuild(); } + +/** + * Rename {flag_content} table to {flagging}. + */ +function flag_update_7301() { + db_rename_table('flag_content', 'flagging'); + // A second cache clear appears to be required here. + cache_clear_all(); +} From 627cbab181bb5f302f3e07cb28b0543a28e1d6cd Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 13:16:04 +0100 Subject: [PATCH 104/629] Changed name of 'flags' table to 'flag'. --- flag.install | 2 +- flag.module | 6 +++--- flag_actions.module | 2 +- includes/flag.entity.inc | 4 ++-- includes/flag/flag_flag.inc | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/flag.install b/flag.install index 2e196d6..9359e90 100644 --- a/flag.install +++ b/flag.install @@ -92,7 +92,7 @@ function _flag_flag_content_message() { function flag_schema() { $schema = array(); - $schema['flags'] = array( + $schema['flag'] = array( 'description' => 'All available flags in the system.', 'fields' => array( 'fid' => array( diff --git a/flag.module b/flag.module index 009c52d..439b12f 100644 --- a/flag.module +++ b/flag.module @@ -1008,7 +1008,7 @@ function flag_session_api_cleanup($arg = 'run') { function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { // This query can't use db_delete() because that doesn't support a // subquery: see http://drupal.org/node/1267508. - db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flags} WHERE content_type = :entity_type)", array( + db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flag} WHERE content_type = :entity_type)", array( ':bundle' => $bundle, ':entity_type' => $entity_type, )); @@ -1684,7 +1684,7 @@ function flag_get_counts($content_type, $content_id, $reset = FALSE) { if (!isset($counts[$content_type][$content_id])) { $counts[$content_type][$content_id] = array(); - $query = db_select('flags', 'f'); + $query = db_select('flag', 'f'); $query->leftJoin('flag_counts', 'fc', 'f.fid = fc.fid'); $result = $query ->fields('f', array('name')) @@ -1778,7 +1778,7 @@ function flag_get_flags($content_type = NULL, $content_subtype = NULL, $account $flags = array(); // Database flags. - $query = db_select('flags', 'f'); + $query = db_select('flag', 'f'); $query->leftJoin('flag_types', 'fn', 'fn.fid = f.fid'); $result = $query ->fields('f', array('fid', 'content_type', 'name', 'title', 'global', 'options')) diff --git a/flag_actions.module b/flag_actions.module index 6a06880..6504229 100644 --- a/flag_actions.module +++ b/flag_actions.module @@ -86,7 +86,7 @@ function flag_actions_get_actions($flag_name = NULL, $reset = FALSE) { if (!isset($flag_actions) || $reset) { $flag_actions = array(); $query = db_select('flag_actions', 'a'); - $query->innerJoin('flags', 'f', 'a.fid = f.fid'); + $query->innerJoin('flag', 'f', 'a.fid = f.fid'); $query->addField('f', 'name', 'flag'); $result = $query ->fields('a') diff --git a/includes/flag.entity.inc b/includes/flag.entity.inc index 6fee9b5..55dba6a 100644 --- a/includes/flag.entity.inc +++ b/includes/flag.entity.inc @@ -17,8 +17,8 @@ class FlaggingController extends DrupalDefaultEntityController { protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { $query = parent::buildQuery($ids, $conditions, $revision_id); // Add the flag name, which determines the bundle. - $query->innerJoin('flags', 'flags', 'base.fid = flags.fid'); - $query->addField('flags', 'name', 'flag_name'); + $query->innerJoin('flag', 'flag', 'base.fid = flag.fid'); + $query->addField('flag', 'name', 'flag_name'); return $query; } } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 77aba60..3b7ad47 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1073,7 +1073,7 @@ class flag_flag { * Saves an existing flag to the database. Better use save(). */ function update() { - db_update('flags')->fields(array( + db_update('flag')->fields(array( 'name' => $this->name, 'title' => $this->title, 'global' => $this->global, @@ -1093,7 +1093,7 @@ class flag_flag { * Saves a new flag to the database. Better use save(). */ function insert() { - $this->fid = db_insert('flags') + $this->fid = db_insert('flag') ->fields(array( 'content_type' => $this->content_type, 'name' => $this->name, @@ -1128,7 +1128,7 @@ class flag_flag { * Deletes a flag from the database. */ function delete() { - db_delete('flags')->condition('fid', $this->fid)->execute(); + db_delete('flag')->condition('fid', $this->fid)->execute(); db_delete('flagging')->condition('fid', $this->fid)->execute(); db_delete('flag_types')->condition('fid', $this->fid)->execute(); db_delete('flag_counts')->condition('fid', $this->fid)->execute(); From 7235167c2b77d86dc264b1a8f3e6f49ae27cf5ac Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 13:16:45 +0100 Subject: [PATCH 105/629] Added rename of {flags} to flag_update_7301(). --- flag.install | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 9359e90..6a3d4f2 100644 --- a/flag.install +++ b/flag.install @@ -448,10 +448,11 @@ function flag_update_7300() { } /** - * Rename {flag_content} table to {flagging}. + * Rename {flag_content} table to {flagging} and {flags} table to {flag}. */ function flag_update_7301() { db_rename_table('flag_content', 'flagging'); + db_rename_table('flags', 'flag'); // A second cache clear appears to be required here. cache_clear_all(); } From 6f408e5579836e758a6305ea21efefe647ba3bed Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 13:29:11 +0100 Subject: [PATCH 106/629] Changed all $content_type variables to $entity_type. Replace s/\$content_type\b/$entity_type/ throughout. --- flag.inc | 14 ++-- flag.module | 70 +++++++++---------- includes/flag.actions.inc | 8 +-- includes/flag/flag_flag.inc | 6 +- includes/views/flag.views.inc | 14 ++-- includes/views/flag_handler_relationships.inc | 10 +-- 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/flag.inc b/flag.inc index 9e91db9..167e294 100644 --- a/flag.inc +++ b/flag.inc @@ -56,7 +56,7 @@ function flag_flag_definitions_alter(&$definitions) { /** * Returns a flag definition. */ -function flag_fetch_definition($content_type = NULL) { +function flag_fetch_definition($entity_type = NULL) { static $defintions; if (!isset($defintions)) { $defintions = module_invoke_all('flag_definitions'); @@ -68,9 +68,9 @@ function flag_fetch_definition($content_type = NULL) { } } - if (isset($content_type)) { - if (isset($defintions[$content_type])) { - return $defintions[$content_type]; + if (isset($entity_type)) { + if (isset($defintions[$entity_type])) { + return $defintions[$entity_type]; } } else { @@ -94,15 +94,15 @@ function flag_get_types() { * flag". A factory method usually populates this empty flag with settings * loaded from the database. */ -function flag_create_handler($content_type) { - $definition = flag_fetch_definition($content_type); +function flag_create_handler($entity_type) { + $definition = flag_fetch_definition($entity_type); if (isset($definition) && class_exists($definition['handler'])) { $handler = new $definition['handler']; } else { $handler = new flag_broken; } - $handler->content_type = $content_type; + $handler->content_type = $entity_type; $handler->construct(); return $handler; } diff --git a/flag.module b/flag.module index 439b12f..2ba23de 100644 --- a/flag.module +++ b/flag.module @@ -1662,7 +1662,7 @@ function _flag_link_type_fields() { /** * Get flag counts for all flags on a node. * - * @param $content_type + * @param $entity_type * The content type (usually 'node'). * @param $content_id * The content ID (usually the node ID). @@ -1672,32 +1672,32 @@ function _flag_link_type_fields() { * @return $flags * An array of the structure [name] => [number of flags]. */ -function flag_get_counts($content_type, $content_id, $reset = FALSE) { +function flag_get_counts($entity_type, $content_id, $reset = FALSE) { static $counts; if ($reset) { $counts = array(); - if (!isset($content_type)) { + if (!isset($entity_type)) { return; } } - if (!isset($counts[$content_type][$content_id])) { - $counts[$content_type][$content_id] = array(); + if (!isset($counts[$entity_type][$content_id])) { + $counts[$entity_type][$content_id] = array(); $query = db_select('flag', 'f'); $query->leftJoin('flag_counts', 'fc', 'f.fid = fc.fid'); $result = $query ->fields('f', array('name')) ->fields('fc', array('count')) - ->condition('fc.content_type', $content_type) + ->condition('fc.content_type', $entity_type) ->condition('fc.content_id', $content_id) ->execute(); foreach ($result as $row) { - $counts[$content_type][$content_id][$row->name] = $row->count; + $counts[$entity_type][$content_id][$row->name] = $row->count; } } - return $counts[$content_type][$content_id]; + return $counts[$entity_type][$content_id]; } /** @@ -1757,7 +1757,7 @@ function flag_get_flag($name = NULL, $fid = NULL) { * If node type or account are entered, a list of all possible flags will be * returned. * - * @param $content_type + * @param $entity_type * Optional. The type of content for which to load the flags. Usually 'node'. * @param $content_subtype * Optional. The node type for which to load the flags. @@ -1770,7 +1770,7 @@ function flag_get_flag($name = NULL, $fid = NULL) { * @return $flags * An array of the structure [fid] = flag_object. */ -function flag_get_flags($content_type = NULL, $content_subtype = NULL, $account = NULL, $reset = FALSE) { +function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL, $reset = FALSE) { static $flags; // Retrieve a list of all flags, regardless of the parameters. @@ -1829,9 +1829,9 @@ function flag_get_flags($content_type = NULL, $content_subtype = NULL, $account $filtered_flags = $flags; // Filter out flags based on type and subtype. - if (isset($content_type) || isset($content_subtype)) { + if (isset($entity_type) || isset($content_subtype)) { foreach ($filtered_flags as $name => $flag) { - if (!_flag_content_enabled($flag, $content_type, $content_subtype)) { + if (!_flag_content_enabled($flag, $entity_type, $content_subtype)) { unset($filtered_flags[$name]); } } @@ -1865,7 +1865,7 @@ function _flag_compare_weight($flag1, $flag2) { * Utility function: Checks whether a flag applies to a certain type, and * possibly subtype, of content. * - * @param $content_type + * @param $entity_type * The type of content being checked, usually "node". * @param $content_subtype * The subtype (node type) being checked. @@ -1873,8 +1873,8 @@ function _flag_compare_weight($flag1, $flag2) { * @return * TRUE if the flag is enabled for this type and subtype. */ -function _flag_content_enabled($flag, $content_type, $content_subtype = NULL) { - $return = $flag->content_type == $content_type && (!isset($content_subtype) || in_array($content_subtype, $flag->types)); +function _flag_content_enabled($flag, $entity_type, $content_subtype = NULL) { + $return = $flag->content_type == $entity_type && (!isset($content_subtype) || in_array($content_subtype, $flag->types)); return $return; } @@ -1959,7 +1959,7 @@ function flag_get_content_id($fcid) { /** * Find what a user has flagged, either a single node or on the entire site. * - * @param $content_type + * @param $entity_type * The type of content that will be retrieved. Usually 'node'. * @param $content_id * Optional. The content ID to check for flagging. If none given, all @@ -1983,12 +1983,12 @@ function flag_get_content_id($fcid) { * [flag_name] => [content_id] => Object from above. * */ -function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) { +function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) { static $flagged_content; if ($reset) { $flagged_content = array(); - if (!isset($content_type)) { + if (!isset($entity_type)) { return; } } @@ -1997,12 +1997,12 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si $sid = !isset($sid) ? flag_get_sid($uid) : $sid; if (isset($content_id)) { - if (!isset($flagged_content[$uid][$sid][$content_type][$content_id])) { + if (!isset($flagged_content[$uid][$sid][$entity_type][$content_id])) { $flag_names = _flag_get_flag_names(); - $flagged_content[$uid][$sid][$content_type][$content_id] = array(); + $flagged_content[$uid][$sid][$entity_type][$content_id] = array(); $result = db_select('flagging', 'fc') ->fields('fc') - ->condition('content_type', $content_type) + ->condition('content_type', $entity_type) ->condition('content_id', $content_id) ->condition(db_or() ->condition('uid', $uid) @@ -2012,19 +2012,19 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si ->execute(); foreach ($result as $flag_content) { - $flagged_content[$uid][$sid][$content_type][$content_id][$flag_names[$flag_content->fid]] = $flag_content; + $flagged_content[$uid][$sid][$entity_type][$content_id][$flag_names[$flag_content->fid]] = $flag_content; } } - return $flagged_content[$uid][$sid][$content_type][$content_id]; + return $flagged_content[$uid][$sid][$entity_type][$content_id]; } else { - if (!isset($flagged_content[$uid][$sid][$content_type]['all'])) { + if (!isset($flagged_content[$uid][$sid][$entity_type]['all'])) { $flag_names = _flag_get_flag_names(); - $flagged_content[$uid][$sid][$content_type]['all'] = array(); + $flagged_content[$uid][$sid][$entity_type]['all'] = array(); $result = db_select('flagging', 'fc') ->fields('fc') - ->condition('content_type', $content_type) + ->condition('content_type', $entity_type) ->condition(db_or() ->condition('uid', $uid) ->condition('uid', 0) @@ -2032,10 +2032,10 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si ->condition('sid', $sid) ->execute(); foreach ($result as $flag_content) { - $flagged_content[$uid][$sid][$content_type]['all'][$flag_names[$flag_content->fid]][$flag_content->content_id] = $flag_content; + $flagged_content[$uid][$sid][$entity_type]['all'][$flag_names[$flag_content->fid]][$flag_content->content_id] = $flag_content; } } - return $flagged_content[$uid][$sid][$content_type]['all']; + return $flagged_content[$uid][$sid][$entity_type]['all']; } } @@ -2043,7 +2043,7 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si /** * Return a list of users who have flagged a piece of content. * - * @param $content_type + * @param $entity_type * The type of content that will be retrieved. Usually 'node'. * @param $content_id * The content ID to check for flagging. @@ -2056,26 +2056,26 @@ function flag_get_user_flags($content_type, $content_id = NULL, $uid = NULL, $si * an array of flag information for each flag, keyed by the flag name. If * a flag name is specified, only the information for that flag is returned. */ -function flag_get_content_flags($content_type, $content_id, $flag_name = NULL) { +function flag_get_content_flags($entity_type, $content_id, $flag_name = NULL) { $content_flags = &drupal_static(__FUNCTION__, array()); - if (!isset($content_flags[$content_type][$content_id])) { + if (!isset($content_flags[$entity_type][$content_id])) { $flag_names = _flag_get_flag_names(); $result = db_select('flagging', 'fc') ->fields('fc') - ->condition('content_type', $content_type) + ->condition('content_type', $entity_type) ->condition('content_id', $content_id) ->orderBy('timestamp', 'DESC') ->execute(); foreach ($result as $flag_content) { // Build a list of flaggings for all flags by user. - $content_flags[$content_type][$content_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; + $content_flags[$entity_type][$content_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; // Build a list of flaggings for each individual flag. - $content_flags[$content_type][$content_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; + $content_flags[$entity_type][$content_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; } } - return isset($flag_name) ? $content_flags[$content_type][$content_id]['flags'][$flag_name] : $content_flags[$content_type][$content_id]['users']; + return isset($flag_name) ? $content_flags[$entity_type][$content_id]['flags'][$flag_name] : $content_flags[$entity_type][$content_id]['users']; } /** diff --git a/includes/flag.actions.inc b/includes/flag.actions.inc index 4f55529..d7a163a 100644 --- a/includes/flag.actions.inc +++ b/includes/flag.actions.inc @@ -179,13 +179,13 @@ function flag_user_action_submit($form, $form_state) { * * @param $context * The current action context. - * @param $content_type + * @param $entity_type * The content type applicable to this action, such as "node" or "comment". */ -function flag_action_form($context, $content_type) { +function flag_action_form($context, $entity_type) { $form = array(); - $flags = flag_get_flags($content_type); + $flags = flag_get_flags($entity_type); // If this is a flag_action action, do not allow the triggering flag. if (isset($context['actions_flag'])) { unset($flags[$context['actions_flag']]); @@ -214,7 +214,7 @@ function flag_action_form($context, $content_type) { ); if (empty($options)) { - $error = t('There are no available %type flags. Before you can create an action of this type, you need to create a %type flag.', array('%type' => $content_type, '!url' => url(FLAG_ADMIN_PATH . '/add'))); + $error = t('There are no available %type flags. Before you can create an action of this type, you need to create a %type flag.', array('%type' => $entity_type, '!url' => url(FLAG_ADMIN_PATH . '/add'))); $form['flag_action']['flag']['#type'] = 'item'; $form['flag_action']['flag']['#markup'] = $error; $form['flag_action']['flag']['#element_validate'][] = 'flag_action_validate_flag'; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 3b7ad47..26db8ee 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -19,7 +19,7 @@ class flag_flag { var $fid = NULL; // The content-type this flag works with. - var $content_type = NULL; + var $entity_type = NULL; // The flag's "machine readable" name. var $name = ''; @@ -89,8 +89,8 @@ class flag_flag { * Another factory method. Returns a new, "empty" flag; e.g., one suitable for * the "Add new flag" page. */ - static function factory_by_content_type($content_type) { - return flag_create_handler($content_type); + static function factory_by_content_type($entity_type) { + return flag_create_handler($entity_type); } /** diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index d7c3e5c..8b57a45 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -221,8 +221,8 @@ function flag_views_query_substitutions() { * This function is used to select the desired flag when setting up flag * relationships and fields. */ -function flag_views_flag_config_form($form_type, $content_type, $current_flag) { - $flags = flag_get_flags($content_type); +function flag_views_flag_config_form($form_type, $entity_type, $current_flag) { + $flags = flag_get_flags($entity_type); $options = array(); foreach ($flags as $flag) { @@ -243,13 +243,13 @@ function flag_views_flag_config_form($form_type, $content_type, $current_flag) { /** * Helper function that gets the first defined flag and returns its name. */ -function flag_views_flag_default($content_type) { +function flag_views_flag_default($entity_type) { static $default_flag = array(); - if (!array_key_exists($content_type, $default_flag)) { - $flag = array_shift(flag_get_flags($content_type)); - $default_flag[$content_type] = $flag ? $flag->name : NULL; + if (!array_key_exists($entity_type, $default_flag)) { + $flag = array_shift(flag_get_flags($entity_type)); + $default_flag[$entity_type] = $flag ? $flag->name : NULL; } - return $default_flag[$content_type]; + return $default_flag[$entity_type]; } diff --git a/includes/views/flag_handler_relationships.inc b/includes/views/flag_handler_relationships.inc index a2fa516..d409c4e 100644 --- a/includes/views/flag_handler_relationships.inc +++ b/includes/views/flag_handler_relationships.inc @@ -91,9 +91,9 @@ class flag_handler_relationship_content extends flag_handler_relationship { function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); - $content_type = $this->definition['flag type']; + $entity_type = $this->definition['flag type']; $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); - $form['flag'] = flag_views_flag_config_form('radios', $content_type, $this->options['flag']); + $form['flag'] = flag_views_flag_config_form('radios', $entity_type, $this->options['flag']); $form['user_scope'] = array( '#type' => 'radios', @@ -108,7 +108,7 @@ class flag_handler_relationship_content extends flag_handler_relationship { if (!$form['flag']['#options']) { $form = array( 'error' => array( - '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', array('%type' => $content_type, '@create-url' => url(FLAG_ADMIN_PATH))) . '

', + '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', array('%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH))) . '

', ), ); $form_state['no flags exist'] = TRUE; @@ -179,8 +179,8 @@ class flag_handler_relationship_counts extends flag_handler_relationship { function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); - $content_type = $this->definition['flag type']; - $form['flag'] = flag_views_flag_config_form('radios', $content_type, $this->options['flag']); + $entity_type = $this->definition['flag type']; + $form['flag'] = flag_views_flag_config_form('radios', $entity_type, $this->options['flag']); $form['required']['#title'] = t('Include only flagged content'); $form['required']['#description'] = t('If checked, only content that is flagged will be included.'); From 8bf2ed606cf0886301aa185268c58814b71b0d78 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 13:36:00 +0100 Subject: [PATCH 107/629] Changed database column 'content_type' to 'entity_type' on all tables. Replaced s/'content_type'/'entity_type'/, except in update functions. --- flag.inc | 2 +- flag.install | 14 ++++---- flag.module | 36 +++++++++---------- flag.rules.inc | 20 +++++------ flag.tokens.inc | 2 +- flag_actions.module | 4 +-- includes/flag.actions.inc | 4 +-- includes/flag.admin.inc | 4 +-- includes/flag.features.inc | 4 +-- includes/flag/flag_entity.inc | 20 +++++------ includes/flag/flag_flag.inc | 22 ++++++------ ..._plugin_argument_validate_flaggability.inc | 2 +- 12 files changed, 67 insertions(+), 67 deletions(-) diff --git a/flag.inc b/flag.inc index 167e294..762b486 100644 --- a/flag.inc +++ b/flag.inc @@ -102,7 +102,7 @@ function flag_create_handler($entity_type) { else { $handler = new flag_broken; } - $handler->content_type = $entity_type; + $handler->entity_type = $entity_type; $handler->construct(); return $handler; } diff --git a/flag.install b/flag.install index 6a3d4f2..c10a80e 100644 --- a/flag.install +++ b/flag.install @@ -102,7 +102,7 @@ function flag_schema() { 'unsigned' => TRUE, 'not null' => TRUE, ), - 'content_type' => array( + 'entity_type' => array( 'description' => 'The flag type, such as one of "node", "comment", or "user".', 'type' => 'varchar', 'length' => '128', @@ -159,7 +159,7 @@ function flag_schema() { 'not null' => TRUE, 'default' => 0, ), - 'content_type' => array( + 'entity_type' => array( 'description' => 'The flag type, one of "node", "comment", "user".', 'type' => 'varchar', 'length' => '128', @@ -201,8 +201,8 @@ function flag_schema() { 'fid_content_id_uid_sid' => array('fid', 'content_id', 'uid', 'sid'), ), 'indexes' => array( - 'content_type_uid_sid' => array('content_type', 'uid', 'sid'), - 'content_type_content_id_uid_sid' => array('content_type', 'content_id', 'uid', 'sid'), + 'entity_type_uid_sid' => array('entity_type', 'uid', 'sid'), + 'entity_type_content_id_uid_sid' => array('entity_type', 'content_id', 'uid', 'sid'), 'content_id_fid' => array('content_id', 'fid'), ), ); @@ -241,7 +241,7 @@ function flag_schema() { 'not null' => TRUE, 'default' => 0, ), - 'content_type' => array( + 'entity_type' => array( 'description' => 'The flag type, usually one of "node", "comment", "user".', 'type' => 'varchar', 'length' => '128', @@ -275,8 +275,8 @@ function flag_schema() { ), 'primary key' => array('fid', 'content_id'), 'indexes' => array( - 'fid_content_type' => array('fid', 'content_type'), - 'content_type_content_id' => array('content_type', 'content_id'), + 'fid_entity_type' => array('fid', 'entity_type'), + 'entity_type_content_id' => array('entity_type', 'content_id'), 'fid_count' => array('fid', 'count'), 'fid_last_updated' => array('fid', 'last_updated'), ), diff --git a/flag.module b/flag.module index 2ba23de..c2f7d48 100644 --- a/flag.module +++ b/flag.module @@ -422,7 +422,7 @@ function flag_field_extra_fields() { // In order to make sense with this hook's structure, we use D7 lingo, hence // some translation is required... - $entity_type = $flag->content_type; + $entity_type = $flag->entity_type; foreach ($flag->types as $bundle_name) { if ($flag->show_on_form) { $extra[$entity_type][$bundle_name]['form']['flag'] = array( @@ -825,10 +825,10 @@ function flag_node_translation_change($node) { */ function _flag_content_delete($entity_type, $entity_id, $fid = NULL) { $query_content = db_delete('flagging') - ->condition('content_type', $entity_type) + ->condition('entity_type', $entity_type) ->condition('content_id', $entity_id); $query_counts = db_delete('flag_counts') - ->condition('content_type', $entity_type) + ->condition('entity_type', $entity_type) ->condition('content_id', $entity_id); if (isset($fid)) { $query_content->condition('fid', $fid); @@ -906,7 +906,7 @@ function flag_user_delete($account) { function flag_user_account_removal($account) { // Remove flags by this user. $query = db_select('flagging', 'fc'); - $query->leftJoin('flag_counts', 'c', 'fc.content_id = c.content_id AND fc.content_type = c.content_type'); + $query->leftJoin('flag_counts', 'c', 'fc.content_id = c.content_id AND fc.entity_type = c.entity_type'); $result = $query ->fields('fc', array('fid', 'content_id')) ->fields('c', array('count')) @@ -1008,7 +1008,7 @@ function flag_session_api_cleanup($arg = 'run') { function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { // This query can't use db_delete() because that doesn't support a // subquery: see http://drupal.org/node/1267508. - db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flag} WHERE content_type = :entity_type)", array( + db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flag} WHERE entity_type = :entity_type)", array( ':bundle' => $bundle, ':entity_type' => $entity_type, )); @@ -1085,7 +1085,7 @@ function flag_build_javascript_info($flag, $content_id) { 'newLink' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id, TRUE), // Further information for the benefit of custom JavaScript event handlers: 'contentId' => $content_id, - 'contentType' => $flag->content_type, + 'contentType' => $flag->entity_type, 'flagName' => $flag->name, 'flagStatus' => $flag->is_flagged($content_id) ? 'flagged' : 'unflagged', ); @@ -1217,10 +1217,10 @@ function flag_flag($action, $flag, $content_id, $account) { if (module_exists('rules')) { $event_name = ($action == 'flag' ? 'flag_flagged_' : 'flag_unflagged_') . $flag->name; // We only support flags on entities. - if (entity_get_info($flag->content_type)) { + if (entity_get_info($flag->entity_type)) { $variables = array( 'flag' => $flag, - 'flagged_' . $flag->content_type => $content_id, + 'flagged_' . $flag->entity_type => $content_id, 'flagging_user' => $account, 'flagging' => $flag->get_flagging($content_id,$account->uid), ); @@ -1240,7 +1240,7 @@ function flag_flag_access($flag, $content_id, $action, $account) { // Restrict access by authorship. It's important that TRUE is never returned // here, otherwise we'd grant permission even if other modules denied access. - if ($flag->content_type == 'node') { + if ($flag->entity_type == 'node') { // For non-existent nodes (such as on the node add form), assume that the // current user is creating the content. if (empty($content_id) || !($node = node_load($content_id))) { @@ -1256,7 +1256,7 @@ function flag_flag_access($flag, $content_id, $action, $account) { } // Restrict access by comment authorship. - if ($flag->content_type == 'comment') { + if ($flag->entity_type == 'comment') { // For non-existent comments (such as on the comment add form), assume that // the current user is creating the content. if (empty($content_id) || !($comment = $flag->fetch_content($content_id))) { @@ -1290,7 +1290,7 @@ function flag_flag_access_multiple($flag, $content_ids, $account) { return $access; } - if ($flag->content_type == 'node') { + if ($flag->entity_type == 'node') { // Restrict access by authorship. This is similar to flag_flag_access() // above, but returns an array of 'nid' => $access values. Similarly, we // should never return TRUE in any of these access values, only FALSE if we @@ -1310,7 +1310,7 @@ function flag_flag_access_multiple($flag, $content_ids, $account) { } } - if ($flag->content_type == 'comment') { + if ($flag->entity_type == 'comment') { // Restrict access by comment ownership. $query = db_select('comment', 'c'); $query->leftJoin('node', 'n', 'c.nid = n.nid'); @@ -1689,7 +1689,7 @@ function flag_get_counts($entity_type, $content_id, $reset = FALSE) { $result = $query ->fields('f', array('name')) ->fields('fc', array('count')) - ->condition('fc.content_type', $entity_type) + ->condition('fc.entity_type', $entity_type) ->condition('fc.content_id', $content_id) ->execute(); foreach ($result as $row) { @@ -1781,7 +1781,7 @@ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = $query = db_select('flag', 'f'); $query->leftJoin('flag_types', 'fn', 'fn.fid = f.fid'); $result = $query - ->fields('f', array('fid', 'content_type', 'name', 'title', 'global', 'options')) + ->fields('f', array('fid', 'entity_type', 'name', 'title', 'global', 'options')) ->fields('fn', array('type')) ->execute(); foreach ($result as $row) { @@ -1874,7 +1874,7 @@ function _flag_compare_weight($flag1, $flag2) { * TRUE if the flag is enabled for this type and subtype. */ function _flag_content_enabled($flag, $entity_type, $content_subtype = NULL) { - $return = $flag->content_type == $entity_type && (!isset($content_subtype) || in_array($content_subtype, $flag->types)); + $return = $flag->entity_type == $entity_type && (!isset($content_subtype) || in_array($content_subtype, $flag->types)); return $return; } @@ -2002,7 +2002,7 @@ function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid $flagged_content[$uid][$sid][$entity_type][$content_id] = array(); $result = db_select('flagging', 'fc') ->fields('fc') - ->condition('content_type', $entity_type) + ->condition('entity_type', $entity_type) ->condition('content_id', $content_id) ->condition(db_or() ->condition('uid', $uid) @@ -2024,7 +2024,7 @@ function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid $flagged_content[$uid][$sid][$entity_type]['all'] = array(); $result = db_select('flagging', 'fc') ->fields('fc') - ->condition('content_type', $entity_type) + ->condition('entity_type', $entity_type) ->condition(db_or() ->condition('uid', $uid) ->condition('uid', 0) @@ -2063,7 +2063,7 @@ function flag_get_content_flags($entity_type, $content_id, $flag_name = NULL) { $flag_names = _flag_get_flag_names(); $result = db_select('flagging', 'fc') ->fields('fc') - ->condition('content_type', $entity_type) + ->condition('entity_type', $entity_type) ->condition('content_id', $content_id) ->orderBy('timestamp', 'DESC') ->execute(); diff --git a/flag.rules.inc b/flag.rules.inc index 4570162..815462a 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -104,10 +104,10 @@ function _flag_rules_flags_options($flag_type = NULL) { $flags = flag_get_flags(); $options = array(); foreach ($flags as $flag) { - if (!isset($flag_type) || $flag->content_type == $flag_type) { + if (!isset($flag_type) || $flag->entity_type == $flag_type) { $options[$flag->name] = array( 'title' => $flag->get_title(), - 'type' => $flag->content_type, + 'type' => $flag->entity_type, 'global' => $flag->global ? t('Yes') : t('No'), ); } @@ -124,15 +124,15 @@ function flag_rules_event_info() { $flags = flag_get_flags(); foreach ($flags as $flag) { // We only support flags on entities. - if ($info = entity_get_info($flag->content_type)) { + if ($info = entity_get_info($flag->entity_type)) { $variables = array( 'flag' => array( 'type' => 'flag', 'label' => t('flag'), - 'flag_type' => $flag->content_type, + 'flag_type' => $flag->entity_type, ), - 'flagged_' . $flag->content_type => array( - 'type' => $flag->content_type, + 'flagged_' . $flag->entity_type => array( + 'type' => $flag->entity_type, 'label' => $info['label'], ), 'flagging_user' => array( @@ -148,13 +148,13 @@ function flag_rules_event_info() { // For each flag we define two events. $items['flag_flagged_' . $flag->name] = array( 'group' => t('Flag'), - 'label' => t('A @flag-type has been flagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->content_type))), + 'label' => t('A @flag-type has been flagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->entity_type))), 'variables' => $variables, 'access callback' => 'flag_rules_integration_access', ); $items['flag_unflagged_' . $flag->name] = array( 'group' => t('Flag'), - 'label' => t('A @flag-type has been unflagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->content_type))), + 'label' => t('A @flag-type has been unflagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->entity_type))), 'variables' => $variables, 'access callback' => 'flag_rules_integration_access', ); @@ -323,7 +323,7 @@ function flag_rules_action_trim($flag, $flagging_user, $cutoff_size) { function flag_rules_action_fetch_users($flag, $entity) { $result = db_select('flagging', 'fc') ->fields('fc', array('uid')) - ->condition('content_type', $flag->content_type) + ->condition('entity_type', $flag->entity_type) ->condition('content_id', $flag->get_content_id($entity)) ->condition('fid', $flag->fid) ->execute(); @@ -338,7 +338,7 @@ function flag_rules_action_fetch_users($flag, $entity) { function flag_rules_action_fetch_entity_by_user($flag, $user) { $result = db_select('flagging', 'fc') ->fields('fc', array('content_id')) - ->condition('content_type', $flag->content_type) + ->condition('entity_type', $flag->entity_type) ->condition('uid', $user->uid) ->condition('fid', $flag->fid) ->execute(); diff --git a/flag.tokens.inc b/flag.tokens.inc index 64f15e9..4fd4e99 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -143,7 +143,7 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr $replacements[$original] = $sanitize ? check_plain($action->content_title) : $action->content_title; break; case 'content-type': - $replacements[$original] = $action->content_type; + $replacements[$original] = $action->entity_type; break; case 'content-id': $replacements[$original] = $action->content_id; diff --git a/flag_actions.module b/flag_actions.module index 6504229..65baa08 100644 --- a/flag_actions.module +++ b/flag_actions.module @@ -241,7 +241,7 @@ function flag_actions_do($event, $flag, $content_id, $account) { $callback($relevant_objects['node'], $context); } else { - $callback($relevant_objects[$flag->content_type], $context); + $callback($relevant_objects[$flag->entity_type], $context); } } @@ -659,7 +659,7 @@ function flag_actions_system_send_email_action_form(&$form, &$flag, $context) { } if (!isset($context['message'])) { - $form['message']['#default_value'] = t("The @flag_content_type [flag-action:content-title] has been flagged [flag-action:count] times with the @flag_title flag.\n\nView this @flag_content_type at [flag-action:content-url].", array('@flag_content_type' => $flag->content_type, '@flag_title' => $flag->get_title())); + $form['message']['#default_value'] = t("The @flag_entity_type [flag-action:content-title] has been flagged [flag-action:count] times with the @flag_title flag.\n\nView this @flag_entity_type at [flag-action:content-url].", array('@flag_entity_type' => $flag->entity_type, '@flag_title' => $flag->get_title())); } $form['help'] = array( diff --git a/includes/flag.actions.inc b/includes/flag.actions.inc index d7a163a..5b6bdf0 100644 --- a/includes/flag.actions.inc +++ b/includes/flag.actions.inc @@ -21,8 +21,8 @@ function flag_trigger_info() { ); foreach (flag_get_flags() as $flag) { - $hooks['flag']['flag_flag_' . $flag->name]['label'] = t('A %type has been flagged with %name', array('%type' => $flag->content_type, '%name' => $flag->name)); - $hooks['flag']['flag_unflag_' . $flag->name]['label'] = t('A %type has been unflagged with %name', array('%type' => $flag->content_type, '%name' => $flag->name)); + $hooks['flag']['flag_flag_' . $flag->name]['label'] = t('A %type has been flagged with %name', array('%type' => $flag->entity_type, '%name' => $flag->name)); + $hooks['flag']['flag_unflag_' . $flag->name]['label'] = t('A %type has been unflagged with %name', array('%type' => $flag->entity_type, '%name' => $flag->name)); } return $hooks; diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 0aa6066..d1b3b25 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -78,7 +78,7 @@ function theme_flag_admin_listing($variables) { $row = array( $flag->name, drupal_render($form['flags'][$flag->name]['weight']), - $flag->content_type, + $flag->entity_type, empty($flag->roles['flag']) ? '' . t('No roles') . '' : implode(', ', $roles), $flag->types ? implode(', ', $flag->types) : '-', $flag->global ? t('Yes') : t('No'), @@ -130,7 +130,7 @@ function theme_flag_admin_listing_disabled($variables) { $rows[] = array( $flag->name, $flag->module, - $flag->content_type, + $flag->entity_type, theme('links', array('links' => $ops)), ); } diff --git a/includes/flag.features.inc b/includes/flag.features.inc index 859f56f..fed0b13 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -19,7 +19,7 @@ function flag_features_export($data, &$export, $module_name = '') { foreach ($data as $key => $flag) { // Get the module that provided the flag definition. if ($flag = flag_load($flag, TRUE)) { - $module = $modules[$flag->content_type]; + $module = $modules[$flag->entity_type]; $export['dependencies'][$module] = $module; $export['features']['flag'][$flag->name] = $flag->name; } @@ -36,7 +36,7 @@ function flag_features_export_options() { // Get all flags, including disabled defaults. $flags = flag_get_flags() + flag_get_default_flags(TRUE); foreach ($flags as $name => $flag) { - $options[$name] = drupal_ucfirst(check_plain($flag->content_type)) . ': ' . check_plain($flag->title); + $options[$name] = drupal_ucfirst(check_plain($flag->entity_type)) . ': ' . check_plain($flag->title); } return $options; } diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 9002142..db49790 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -31,7 +31,7 @@ class flag_entity extends flag_flag { */ function options_form(&$form) { $bundles = array(); - $entity_info = entity_get_info($this->content_type); + $entity_info = entity_get_info($this->entity_type); foreach ($entity_info['bundles'] as $bundle_key => $bundle) { $bundles[$bundle_key] = check_plain($bundle['label']); } @@ -64,7 +64,7 @@ class flag_entity extends flag_flag { */ function _load_content($content_id) { if (is_numeric($content_id)) { - $entity = entity_load($this->content_type, array($content_id)); + $entity = entity_load($this->entity_type, array($content_id)); return reset($entity); } return NULL; @@ -74,7 +74,7 @@ class flag_entity extends flag_flag { * Checks whether the flag applies for the current entity bundle. */ function applies_to_content_object($entity) { - $entity_info = entity_get_info($this->content_type); + $entity_info = entity_get_info($this->entity_type); if (empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { return TRUE; } @@ -85,7 +85,7 @@ class flag_entity extends flag_flag { * Returns the entity id, if it already exists. */ function get_content_id($entity) { - $entity_info = entity_get_info($this->content_type); + $entity_info = entity_get_info($this->entity_type); if ($entity && isset($entity->{$entity_info['entity keys']['id']})) { return $entity->{$entity_info['entity keys']['id']}; } @@ -107,7 +107,7 @@ class flag_entity extends flag_flag { function get_labels_token_types() { // The token type name might be different to the entity type name. If so, // an own flag entity handler can be used for overriding this. - return array_merge(array($this->content_type), parent::get_labels_token_types()); + return array_merge(array($this->entity_type), parent::get_labels_token_types()); } /** @@ -115,7 +115,7 @@ class flag_entity extends flag_flag { */ function replace_tokens($label, $contexts, $options, $content_id) { if ($content_id && ($entity = $this->fetch_content($content_id))) { - $contexts[$this->content_type] = $entity; + $contexts[$this->entity_type] = $entity; } return parent::replace_tokens($label, $contexts, $options, $content_id); } @@ -126,8 +126,8 @@ class flag_entity extends flag_flag { function get_flag_action($content_id) { $flag_action = parent::get_flag_action($content_id); $entity = $this->fetch_content($content_id); - $flag_action->content_title = entity_label($this->content_type, $entity); - $flag_action->content_url = _flag_url($this->content_type . '/' . $this->get_content_id($entity)); + $flag_action->content_title = entity_label($this->entity_type, $entity); + $flag_action->content_url = _flag_url($this->entity_type . '/' . $this->get_content_id($entity)); return $flag_action; } @@ -136,7 +136,7 @@ class flag_entity extends flag_flag { */ function get_relevant_action_objects($content_id) { return array( - $this->content_type => $this->fetch_content($content_id), + $this->entity_type => $this->fetch_content($content_id), ); } @@ -144,7 +144,7 @@ class flag_entity extends flag_flag { * Returns information for the Views integration. */ function get_views_info() { - $entity_info = entity_get_info($this->content_type); + $entity_info = entity_get_info($this->entity_type); return array( 'views table' => $entity_info['base table'], 'join field' => $entity_info['entity keys']['id'], diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 26db8ee..5379ac2 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -37,12 +37,12 @@ class flag_flag { * This is static method. * * The reason this isn't a non-static instance method --like Views's init()-- - * is because the class to instantiate changes according to the 'content_type' + * is because the class to instantiate changes according to the 'entity_type' * database column. This design pattern is known as the "Single Table * Inheritance". */ static function factory_by_row($row) { - $flag = flag_create_handler($row->content_type); + $flag = flag_create_handler($row->entity_type); // Lump all data unto the object... foreach ($row as $field => $value) { @@ -72,7 +72,7 @@ class flag_flag { * Create a complete flag (except an FID) from an array definition. */ static function factory_by_array($config) { - $flag = flag_create_handler($config['content_type']); + $flag = flag_create_handler($config['entity_type']); foreach ($config as $option => $value) { $flag->$option = $value; @@ -703,7 +703,7 @@ class flag_flag { $sid = $this->global ? 0 : (!isset($sid) ? flag_get_sid($uid) : $sid); // flag_get_user_flags() does caching. - $user_flags = flag_get_user_flags($this->content_type, $content_id, $uid, $sid); + $user_flags = flag_get_user_flags($this->entity_type, $content_id, $uid, $sid); return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL; } @@ -758,7 +758,7 @@ class flag_flag { $fcid = db_insert('flagging') ->fields(array( 'fid' => $this->fid, - 'content_type' => $this->content_type, + 'entity_type' => $this->entity_type, 'content_id' => $content_id, 'uid' => $uid, 'sid' => $sid, @@ -814,7 +814,7 @@ class flag_flag { 'content_id' => $content_id, )) ->fields(array( - 'content_type' => $this->content_type, + 'entity_type' => $this->entity_type, 'count' => $number, 'last_updated' => REQUEST_TIME, )) @@ -882,7 +882,7 @@ class flag_flag { * item results in only one SQL query. */ function get_count($content_id) { - $counts = flag_get_counts($this->content_type, $content_id); + $counts = flag_get_counts($this->entity_type, $content_id); return isset($counts[$this->name]) ? $counts[$this->name] : 0; } @@ -987,7 +987,7 @@ class flag_flag { function get_flag_action($content_id) { $flag_action = new stdClass(); $flag_action->flag = $this->name; - $flag_action->content_type = $this->content_type; + $flag_action->entity_type = $this->entity_type; $flag_action->content_id = $content_id; return $flag_action; } @@ -1004,7 +1004,7 @@ class flag_flag { function get_valid_actions() { $actions = module_invoke_all('action_info'); foreach ($actions as $callback => $action) { - if ($action['type'] != $this->content_type && !in_array('any', $action['triggers'])) { + if ($action['type'] != $this->entity_type && !in_array('any', $action['triggers'])) { unset($actions[$callback]); } } @@ -1095,7 +1095,7 @@ class flag_flag { function insert() { $this->fid = db_insert('flag') ->fields(array( - 'content_type' => $this->content_type, + 'entity_type' => $this->entity_type, 'name' => $this->name, 'title' => $this->title, 'global' => $this->global, @@ -1293,7 +1293,7 @@ class flag_broken extends flag_flag { function options_form(&$form) { $form = array(); $form['error'] = array( - '#markup' => '
' . t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->content_type)) . '
', + '#markup' => '
' . t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->entity_type)) . '
', ); } } diff --git a/includes/views/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc index 3863bed..a361458 100644 --- a/includes/views/flag_plugin_argument_validate_flaggability.inc +++ b/includes/views/flag_plugin_argument_validate_flaggability.inc @@ -145,7 +145,7 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v // Note: we can't do $handler->field, because the relationship handler's init() may overwrite it. if (strpos($handler->options['field'], 'flag') !== FALSE && !empty($handler->options['flag'])) { $flag = flag_get_flag($handler->options['flag']); - if ($flag && $flag->content_type == $this->flag_type) { + if ($flag && $flag->entity_type == $this->flag_type) { return $flag; } } From bb2d7db5551365b73781936463ab107e87153410 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 13:36:29 +0100 Subject: [PATCH 108/629] Changed method factory_by_content_type() to factory_by_entity_type(). --- flag_bookmark/flag_bookmark.install | 2 +- includes/flag.admin.inc | 4 ++-- includes/flag/flag_flag.inc | 2 +- includes/views/flag.views.inc | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flag_bookmark/flag_bookmark.install b/flag_bookmark/flag_bookmark.install index 38c9f47..aec3f78 100644 --- a/flag_bookmark/flag_bookmark.install +++ b/flag_bookmark/flag_bookmark.install @@ -26,7 +26,7 @@ function flag_bookmark_enable() { // Install a demonstration flag only if no flag exists. This is to prevent // a case where a disables and enables the module, and the demonstration // flag is overwritten or re-created. - $flag = flag_flag::factory_by_content_type('node'); + $flag = flag_flag::factory_by_entity_type('node'); $configuration = array( 'name' => 'bookmarks', 'global' => 0, diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index d1b3b25..0ae0101 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -198,7 +198,7 @@ function theme_flag_admin_page($variables) { function flag_add_page($type = NULL, $name = NULL) { drupal_set_title(t('Add new flag')); if (isset($type) && isset($name)) { - $flag = flag_flag::factory_by_content_type($type); + $flag = flag_flag::factory_by_entity_type($type); $flag->name = $name; return drupal_get_form('flag_form', $flag); } @@ -246,7 +246,7 @@ function flag_add_form($form, &$form_state) { } function flag_add_form_validate($form, &$form_state) { - $flag = flag_flag::factory_by_content_type($form_state['values']['type']); + $flag = flag_flag::factory_by_entity_type($form_state['values']['type']); $flag->name = $form_state['values']['name']; $errors = $flag->validate_name(); foreach ($errors as $field => $field_errors) { diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 5379ac2..adcf3df 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -89,7 +89,7 @@ class flag_flag { * Another factory method. Returns a new, "empty" flag; e.g., one suitable for * the "Add new flag" page. */ - static function factory_by_content_type($entity_type) { + static function factory_by_entity_type($entity_type) { return flag_create_handler($entity_type); } diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index 8b57a45..840c3cb 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -154,7 +154,7 @@ function flag_views_data() { function flag_views_data_alter(&$data) { foreach (array_keys(flag_fetch_definition()) as $flag_type) { - $flag = flag_flag::factory_by_content_type($flag_type); + $flag = flag_flag::factory_by_entity_type($flag_type); $info = $flag->get_views_info(); if (!empty($info['join field'])) { From 809e65b44374f4e60dfab318043469b3ce72ed91 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 13:37:07 +0100 Subject: [PATCH 109/629] Changed 'contentType' in JavaScript into to 'entityType'. (Nothing seems to make use of this.) --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index c2f7d48..d427e10 100644 --- a/flag.module +++ b/flag.module @@ -1085,7 +1085,7 @@ function flag_build_javascript_info($flag, $content_id) { 'newLink' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id, TRUE), // Further information for the benefit of custom JavaScript event handlers: 'contentId' => $content_id, - 'contentType' => $flag->entity_type, + 'entityType' => $flag->entity_type, 'flagName' => $flag->name, 'flagStatus' => $flag->is_flagged($content_id) ? 'flagged' : 'unflagged', ); From 21e7091df4c1d44e5dc41d93f5bbc4c5995bfea7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 20:21:17 +0100 Subject: [PATCH 110/629] Changed all $content_id variables to $entity_id. Replace s/\$content_id\b/$entity_id/ throughout. --- flag.api.php | 12 +- flag.module | 178 +++++++++++----------- flag_actions.module | 12 +- includes/flag.cookie_storage.inc | 38 ++--- includes/flag/flag_comment.inc | 18 +-- includes/flag/flag_entity.inc | 22 +-- includes/flag/flag_flag.inc | 170 ++++++++++----------- includes/flag/flag_node.inc | 34 ++--- includes/flag/flag_user.inc | 14 +- includes/views/flag_handler_field_ops.inc | 12 +- 10 files changed, 255 insertions(+), 255 deletions(-) diff --git a/flag.api.php b/flag.api.php index 1bf4e20..d31d7a0 100644 --- a/flag.api.php +++ b/flag.api.php @@ -88,14 +88,14 @@ function hook_flag_options_alter(&$options, $flag) { * The operation being performed: one of 'flag' or 'unflag'. * @param $flag * The flag object. - * @param $content_id + * @param $entity_id * The id of the content (aka entity) the flag is on. * @param $account * The user account performing the action. * @param $fcid * The id of the flagging in the {flagging} table. */ -function hook_flag($op, $flag, $content_id, $account, $fcid) { +function hook_flag($op, $flag, $entity_id, $account, $fcid) { } @@ -104,7 +104,7 @@ function hook_flag($op, $flag, $content_id, $account, $fcid) { * * @param $flag * The flag object. - * @param $content_id + * @param $entity_id * The id of the entity in question. * @param $action * The action to test. Either 'flag' or 'unflag'. @@ -117,7 +117,7 @@ function hook_flag($op, $flag, $content_id, $account, $fcid) { * * @see flag_flag:access() */ -function hook_flag_access($flag, $content_id, $action, $account) { +function hook_flag_access($flag, $entity_id, $action, $account) { } @@ -193,7 +193,7 @@ function hook_flag_link_types_alter(&$link_types) { * The full flag object for the flag link being generated. * @param $action * The action this link should perform. Either 'flag' or 'unflag'. - * @param $content_id + * @param $entity_id * The ID of the node, comment, user, or other object being flagged. The type * of the object can be deduced from the flag type. * @@ -226,7 +226,7 @@ function hook_flag_reset() { * * @param $flag * The full flag object. - * @param $content_id + * @param $entity_id * The ID of the node, comment, user or other object being flagged. * * @see flag_build_javascript_info() diff --git a/flag.module b/flag.module index d427e10..9032743 100644 --- a/flag.module +++ b/flag.module @@ -340,13 +340,13 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { $flags = flag_get_flags($type); foreach ($flags as $flag) { - $content_id = $flag->get_content_id($object); + $entity_id = $flag->get_content_id($object); if (!$flag->uses_hook_link($teaser)) { // Flag is not configured to show its link here. continue; } - if (!$flag->access($content_id) && (!$flag->is_flagged($content_id) || !$flag->access($content_id, 'flag'))) { + if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this // content. The link is not skipped if the user has "flag" access but // not "unflag" access (this way the unflag denied message is shown). @@ -356,7 +356,7 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { // The flag links are actually fully rendered theme functions. // The HTML attribute is set to TRUE to allow whatever the themer desires. $links['flag-' . $flag->name] = array( - 'title' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id), + 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), 'html' => TRUE, ); } @@ -369,10 +369,10 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { /** * Implements hook_flag_link(). */ -function flag_flag_link($flag, $action, $content_id) { - $token = flag_get_token($content_id); +function flag_flag_link($flag, $action, $entity_id) { + $token = flag_get_token($entity_id); return array( - 'href' => 'flag/' . ($flag->link_type == 'confirm' ? 'confirm/' : '') . "$action/$flag->name/$content_id", + 'href' => 'flag/' . ($flag->link_type == 'confirm' ? 'confirm/' : '') . "$action/$flag->name/$entity_id", 'query' => drupal_get_destination() + ($flag->link_type == 'confirm' ? array() : array('token' => $token)), ); } @@ -688,8 +688,8 @@ function flag_contextual_links_view_alter(&$element, $items) { continue; } - $content_id = $flag->get_content_id($node); - if (!$flag->access($content_id) && (!$flag->is_flagged($content_id) || !$flag->access($content_id, 'flag'))) { + $entity_id = $flag->get_content_id($node); + if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this // content. The link is not skipped if the user has "flag" access but // not "unflag" access (this way the unflag denied message is shown). @@ -697,7 +697,7 @@ function flag_contextual_links_view_alter(&$element, $items) { } $element['#links']['flag-'. $name] = array( - 'title' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id), + 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), 'html' => TRUE, ); } @@ -797,14 +797,14 @@ function flag_node_translation_change($node) { if (isset($node->translation_change)) { // If there is only one node remaining, track by nid rather than tnid. // Otherwise, use the new tnid. - $content_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid']; + $entity_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid']; foreach (flag_get_flags('node') as $flag) { if ($flag->i18n) { - db_update('flagging')->fields(array('content_id' => $content_id)) + db_update('flagging')->fields(array('content_id' => $entity_id)) ->condition('fid', $flag->fid) ->condition('content_id', $node->translation_change['old_tnid']) ->execute(); - db_update('flag_counts')->fields(array('content_id' => $content_id)) + db_update('flag_counts')->fields(array('content_id' => $entity_id)) ->condition('fid', $flag->fid) ->condition('content_id', $node->translation_change['old_tnid']) ->execute(); @@ -1022,7 +1022,7 @@ function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { * @param $action * Either 'flag' or 'unflag'. */ -function flag_page($action, $flag, $content_id) { +function flag_page($action, $flag, $entity_id) { global $user; // Shorten up the variables that affect the behavior of this page. @@ -1033,14 +1033,14 @@ function flag_page($action, $flag, $content_id) { $has_js = isset($_GET['has_js']); // Check the flag token, then perform the flagging. - if (!flag_check_token($token, $content_id)) { + if (!flag_check_token($token, $entity_id)) { $error = t('Bad token. You seem to have followed an invalid link.'); } elseif ($user->uid == 0 && !$has_js) { $error = t('You must have JavaScript and cookies enabled in your browser to flag content.'); } else { - $result = $flag->flag($action, $content_id); + $result = $flag->flag($action, $entity_id); if (!$result) { $error = t('You are not allowed to flag, or unflag, this content.'); } @@ -1067,11 +1067,11 @@ function flag_page($action, $flag, $content_id) { if ($js) { drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); $flag->link_type = 'toggle'; - print drupal_json_encode(flag_build_javascript_info($flag, $content_id)); + print drupal_json_encode(flag_build_javascript_info($flag, $entity_id)); drupal_exit(); } else { - drupal_set_message($flag->get_label($action . '_message', $content_id)); + drupal_set_message($flag->get_label($action . '_message', $entity_id)); drupal_goto(); } } @@ -1079,15 +1079,15 @@ function flag_page($action, $flag, $content_id) { /** * Builds the JavaScript structure describing the flagging operation. */ -function flag_build_javascript_info($flag, $content_id) { +function flag_build_javascript_info($flag, $entity_id) { $info = array( 'status' => TRUE, - 'newLink' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id, TRUE), + 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, TRUE), // Further information for the benefit of custom JavaScript event handlers: - 'contentId' => $content_id, + 'contentId' => $entity_id, 'entityType' => $flag->entity_type, 'flagName' => $flag->name, - 'flagStatus' => $flag->is_flagged($content_id) ? 'flagged' : 'unflagged', + 'flagStatus' => $flag->is_flagged($entity_id) ? 'flagged' : 'unflagged', ); drupal_alter('flag_javascript_info', $info); return $info; @@ -1100,12 +1100,12 @@ function flag_build_javascript_info($flag, $content_id) { * Either 'flag' or 'unflag'. * @param $flag * A loaded flag object. - * @param $content_id + * @param $entity_id * The id of the content to operate on. The type is implicit in the flag. * * @see flag_confirm_submit() */ -function flag_confirm($form, &$form_state, $action, $flag, $content_id) { +function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { $form['action'] = array( '#type' => 'value', '#value' => $action, @@ -1116,17 +1116,17 @@ function flag_confirm($form, &$form_state, $action, $flag, $content_id) { ); $form['content_id'] = array( '#type' => 'value', - '#value' => $content_id, + '#value' => $entity_id, ); - $question = $flag->get_label($action . '_confirmation', $content_id); + $question = $flag->get_label($action . '_confirmation', $entity_id); $path = isset($_GET['destination']) ? $_GET['destination'] : ''; - $yes = $flag->get_label($action . '_short', $content_id); + $yes = $flag->get_label($action . '_short', $entity_id); if ($action == 'flag') { // If the action 'flag', we're potentially about to create a new // flagging entity. We need an empty new entity to pass to FieldAPI. - $flagging = $flag->new_flagging($content_id); + $flagging = $flag->new_flagging($entity_id); field_attach_form('flagging', $flagging, $form, $form_state); $form['#flagging'] = $flagging; } @@ -1145,7 +1145,7 @@ function flag_confirm($form, &$form_state, $action, $flag, $content_id) { function flag_confirm_submit(&$form, &$form_state) { $action = $form_state['values']['action']; $flag_name = $form_state['values']['flag_name']; - $content_id = $form_state['values']['content_id']; + $entity_id = $form_state['values']['content_id']; $flag = flag_get_flag($flag_name); @@ -1154,17 +1154,17 @@ function flag_confirm_submit(&$form, &$form_state) { $flagging = $form['#flagging']; entity_form_submit_build_entity('flagging', $flagging, $form, $form_state); - $result = $flag->flag($action, $content_id, NULL, FALSE, $flagging); + $result = $flag->flag($action, $entity_id, NULL, FALSE, $flagging); } else { - $result = $flag->flag($action, $content_id, NULL, FALSE); + $result = $flag->flag($action, $entity_id, NULL, FALSE); } if (!$result) { drupal_set_message(t('You are not allowed to flag, or unflag, this content.')); } else { - drupal_set_message($flag->get_label($action . '_message', $content_id)); + drupal_set_message($flag->get_label($action . '_message', $entity_id)); } } @@ -1177,27 +1177,27 @@ function flag_confirm_submit(&$form, &$form_state) { * FALSE if some error occured (e.g., user has no permission, flag isn't * applicable to the item, etc.), TRUE otherwise. */ -function flag($action, $flag_name, $content_id, $account = NULL) { +function flag($action, $flag_name, $entity_id, $account = NULL) { if (!($flag = flag_get_flag($flag_name))) { // Flag does not exist. return FALSE; } - return $flag->flag($action, $content_id, $account); + return $flag->flag($action, $entity_id, $account); } /** * Implements hook_flag(). Trigger actions if any are available. */ -function flag_flag($action, $flag, $content_id, $account) { +function flag_flag($action, $flag, $entity_id, $account) { if (module_exists('trigger')) { $context['hook'] = 'flag'; $context['account'] = $account; $context['flag'] = $flag; $context['op'] = $action; // We add to the $context all the objects we know about: - $context = array_merge($flag->get_relevant_action_objects($content_id), $context); + $context = array_merge($flag->get_relevant_action_objects($entity_id), $context); // The primary object the actions work on. - $object = $flag->fetch_content($content_id); + $object = $flag->fetch_content($entity_id); // Generic "all flags" actions. foreach (trigger_get_assigned_actions('flag_' . $action) as $aid => $action_info) { @@ -1220,9 +1220,9 @@ function flag_flag($action, $flag, $content_id, $account) { if (entity_get_info($flag->entity_type)) { $variables = array( 'flag' => $flag, - 'flagged_' . $flag->entity_type => $content_id, + 'flagged_' . $flag->entity_type => $entity_id, 'flagging_user' => $account, - 'flagging' => $flag->get_flagging($content_id,$account->uid), + 'flagging' => $flag->get_flagging($entity_id,$account->uid), ); rules_invoke_event_by_args($event_name, $variables); } @@ -1232,7 +1232,7 @@ function flag_flag($action, $flag, $content_id, $account) { /** * Implements hook_flag_access(). */ -function flag_flag_access($flag, $content_id, $action, $account) { +function flag_flag_access($flag, $entity_id, $action, $account) { // Do nothing if there is no restriction by authorship. if (empty($flag->access_author)) { return; @@ -1243,7 +1243,7 @@ function flag_flag_access($flag, $content_id, $action, $account) { if ($flag->entity_type == 'node') { // For non-existent nodes (such as on the node add form), assume that the // current user is creating the content. - if (empty($content_id) || !($node = node_load($content_id))) { + if (empty($entity_id) || !($node = node_load($entity_id))) { return $flag->access_author == 'others' ? FALSE : NULL; } @@ -1259,7 +1259,7 @@ function flag_flag_access($flag, $content_id, $action, $account) { if ($flag->entity_type == 'comment') { // For non-existent comments (such as on the comment add form), assume that // the current user is creating the content. - if (empty($content_id) || !($comment = $flag->fetch_content($content_id))) { + if (empty($entity_id) || !($comment = $flag->fetch_content($entity_id))) { return $flag->access_author == 'comment_others' ? FALSE : NULL; } @@ -1370,17 +1370,17 @@ function flag_trim_flag($flag, $account, $cutoff_size) { * * @param $flag * The flag object. - * @param $content_id + * @param $entity_id * Optional. The content ID on which all flaggings will be removed. If left * empty, this will remove all of this flag's content. */ -function flag_reset_flag($flag, $content_id = NULL) { +function flag_reset_flag($flag, $entity_id = NULL) { $query = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid); - if ($content_id) { - $query->condition('content_id', $content_id); + if ($entity_id) { + $query->condition('content_id', $entity_id); } $result = $query->execute()->fetchAllAssoc('fcid', PDO::FETCH_ASSOC); @@ -1388,14 +1388,14 @@ function flag_reset_flag($flag, $content_id = NULL) { foreach ($result as $row) { $rows[] = $row; } - module_invoke_all('flag_reset', $flag, $content_id, $rows); + module_invoke_all('flag_reset', $flag, $entity_id, $rows); $query = db_delete('flagging')->condition('fid' , $flag->fid); // Update the flag_counts table. $count_query = db_delete('flag_counts')->condition('fid', $flag->fid); - if ($content_id) { - $query->condition('content_id', $content_id); - $count_query->condition('content_id', $content_id); + if ($entity_id) { + $query->condition('content_id', $entity_id); + $count_query->condition('content_id', $entity_id); } $count_query->execute(); return $query->execute(); @@ -1529,7 +1529,7 @@ function flag_theme() { * The $variables array initially contains the following arguments: * - $flag * - $action - * - $content_id + * - $entity_id * - $after_flagging * * See 'flag.tpl.php' for their documentation. @@ -1541,19 +1541,19 @@ function template_preprocess_flag(&$variables) { // Some typing shotcuts: $flag =& $variables['flag']; $action = $variables['action']; - $content_id = $variables['content_id']; + $entity_id = $variables['content_id']; $flag_css_name = str_replace('_', '-', $flag->name); // Generate the link URL. $link_type = $flag->get_link_type(); - $link = module_invoke($link_type['module'], 'flag_link', $flag, $action, $content_id); + $link = module_invoke($link_type['module'], 'flag_link', $flag, $action, $entity_id); if (isset($link['title']) && empty($link['html'])) { $link['title'] = check_plain($link['title']); } // Replace the link with the access denied text if unable to flag. - if ($action == 'unflag' && !$flag->access($content_id, 'unflag')) { - $link['title'] = $flag->get_label('unflag_denied_text', $content_id); + if ($action == 'unflag' && !$flag->access($entity_id, 'unflag')) { + $link['title'] = $flag->get_label('unflag_denied_text', $entity_id); unset($link['href']); } @@ -1575,15 +1575,15 @@ function template_preprocess_flag(&$variables) { $variables['link'] = $link; $variables['link_href'] = isset($link['href']) ? check_url(url($link['href'], $link)) : FALSE; - $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $content_id); - $variables['link_title'] = isset($link['attributes']['title']) ? check_plain($link['attributes']['title']) : check_plain(strip_tags($flag->get_label($action . '_long', $content_id))); + $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $entity_id); + $variables['link_title'] = isset($link['attributes']['title']) ? check_plain($link['attributes']['title']) : check_plain(strip_tags($flag->get_label($action . '_long', $entity_id))); $variables['status'] = ($action == 'flag' ? 'unflagged' : 'flagged'); $variables['flag_name_css'] = $flag_css_name; $variables['flag_wrapper_classes_array'] = array(); $variables['flag_wrapper_classes_array'][] = 'flag-wrapper'; $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name; - $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name . '-' . $content_id; + $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name . '-' . $entity_id; $variables['flag_wrapper_classes'] = implode(' ', $variables['flag_wrapper_classes_array']); $variables['flag_classes_array'] = array(); @@ -1596,7 +1596,7 @@ function template_preprocess_flag(&$variables) { } if ($variables['after_flagging']) { $inverse_action = ($action == 'flag' ? 'unflag' : 'flag'); - $variables['message_text'] = $flag->get_label($inverse_action . '_message', $content_id); + $variables['message_text'] = $flag->get_label($inverse_action . '_message', $entity_id); $variables['flag_classes_array'][] = $variables['status']; } $variables['flag_classes'] = implode(' ', $variables['flag_classes_array']); @@ -1664,7 +1664,7 @@ function _flag_link_type_fields() { * * @param $entity_type * The content type (usually 'node'). - * @param $content_id + * @param $entity_id * The content ID (usually the node ID). * @param $reset * Reset the internal cache and execute the SQL query another time. @@ -1672,7 +1672,7 @@ function _flag_link_type_fields() { * @return $flags * An array of the structure [name] => [number of flags]. */ -function flag_get_counts($entity_type, $content_id, $reset = FALSE) { +function flag_get_counts($entity_type, $entity_id, $reset = FALSE) { static $counts; if ($reset) { @@ -1682,22 +1682,22 @@ function flag_get_counts($entity_type, $content_id, $reset = FALSE) { } } - if (!isset($counts[$entity_type][$content_id])) { - $counts[$entity_type][$content_id] = array(); + if (!isset($counts[$entity_type][$entity_id])) { + $counts[$entity_type][$entity_id] = array(); $query = db_select('flag', 'f'); $query->leftJoin('flag_counts', 'fc', 'f.fid = fc.fid'); $result = $query ->fields('f', array('name')) ->fields('fc', array('count')) ->condition('fc.entity_type', $entity_type) - ->condition('fc.content_id', $content_id) + ->condition('fc.content_id', $entity_id) ->execute(); foreach ($result as $row) { - $counts[$entity_type][$content_id][$row->name] = $row->count; + $counts[$entity_type][$entity_id][$row->name] = $row->count; } } - return $counts[$entity_type][$content_id]; + return $counts[$entity_type][$entity_id]; } /** @@ -1961,7 +1961,7 @@ function flag_get_content_id($fcid) { * * @param $entity_type * The type of content that will be retrieved. Usually 'node'. - * @param $content_id + * @param $entity_id * Optional. The content ID to check for flagging. If none given, all * content flagged by this user will be returned. * @param $uid @@ -1975,7 +1975,7 @@ function flag_get_content_id($fcid) { * Reset the internal cache and execute the SQL query another time. * * @return $flags - * If returning a single item's flags (that is, when $content_id isn't NULL), + * If returning a single item's flags (that is, when $entity_id isn't NULL), * an array of the structure * [flag_name] => (fcid => [fcid], uid => [uid], content_id => [content_id], timestamp => [timestamp], ...) * @@ -1983,7 +1983,7 @@ function flag_get_content_id($fcid) { * [flag_name] => [content_id] => Object from above. * */ -function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) { +function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) { static $flagged_content; if ($reset) { @@ -1996,14 +1996,14 @@ function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid; $sid = !isset($sid) ? flag_get_sid($uid) : $sid; - if (isset($content_id)) { - if (!isset($flagged_content[$uid][$sid][$entity_type][$content_id])) { + if (isset($entity_id)) { + if (!isset($flagged_content[$uid][$sid][$entity_type][$entity_id])) { $flag_names = _flag_get_flag_names(); - $flagged_content[$uid][$sid][$entity_type][$content_id] = array(); + $flagged_content[$uid][$sid][$entity_type][$entity_id] = array(); $result = db_select('flagging', 'fc') ->fields('fc') ->condition('entity_type', $entity_type) - ->condition('content_id', $content_id) + ->condition('content_id', $entity_id) ->condition(db_or() ->condition('uid', $uid) ->condition('uid', 0) @@ -2012,10 +2012,10 @@ function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid ->execute(); foreach ($result as $flag_content) { - $flagged_content[$uid][$sid][$entity_type][$content_id][$flag_names[$flag_content->fid]] = $flag_content; + $flagged_content[$uid][$sid][$entity_type][$entity_id][$flag_names[$flag_content->fid]] = $flag_content; } } - return $flagged_content[$uid][$sid][$entity_type][$content_id]; + return $flagged_content[$uid][$sid][$entity_type][$entity_id]; } else { @@ -2045,7 +2045,7 @@ function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid * * @param $entity_type * The type of content that will be retrieved. Usually 'node'. - * @param $content_id + * @param $entity_id * The content ID to check for flagging. * @param $flag_name * Optional. The name of a flag if wanting a list specific to a single flag. @@ -2056,26 +2056,26 @@ function flag_get_user_flags($entity_type, $content_id = NULL, $uid = NULL, $sid * an array of flag information for each flag, keyed by the flag name. If * a flag name is specified, only the information for that flag is returned. */ -function flag_get_content_flags($entity_type, $content_id, $flag_name = NULL) { +function flag_get_content_flags($entity_type, $entity_id, $flag_name = NULL) { $content_flags = &drupal_static(__FUNCTION__, array()); - if (!isset($content_flags[$entity_type][$content_id])) { + if (!isset($content_flags[$entity_type][$entity_id])) { $flag_names = _flag_get_flag_names(); $result = db_select('flagging', 'fc') ->fields('fc') ->condition('entity_type', $entity_type) - ->condition('content_id', $content_id) + ->condition('content_id', $entity_id) ->orderBy('timestamp', 'DESC') ->execute(); foreach ($result as $flag_content) { // Build a list of flaggings for all flags by user. - $content_flags[$entity_type][$content_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; + $content_flags[$entity_type][$entity_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; // Build a list of flaggings for each individual flag. - $content_flags[$entity_type][$content_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; + $content_flags[$entity_type][$entity_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; } } - return isset($flag_name) ? $content_flags[$entity_type][$content_id]['flags'][$flag_name] : $content_flags[$entity_type][$content_id]['users']; + return isset($flag_name) ? $content_flags[$entity_type][$entity_id]['flags'][$flag_name] : $content_flags[$entity_type][$entity_id]['users']; } /** @@ -2089,20 +2089,20 @@ function flag_get_content_flags($entity_type, $content_id, $flag_name = NULL) { * * @param $flag_name * The "machine readable" name of the flag; e.g. 'bookmarks'. - * @param $content_id + * @param $entity_id * The content ID to check for flagging. This is usually a node ID. */ -function flag_create_link($flag_name, $content_id) { +function flag_create_link($flag_name, $entity_id) { $flag = flag_get_flag($flag_name); if (!$flag) { // Flag does not exist. return; } - if (!$flag->access($content_id) && (!$flag->is_flagged($content_id) || !$flag->access($content_id, 'flag'))) { + if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag. return; } - return $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id); + return $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id); } /** @@ -2149,17 +2149,17 @@ function flag_get_link_types($reset = FALSE) { /** * Get a private token used to protect links from spoofing - CSRF. */ -function flag_get_token($content_id) { +function flag_get_token($entity_id) { // Anonymous users get a less secure token, since it must be the same for all // anonymous users on the entire site to work with page caching. - return ($GLOBALS['user']->uid) ? drupal_get_token($content_id) : md5(drupal_get_private_key() . $content_id); + return ($GLOBALS['user']->uid) ? drupal_get_token($entity_id) : md5(drupal_get_private_key() . $entity_id); } /** * Check to see if a token value matches the specified node. */ -function flag_check_token($token, $content_id) { - return flag_get_token($content_id) == $token; +function flag_check_token($token, $entity_id) { + return flag_get_token($entity_id) == $token; } /** diff --git a/flag_actions.module b/flag_actions.module index 65baa08..b3bed68 100644 --- a/flag_actions.module +++ b/flag_actions.module @@ -8,8 +8,8 @@ /** * Implements hook_flag(). Trigger actions if any are available. */ -function flag_actions_flag($event, $flag, $content_id, $account) { - flag_actions_do($event, $flag, $content_id, $account); +function flag_actions_flag($event, $flag, $entity_id, $account) { + flag_actions_do($event, $flag, $entity_id, $account); } /** @@ -195,16 +195,16 @@ function flag_actions_delete_action($aid) { /** * Perform flag actions. */ -function flag_actions_do($event, $flag, $content_id, $account) { +function flag_actions_do($event, $flag, $entity_id, $account) { $actions = flag_actions_get_actions($flag->name); if (!$actions) { return; } - $flag_action = $flag->get_flag_action($content_id); + $flag_action = $flag->get_flag_action($entity_id); $flag_action->action = $event; - $flag_action->count = $count = $flag->get_count($content_id); - $relevant_objects = $flag->get_relevant_action_objects($content_id); + $flag_action->count = $count = $flag->get_count($entity_id); + $relevant_objects = $flag->get_relevant_action_objects($entity_id); $object_changed = FALSE; foreach ($actions as $aid => $action) { if ($action->event == 'flag') { diff --git a/includes/flag.cookie_storage.inc b/includes/flag.cookie_storage.inc index a7c7ac1..856f582 100644 --- a/includes/flag.cookie_storage.inc +++ b/includes/flag.cookie_storage.inc @@ -42,14 +42,14 @@ abstract class FlagCookieStorage { * * It just records this fact in a cookie. */ - abstract function flag($content_id); + abstract function flag($entity_id); /** * "Unflags" an item. * * It just records this fact in a cookie. */ - abstract function unflag($content_id); + abstract function unflag($entity_id); /** * Deletes all the cookies. @@ -67,14 +67,14 @@ abstract class FlagCookieStorage { */ class FlagGlobalCookieStorage extends FlagCookieStorage { - function flag($content_id) { - $cookie_key = $this->cookie_key($content_id); + function flag($entity_id) { + $cookie_key = $this->cookie_key($entity_id); setcookie($cookie_key, 1, REQUEST_TIME + $this->get_lifetime(), base_path()); $_COOKIE[$cookie_key] = 1; } - function unflag($content_id) { - $cookie_key = $this->cookie_key($content_id); + function unflag($entity_id) { + $cookie_key = $this->cookie_key($entity_id); setcookie($cookie_key, 0, REQUEST_TIME + $this->get_lifetime(), base_path()); $_COOKIE[$cookie_key] = 0; } @@ -92,8 +92,8 @@ class FlagGlobalCookieStorage extends FlagCookieStorage { return $cookie_lifetime; } - protected function cookie_key($content_id) { - return 'flag_global_' . $this->flag->name . '_' . $content_id; + protected function cookie_key($entity_id) { + return 'flag_global_' . $this->flag->name . '_' . $entity_id; } /** @@ -122,15 +122,15 @@ class FlagNonGlobalCookieStorage extends FlagCookieStorage { $this->flaggings = isset($_COOKIE['flags']) ? explode(' ', $_COOKIE['flags']) : array(); } - function flag($content_id) { - if (!$this->is_flagged($content_id)) { - $this->flaggings[] = $this->cookie_key($content_id); + function flag($entity_id) { + if (!$this->is_flagged($entity_id)) { + $this->flaggings[] = $this->cookie_key($entity_id); $this->write(); } } - function unflag($content_id) { - if (($index = $this->index_of($content_id)) !== FALSE) { + function unflag($entity_id) { + if (($index = $this->index_of($entity_id)) !== FALSE) { unset($this->flaggings[$index]); $this->write(); } @@ -140,8 +140,8 @@ class FlagNonGlobalCookieStorage extends FlagCookieStorage { return min((int) ini_get('session.cookie_lifetime'), (int) ini_get('session.gc_maxlifetime')); } - protected function cookie_key($content_id) { - return $this->flag->name . '_' . $content_id; + protected function cookie_key($entity_id) { + return $this->flag->name . '_' . $entity_id; } protected function write() { @@ -150,12 +150,12 @@ class FlagNonGlobalCookieStorage extends FlagCookieStorage { $_COOKIE['flags'] = $serialized; } - protected function is_flagged($content_id) { - return $this->index_of($content_id) !== FALSE; + protected function is_flagged($entity_id) { + return $this->index_of($entity_id) !== FALSE; } - protected function index_of($content_id) { - return array_search($this->cookie_key($content_id), $this->flaggings); + protected function index_of($entity_id) { + return array_search($this->cookie_key($entity_id), $this->flaggings); } /** diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 48bf370..202609d 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -84,26 +84,26 @@ class flag_comment extends flag_entity { return array_merge(array('comment', 'node'), parent::get_labels_token_types()); } - function replace_tokens($label, $contexts, $options, $content_id) { - if ($content_id) { - if (($comment = $this->fetch_content($content_id)) && ($node = node_load($comment->nid))) { + function replace_tokens($label, $contexts, $options, $entity_id) { + if ($entity_id) { + if (($comment = $this->fetch_content($entity_id)) && ($node = node_load($comment->nid))) { $contexts['node'] = $node; $contexts['comment'] = $comment; } } - return parent::replace_tokens($label, $contexts, $options, $content_id); + return parent::replace_tokens($label, $contexts, $options, $entity_id); } - function get_flag_action($content_id) { - $flag_action = parent::get_flag_action($content_id); - $comment = $this->fetch_content($content_id); + function get_flag_action($entity_id) { + $flag_action = parent::get_flag_action($entity_id); + $comment = $this->fetch_content($entity_id); $flag_action->content_title = $comment->subject; $flag_action->content_url = _flag_url("comment/$comment->cid", "comment-$comment->cid"); return $flag_action; } - function get_relevant_action_objects($content_id) { - $comment = $this->fetch_content($content_id); + function get_relevant_action_objects($entity_id) { + $comment = $this->fetch_content($entity_id); return array( 'comment' => $comment, 'node' => node_load($comment->nid), diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index db49790..8ae3b3d 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -62,9 +62,9 @@ class flag_entity extends flag_flag { /** * Loads the entity object. */ - function _load_content($content_id) { - if (is_numeric($content_id)) { - $entity = entity_load($this->entity_type, array($content_id)); + function _load_content($entity_id) { + if (is_numeric($entity_id)) { + $entity = entity_load($this->entity_type, array($entity_id)); return reset($entity); } return NULL; @@ -113,19 +113,19 @@ class flag_entity extends flag_flag { /** * Replaces tokens. */ - function replace_tokens($label, $contexts, $options, $content_id) { - if ($content_id && ($entity = $this->fetch_content($content_id))) { + function replace_tokens($label, $contexts, $options, $entity_id) { + if ($entity_id && ($entity = $this->fetch_content($entity_id))) { $contexts[$this->entity_type] = $entity; } - return parent::replace_tokens($label, $contexts, $options, $content_id); + return parent::replace_tokens($label, $contexts, $options, $entity_id); } /** * Returns a 'flag action' object. */ - function get_flag_action($content_id) { - $flag_action = parent::get_flag_action($content_id); - $entity = $this->fetch_content($content_id); + function get_flag_action($entity_id) { + $flag_action = parent::get_flag_action($entity_id); + $entity = $this->fetch_content($entity_id); $flag_action->content_title = entity_label($this->entity_type, $entity); $flag_action->content_url = _flag_url($this->entity_type . '/' . $this->get_content_id($entity)); return $flag_action; @@ -134,9 +134,9 @@ class flag_entity extends flag_flag { /** * Returns objects the action may possible need. */ - function get_relevant_action_objects($content_id) { + function get_relevant_action_objects($entity_id) { return array( - $this->entity_type => $this->fetch_content($content_id), + $this->entity_type => $this->fetch_content($entity_id), ); } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index adcf3df..b08087f 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -242,16 +242,16 @@ class flag_flag { /** * Fetches, possibly from some cache, a content object this flag works with. */ - function fetch_content($content_id, $object_to_remember = NULL) { + function fetch_content($entity_id, $object_to_remember = NULL) { static $cache = array(); if (isset($object_to_remember)) { - $cache[$content_id] = $object_to_remember; + $cache[$entity_id] = $object_to_remember; } - if (!array_key_exists($content_id, $cache)) { - $content = $this->_load_content($content_id); - $cache[$content_id] = $content ? $content : NULL; + if (!array_key_exists($entity_id, $cache)) { + $content = $this->_load_content($entity_id); + $cache[$entity_id] = $content ? $content : NULL; } - return $cache[$content_id]; + return $cache[$entity_id]; } /** @@ -262,7 +262,7 @@ class flag_flag { * @private * @static */ - function _load_content($content_id) { + function _load_content($entity_id) { return NULL; } @@ -274,8 +274,8 @@ class flag_flag { * database (by calling _load_content()), whereas sometimes we want to fetch * an object that hasn't yet been saved to the database. See flag_nodeapi(). */ - function remember_content($content_id, $object) { - $this->fetch_content($content_id, $object); + function remember_content($entity_id, $object) { + $this->fetch_content($entity_id, $object); } /** @@ -301,8 +301,8 @@ class flag_flag { * applies_to_content_object(). If you already have the object, don't call * this function: call applies_to_content_object() directly. */ - function applies_to_content_id($content_id) { - return $this->applies_to_content_object($this->fetch_content($content_id)); + function applies_to_content_id($entity_id) { + return $this->applies_to_content_object($this->fetch_content($entity_id)); } /** @@ -337,7 +337,7 @@ class flag_flag { * This method typically should not be overridden by child classes. Instead * they should implement type_access(), which is called by this method. * - * @param $content_id + * @param $entity_id * The content ID to flag/unflag. * @param $action * The action to test. Either 'flag' or 'unflag'. Leave NULL to determine @@ -350,12 +350,12 @@ class flag_flag { * Boolean TRUE if the user is allowed to flag/unflag the given content. * FALSE otherwise. */ - function access($content_id, $action = NULL, $account = NULL) { + function access($entity_id, $action = NULL, $account = NULL) { if (!isset($account)) { $account = $GLOBALS['user']; } - if (isset($content_id) && !$this->applies_to_content_id($content_id)) { + if (isset($entity_id) && !$this->applies_to_content_id($entity_id)) { // Flag does not apply to this content. return FALSE; } @@ -363,20 +363,20 @@ class flag_flag { if (!isset($action)) { $uid = $account->uid; $sid = flag_get_sid($uid); - $action = $this->is_flagged($content_id, $uid, $sid) ? 'unflag' : 'flag'; + $action = $this->is_flagged($entity_id, $uid, $sid) ? 'unflag' : 'flag'; } // Base initial access on the user's basic permission to use this flag. $access = $this->user_access($action, $account); // Check for additional access rules provided by sub-classes. - $child_access = $this->type_access($content_id, $action, $account); + $child_access = $this->type_access($entity_id, $action, $account); if (isset($child_access)) { $access = $child_access; } // Allow modules to disallow (or allow) access to flagging. - $access_array = module_invoke_all('flag_access', $this, $content_id, $action, $account); + $access_array = module_invoke_all('flag_access', $this, $entity_id, $action, $account); foreach ($access_array as $set_access) { if (isset($set_access)) { @@ -418,16 +418,16 @@ class flag_flag { $access = array(); // First check basic user access for this action. - foreach ($content_ids as $content_id => $action) { - $access[$content_id] = $this->user_access($content_ids[$content_id], $account); + foreach ($content_ids as $entity_id => $action) { + $access[$entity_id] = $this->user_access($content_ids[$entity_id], $account); } // Check for additional access rules provided by sub-classes. $child_access = $this->type_access_multiple($content_ids, $account); if (isset($child_access)) { - foreach ($child_access as $content_id => $content_access) { + foreach ($child_access as $entity_id => $content_access) { if (isset($content_access)) { - $access[$content_id] = $content_access; + $access[$entity_id] = $content_access; } } } @@ -435,9 +435,9 @@ class flag_flag { // Merge in module-defined access. foreach (module_implements('flag_access_multiple') as $module) { $module_access = module_invoke($module, 'flag_access_multiple', $this, $content_ids, $account); - foreach ($module_access as $content_id => $content_access) { + foreach ($module_access as $entity_id => $content_access) { if (isset($content_access)) { - $access[$content_id] = $content_access; + $access[$entity_id] = $content_access; } } } @@ -450,7 +450,7 @@ class flag_flag { * * @abstract */ - function type_access($content_id, $action, $account) { + function type_access($entity_id, $action, $account) { return NULL; } @@ -498,7 +498,7 @@ class flag_flag { * * @param $action * Either 'flag' or 'unflag'. - * @param $content_id + * @param $entity_id * The ID of the item to flag or unflag. * @param $account * The user on whose behalf to flag. Leave empty for the current user. @@ -512,7 +512,7 @@ class flag_flag { * FALSE if some error occured (e.g., user has no permission, flag isn't * applicable to the item, etc.), TRUE otherwise. */ - function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { + function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { // Get the user. if (!isset($account)) { $account = $GLOBALS['user']; @@ -523,7 +523,7 @@ class flag_flag { // Check access and applicability. if (!$skip_permission_check) { - if (!$this->access($content_id, $action, $account)) { + if (!$this->access($entity_id, $action, $account)) { // User has no permission to flag/unflag this object. return FALSE; } @@ -531,7 +531,7 @@ class flag_flag { else { // We are skipping permission checks. However, at a minimum we must make // sure the flag applies to this content type: - if (!$this->applies_to_content_id($content_id)) { + if (!$this->applies_to_content_id($entity_id)) { return FALSE; } } @@ -570,35 +570,35 @@ class flag_flag { // @todo: Discuss: Core wraps everything in a try { }, should we? // Perform the flagging or unflagging of this flag. - $existing_fcid = $this->_is_flagged($content_id, $uid, $sid); + $existing_fcid = $this->_is_flagged($entity_id, $uid, $sid); $flagged = (bool) $existing_fcid; if ($action == 'unflag') { if ($this->uses_anonymous_cookies()) { - $this->_unflag_anonymous($content_id); + $this->_unflag_anonymous($entity_id); } if ($flagged) { // Note the order: We delete the entity before calling _unflag() to // delete the {flagging} record. $this->_delete_flagging($existing_fcid); - $this->_unflag($content_id, $uid, $sid); - module_invoke_all('flag', 'unflag', $this, $content_id, $account, $existing_fcid); + $this->_unflag($entity_id, $uid, $sid); + module_invoke_all('flag', 'unflag', $this, $entity_id, $account, $existing_fcid); } } elseif ($action == 'flag') { if ($this->uses_anonymous_cookies()) { - $this->_flag_anonymous($content_id); + $this->_flag_anonymous($entity_id); } if (!$flagged) { if (!isset($flagging)) { // Construct a new flagging object if we don't have one. - $flagging = $this->new_flagging($content_id, $uid, $sid); + $flagging = $this->new_flagging($entity_id, $uid, $sid); } - $fcid = $this->_flag($content_id, $uid, $sid); + $fcid = $this->_flag($entity_id, $uid, $sid); // We're writing out a flagging entity even when we aren't passed one // (e.g., when flagging via JavaScript toggle links); in this case // Field API will assign the fields their default values. - $this->_insert_flagging($flagging, $content_id, $fcid); - module_invoke_all('flag', 'flag', $this, $content_id, $account, $fcid); + $this->_insert_flagging($flagging, $entity_id, $fcid); + module_invoke_all('flag', 'flag', $this, $entity_id, $account, $fcid); } else { // Nothing to do. Item is already flagged. @@ -623,7 +623,7 @@ class flag_flag { * operation is also accompanied by some bookkeeping (calling hooks, updating * counters) or access control. These tasks are handled by the flag() method. */ - private function _insert_flagging($flagging, $content_id, $fcid) { + private function _insert_flagging($flagging, $entity_id, $fcid) { $flagging->fcid = $fcid; field_attach_presave('flagging', $flagging); field_attach_insert('flagging', $flagging); @@ -645,7 +645,7 @@ class flag_flag { /** * Construct a new, empty flagging entity object. * - * @param mixed $content_id + * @param mixed $entity_id * The unique identifier of the content being flagged. * @param int $uid * Optional. The user id of the user doing the flagging. @@ -658,11 +658,11 @@ class flag_flag { * enables Field API to figure out the bundle, but it's your responsibility * to eventually populate 'content_id' and 'fcid'. */ - function new_flagging($content_id = NULL, $uid = NULL, $sid = NULL) { + function new_flagging($entity_id = NULL, $uid = NULL, $sid = NULL) { return (object) array( 'fcid' => NULL, 'flag_name' => $this->name, - 'content_id' => $content_id, + 'content_id' => $entity_id, 'uid' => $uid, 'sid' => $sid, ); @@ -681,8 +681,8 @@ class flag_flag { * @return * TRUE if the content is flagged, FALSE otherwise. */ - function is_flagged($content_id, $uid = NULL, $sid = NULL) { - return (bool) $this->get_flagging_record($content_id, $uid, $sid); + function is_flagged($entity_id, $uid = NULL, $sid = NULL) { + return (bool) $this->get_flagging_record($entity_id, $uid, $sid); } /** @@ -698,20 +698,20 @@ class flag_flag { * * Parameters are the same as is_flagged()'s. */ - function get_flagging_record($content_id, $uid = NULL, $sid = NULL) { + function get_flagging_record($entity_id, $uid = NULL, $sid = NULL) { $uid = $this->global ? 0 : (!isset($uid) ? $GLOBALS['user']->uid : $uid); $sid = $this->global ? 0 : (!isset($sid) ? flag_get_sid($uid) : $sid); // flag_get_user_flags() does caching. - $user_flags = flag_get_user_flags($this->entity_type, $content_id, $uid, $sid); + $user_flags = flag_get_user_flags($this->entity_type, $entity_id, $uid, $sid); return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL; } /** * Similar to is_flagged() excepts it returns the flagging entity. */ - function get_flagging($content_id, $uid = NULL, $sid = NULL) { - if (($record = $this->get_flagging_record($content_id, $uid, $sid))) { + function get_flagging($entity_id, $uid = NULL, $sid = NULL) { + if (($record = $this->get_flagging_record($entity_id, $uid, $sid))) { return flagging_load($record->fcid); } } @@ -732,13 +732,13 @@ class flag_flag { * * @private */ - function _is_flagged($content_id, $uid, $sid) { + function _is_flagged($entity_id, $uid, $sid) { return db_select('flagging', 'fc') ->fields('fc', array('fcid')) ->condition('fid', $this->fid) ->condition('uid', $uid) ->condition('sid', $sid) - ->condition('content_id', $content_id) + ->condition('content_id', $entity_id) ->execute() ->fetchField(); } @@ -754,18 +754,18 @@ class flag_flag { * * @private */ - function _flag($content_id, $uid, $sid) { + function _flag($entity_id, $uid, $sid) { $fcid = db_insert('flagging') ->fields(array( 'fid' => $this->fid, 'entity_type' => $this->entity_type, - 'content_id' => $content_id, + 'content_id' => $entity_id, 'uid' => $uid, 'sid' => $sid, 'timestamp' => REQUEST_TIME, )) ->execute(); - $this->_increase_count($content_id); + $this->_increase_count($entity_id); return $fcid; } @@ -781,18 +781,18 @@ class flag_flag { * * @private */ - function _unflag($content_id, $uid, $sid) { + function _unflag($entity_id, $uid, $sid) { $fcid = db_select('flagging', 'fc') ->fields('fc', array('fcid')) ->condition('fid', $this->fid) ->condition('uid', $uid) ->condition('sid', $sid) - ->condition('content_id', $content_id) + ->condition('content_id', $entity_id) ->execute() ->fetchField(); if ($fcid) { db_delete('flagging')->condition('fcid', $fcid)->execute(); - $this->_decrease_count($content_id); + $this->_decrease_count($entity_id); } return $fcid; } @@ -800,18 +800,18 @@ class flag_flag { /** * Increases the flag count for a piece of content. * - * @param $content_id + * @param $entity_id * For which item should the count be increased. * @param $number * The amount of counts to increasing. Defaults to 1. * * @private */ - function _increase_count($content_id, $number = 1) { + function _increase_count($entity_id, $number = 1) { db_merge('flag_counts') ->key(array( 'fid' => $this->fid, - 'content_id' => $content_id, + 'content_id' => $entity_id, )) ->fields(array( 'entity_type' => $this->entity_type, @@ -828,19 +828,19 @@ class flag_flag { /** * Decreases the flag count for a piece of content. * - * @param $content_id + * @param $entity_id * For which item should the count be descreased. * @param $number * The amount of counts to decrease. Defaults to 1. * * @private */ - function _decrease_count($content_id, $number = 1) { + function _decrease_count($entity_id, $number = 1) { // Delete rows with count 0, for data consistency and space-saving. // Done before the db_update() to prevent out-of-bounds errors on "count". db_delete('flag_counts') ->condition('fid', $this->fid) - ->condition('content_id', $content_id) + ->condition('content_id', $entity_id) ->condition('count', $number, '<=') ->execute(); @@ -851,7 +851,7 @@ class flag_flag { 'last_updated' => REQUEST_TIME, )) ->condition('fid', $this->fid) - ->condition('content_id', $content_id) + ->condition('content_id', $entity_id) ->execute(); } @@ -860,9 +860,9 @@ class flag_flag { * * @private */ - function _flag_anonymous($content_id) { + function _flag_anonymous($entity_id) { $storage = FlagCookieStorage::factory($this); - $storage->flag($content_id); + $storage->flag($entity_id); } /** @@ -870,9 +870,9 @@ class flag_flag { * * @private */ - function _unflag_anonymous($content_id) { + function _unflag_anonymous($entity_id) { $storage = FlagCookieStorage::factory($this); - $storage->unflag($content_id); + $storage->unflag($entity_id); } /** @@ -881,8 +881,8 @@ class flag_flag { * Thanks to using a cache, inquiring several different flags about the same * item results in only one SQL query. */ - function get_count($content_id) { - $counts = flag_get_counts($this->entity_type, $content_id); + function get_count($entity_id) { + $counts = flag_get_counts($this->entity_type, $entity_id); return isset($counts[$this->name]) ? $counts[$this->name] : 0; } @@ -910,19 +910,19 @@ class flag_flag { * * @param $label * The label to get, e.g. 'title', 'flag_short', 'unflag_short', etc. - * @param $content_id + * @param $entity_id * The ID in whose context to interpret tokens. If not given, only global * tokens will be substituted. * @return * The processed label. */ - function get_label($label, $content_id = NULL) { + function get_label($label, $entity_id = NULL) { if (!isset($this->$label)) { return; } $label = t($this->$label); if (strpos($label, '[') !== FALSE) { - $label = $this->replace_tokens($label, array(), array('sanitize' => FALSE), $content_id); + $label = $this->replace_tokens($label, array(), array('sanitize' => FALSE), $entity_id); } return filter_xss_admin($label); } @@ -940,9 +940,9 @@ class flag_flag { * by default, so derived classes should override this method to add all * token contexts they understand. */ - function replace_tokens($label, $contexts, $options, $content_id) { + function replace_tokens($label, $contexts, $options, $entity_id) { if (strpos($label , 'flagging:') !== FALSE) { - if (($flagging = $this->get_flagging($content_id))) { + if (($flagging = $this->get_flagging($entity_id))) { $contexts['flagging'] = $flagging; } } @@ -965,14 +965,14 @@ class flag_flag { * * `$flag->get_title()` is shorthand for `$flag->get_label('title')`. */ - function get_title($content_id = NULL, $reset = FALSE) { + function get_title($entity_id = NULL, $reset = FALSE) { static $titles = array(); if ($reset) { $titles = array(); } - $slot = intval($content_id); // Convert NULL to 0. + $slot = intval($entity_id); // Convert NULL to 0. if (!isset($titles[$this->fid][$slot])) { - $titles[$this->fid][$slot] = $this->get_label('title', $content_id); + $titles[$this->fid][$slot] = $this->get_label('title', $entity_id); } return $titles[$this->fid][$slot]; } @@ -984,11 +984,11 @@ class flag_flag { * Derived classes should populate the 'content_title' and 'content_url' * slots. */ - function get_flag_action($content_id) { + function get_flag_action($entity_id) { $flag_action = new stdClass(); $flag_action->flag = $this->name; $flag_action->entity_type = $this->entity_type; - $flag_action->content_id = $content_id; + $flag_action->content_id = $entity_id; return $flag_action; } @@ -1024,7 +1024,7 @@ class flag_flag { * * @abstract */ - function get_relevant_action_objects($content_id) { + function get_relevant_action_objects($entity_id) { return array(); } @@ -1240,7 +1240,7 @@ class flag_flag { * * For parameters docmentation, see theme_flag(). */ - function theme($action, $content_id, $after_flagging = FALSE) { + function theme($action, $entity_id, $after_flagging = FALSE) { static $js_added = array(); global $user; @@ -1265,14 +1265,14 @@ class flag_flag { $js_action = 'unflag'; $action = 'flag'; } - if (!isset($js_added[$this->name . '_' . $content_id])) { - $js_added[$this->name . '_' . $content_id] = TRUE; - $js_template = theme($this->theme_suggestions(), array('flag' => $this, 'action' => $js_action, 'content_id' => $content_id, 'after_flagging' => $after_flagging)); - drupal_add_js(array('flag' => array('templates' => array($this->name . '_' . $content_id => $js_template))), 'setting'); + if (!isset($js_added[$this->name . '_' . $entity_id])) { + $js_added[$this->name . '_' . $entity_id] = TRUE; + $js_template = theme($this->theme_suggestions(), array('flag' => $this, 'action' => $js_action, 'content_id' => $entity_id, 'after_flagging' => $after_flagging)); + drupal_add_js(array('flag' => array('templates' => array($this->name . '_' . $entity_id => $js_template))), 'setting'); } } - return theme($this->theme_suggestions(), array('flag' => $this, 'action' => $action, 'content_id' => $content_id, 'after_flagging' => $after_flagging)); + return theme($this->theme_suggestions(), array('flag' => $this, 'action' => $action, 'content_id' => $entity_id, 'after_flagging' => $after_flagging)); } /** diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index 6ecf757..5a87c92 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -102,19 +102,19 @@ class flag_node extends flag_entity { /** * Adjust the Content ID to find the translation parent if i18n-enabled. * - * @param $content_id + * @param $entity_id * The nid for the content. * @return * The tnid if available, the nid otherwise. */ - function get_translation_id($content_id) { + function get_translation_id($entity_id) { if ($this->i18n) { - $node = $this->fetch_content($content_id); + $node = $this->fetch_content($entity_id); if (!empty($node->tnid)) { - $content_id = $node->tnid; + $entity_id = $node->tnid; } } - return $content_id; + return $entity_id; } function uses_hook_link($teaser) { @@ -124,32 +124,32 @@ class flag_node extends flag_entity { return FALSE; } - function flag($action, $content_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { - $content_id = $this->get_translation_id($content_id); - return parent::flag($action, $content_id, $account, $skip_permission_check, $flagging); + function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { + $entity_id = $this->get_translation_id($entity_id); + return parent::flag($action, $entity_id, $account, $skip_permission_check, $flagging); } // Instead of overriding is_flagged() we override get_flagging_record(), // which is the underlying method. - function get_flagging_record($content_id, $uid = NULL, $sid = NULL) { - $content_id = $this->get_translation_id($content_id); - return parent::get_flagging_record($content_id, $uid, $sid); + function get_flagging_record($entity_id, $uid = NULL, $sid = NULL) { + $entity_id = $this->get_translation_id($entity_id); + return parent::get_flagging_record($entity_id, $uid, $sid); } - function replace_tokens($label, $contexts, $options, $content_id) { - if (is_numeric($content_id) && ($node = $this->fetch_content($content_id))) { + function replace_tokens($label, $contexts, $options, $entity_id) { + if (is_numeric($entity_id) && ($node = $this->fetch_content($entity_id))) { $contexts['node'] = $node; } - // Nodes accept the node-type as a $content_id in the case that a new node + // Nodes accept the node-type as a $entity_id in the case that a new node // is being created and a full node object does not yet exist. - elseif (!empty($content_id) && ($type = node_type_get_type($content_id))) { - $content_id = NULL; + elseif (!empty($entity_id) && ($type = node_type_get_type($entity_id))) { + $entity_id = NULL; $contexts['node'] = (object) array( 'nid' => NULL, 'type' => $type->type, 'title' => '', ); } - return parent::replace_tokens($label, $contexts, $options, $content_id); + return parent::replace_tokens($label, $contexts, $options, $entity_id); } } diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc index b302393..6242d46 100644 --- a/includes/flag/flag_user.inc +++ b/includes/flag/flag_user.inc @@ -54,9 +54,9 @@ class flag_user extends flag_entity { $this->access_uid = empty($form_values['access_uid']) ? 'others' : ''; } - function type_access($content_id, $action, $account) { + function type_access($entity_id, $action, $account) { // Prevent users from flagging themselves. - if ($this->access_uid == 'others' && $content_id == $account->uid) { + if ($this->access_uid == 'others' && $entity_id == $account->uid) { return FALSE; } } @@ -84,17 +84,17 @@ class flag_user extends flag_entity { return FALSE; } - function get_flag_action($content_id) { - $flag_action = parent::get_flag_action($content_id); - $user = $this->fetch_content($content_id); + function get_flag_action($entity_id) { + $flag_action = parent::get_flag_action($entity_id); + $user = $this->fetch_content($entity_id); $flag_action->content_title = $user->name; $flag_action->content_url = _flag_url('user/' . $user->uid); return $flag_action; } - function get_relevant_action_objects($content_id) { + function get_relevant_action_objects($entity_id) { return array( - 'user' => $this->fetch_content($content_id), + 'user' => $this->fetch_content($entity_id), ); } diff --git a/includes/views/flag_handler_field_ops.inc b/includes/views/flag_handler_field_ops.inc index cf29a67..52ec38f 100644 --- a/includes/views/flag_handler_field_ops.inc +++ b/includes/views/flag_handler_field_ops.inc @@ -116,10 +116,10 @@ class flag_handler_field_ops extends views_handler_field { $ids = array(); foreach ($values as $row) { - $content_id = $row->{$this->aliases['content_id']}; + $entity_id = $row->{$this->aliases['content_id']}; $is_flagged = $row->{$this->aliases['is_flagged']}; - if (isset($content_id)) { - $ids[$content_id] = $is_flagged ? 'unflag' : 'flag'; + if (isset($entity_id)) { + $ids[$entity_id] = $is_flagged ? 'unflag' : 'flag'; } } $this->flag_applies = $ids ? $flag->access_multiple($ids) : array(); @@ -130,10 +130,10 @@ class flag_handler_field_ops extends views_handler_field { return t('Missing flag'); // get_flag() itself will print a more detailed message. } - $content_id = $values->{$this->aliases['content_id']}; + $entity_id = $values->{$this->aliases['content_id']}; $is_flagged = $values->{$this->aliases['is_flagged']}; - if (empty($this->flag_applies[$content_id])) { + if (empty($this->flag_applies[$entity_id])) { // Flag does not apply to this content. return; } @@ -141,6 +141,6 @@ class flag_handler_field_ops extends views_handler_field { if (!empty($this->options['link_type'])) { $flag->link_type = $this->options['link_type']; } - return $flag->theme($is_flagged ? 'unflag' : 'flag', $content_id); + return $flag->theme($is_flagged ? 'unflag' : 'flag', $entity_id); } } From a8e3863bfa7160a6be71d24555d2b57c6773ab17 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 20:22:33 +0100 Subject: [PATCH 111/629] Changed all $content_ids variables to $entity_ids. Replace s/\$content_ids\b/$entity_ids/ throughout. --- flag.api.php | 4 ++-- flag.module | 6 +++--- includes/flag/flag_comment.inc | 4 ++-- includes/flag/flag_flag.inc | 14 +++++++------- includes/flag/flag_node.inc | 4 ++-- includes/flag/flag_user.inc | 6 +++--- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/flag.api.php b/flag.api.php index d31d7a0..0ab7e27 100644 --- a/flag.api.php +++ b/flag.api.php @@ -126,7 +126,7 @@ function hook_flag_access($flag, $entity_id, $action, $account) { * * @param $flag * The flag object. - * @param $content_ids + * @param $entity_ids * An array of object ids to check access. * @param $account * The user on whose behalf to test the flagging action. @@ -138,7 +138,7 @@ function hook_flag_access($flag, $entity_id, $action, $account) { * @see hook_flag_access() * @see flag_flag:access_multiple() */ -function hook_flag_access_multiple($flag, $content_ids, $account) { +function hook_flag_access_multiple($flag, $entity_ids, $account) { } diff --git a/flag.module b/flag.module index 9032743..4cab420 100644 --- a/flag.module +++ b/flag.module @@ -1282,7 +1282,7 @@ function flag_flag_access($flag, $entity_id, $action, $account) { /** * Implements hook_flag_access_multiple(). */ -function flag_flag_access_multiple($flag, $content_ids, $account) { +function flag_flag_access_multiple($flag, $entity_ids, $account) { $access = array(); // Do nothing if there is no restriction by authorship. @@ -1297,7 +1297,7 @@ function flag_flag_access_multiple($flag, $content_ids, $account) { // want to deny access, or use the current access value provided by Flag. $result = db_select('node', 'n') ->fields('n', array('nid', 'uid')) - ->condition('nid', array_keys($content_ids), 'IN') + ->condition('nid', array_keys($entity_ids), 'IN') ->condition('type', $flag->types, 'IN') ->execute(); foreach ($result as $row) { @@ -1316,7 +1316,7 @@ function flag_flag_access_multiple($flag, $content_ids, $account) { $query->leftJoin('node', 'n', 'c.nid = n.nid'); $query ->fields('c', array('cid', 'nid', 'uid')) - ->condition('c.cid', $content_ids, 'IN'); + ->condition('c.cid', $entity_ids, 'IN'); $query->addField('c', 'uid', 'comment_uid'); $result = $query->execute(); diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 202609d..8bc3d32 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -50,7 +50,7 @@ class flag_comment extends flag_entity { unset($form['display']['show_on_entity']); } - function type_access_multiple($content_ids, $account) { + function type_access_multiple($entity_ids, $account) { $access = array(); // Ensure node types are granted access. This avoids a @@ -59,7 +59,7 @@ class flag_comment extends flag_entity { $query->innerJoin('node', 'n', 'c.nid = n.nid'); $result = $query ->fields('c', array('cid')) - ->condition('c.cid', $content_ids, 'IN') + ->condition('c.cid', $entity_ids, 'IN') ->condition('n.type', $this->types, 'NOT IN') ->execute(); foreach ($result as $row) { diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index b08087f..dcfa732 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -400,7 +400,7 @@ class flag_flag { * they should implement type_access_multiple(), which is called by this * method. * - * @param $content_ids + * @param $entity_ids * The array of content IDs to check. The keys are the content IDs, the * values are the actions to test: either 'flag' or 'unflag'. * @param $account @@ -413,17 +413,17 @@ class flag_flag { * * @see hook_flag_access_multiple() */ - function access_multiple($content_ids, $account = NULL) { + function access_multiple($entity_ids, $account = NULL) { $account = isset($account) ? $account : $GLOBALS['user']; $access = array(); // First check basic user access for this action. - foreach ($content_ids as $entity_id => $action) { - $access[$entity_id] = $this->user_access($content_ids[$entity_id], $account); + foreach ($entity_ids as $entity_id => $action) { + $access[$entity_id] = $this->user_access($entity_ids[$entity_id], $account); } // Check for additional access rules provided by sub-classes. - $child_access = $this->type_access_multiple($content_ids, $account); + $child_access = $this->type_access_multiple($entity_ids, $account); if (isset($child_access)) { foreach ($child_access as $entity_id => $content_access) { if (isset($content_access)) { @@ -434,7 +434,7 @@ class flag_flag { // Merge in module-defined access. foreach (module_implements('flag_access_multiple') as $module) { - $module_access = module_invoke($module, 'flag_access_multiple', $this, $content_ids, $account); + $module_access = module_invoke($module, 'flag_access_multiple', $this, $entity_ids, $account); foreach ($module_access as $entity_id => $content_access) { if (isset($content_access)) { $access[$entity_id] = $content_access; @@ -459,7 +459,7 @@ class flag_flag { * * @abstract */ - function type_access_multiple($content_ids, $account) { + function type_access_multiple($entity_ids, $account) { return array(); } diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index 5a87c92..c900220 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -83,13 +83,13 @@ class flag_node extends flag_entity { unset($form['display']['show_on_entity']); } - function type_access_multiple($content_ids, $account = NULL) { + function type_access_multiple($entity_ids, $account = NULL) { $access = array(); // Ensure that only flaggable node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_content_id(). $result = db_select('node', 'n')->fields('n', array('nid')) - ->condition('nid', array_keys($content_ids), 'IN') + ->condition('nid', array_keys($entity_ids), 'IN') ->condition('type', $this->types, 'NOT IN') ->execute(); foreach ($result as $row) { diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc index 6242d46..5185d67 100644 --- a/includes/flag/flag_user.inc +++ b/includes/flag/flag_user.inc @@ -61,16 +61,16 @@ class flag_user extends flag_entity { } } - function type_access_multiple($content_ids, $account) { + function type_access_multiple($entity_ids, $account) { $access = array(); // Exclude anonymous. - if (array_key_exists(0, $content_ids)) { + if (array_key_exists(0, $entity_ids)) { $access[0] = FALSE; } // Prevent users from flagging themselves. - if ($this->access_uid == 'others' && array_key_exists($account->uid, $content_ids)) { + if ($this->access_uid == 'others' && array_key_exists($account->uid, $entity_ids)) { $access[$account->uid] = FALSE; } From 13daa1f389169a6c03fea919dd0b7af44a6aa853 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 21:21:30 +0100 Subject: [PATCH 112/629] Changed method flag_get_content_id() to flag_get_entity_id(). --- flag.module | 6 +++--- flag.rules.inc | 10 +++++----- flag.tokens.inc | 4 ++-- includes/flag/flag_comment.inc | 2 +- includes/flag/flag_entity.inc | 4 ++-- includes/flag/flag_flag.inc | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/flag.module b/flag.module index 4cab420..ce5a274 100644 --- a/flag.module +++ b/flag.module @@ -340,7 +340,7 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { $flags = flag_get_flags($type); foreach ($flags as $flag) { - $entity_id = $flag->get_content_id($object); + $entity_id = $flag->get_entity_id($object); if (!$flag->uses_hook_link($teaser)) { // Flag is not configured to show its link here. @@ -688,7 +688,7 @@ function flag_contextual_links_view_alter(&$element, $items) { continue; } - $entity_id = $flag->get_content_id($node); + $entity_id = $flag->get_entity_id($node); if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this // content. The link is not skipped if the user has "flag" access but @@ -1948,7 +1948,7 @@ function flag_get_flagged_content($flag_name) { * @param $fcid * The flag content ID for which to look up the content ID. */ -function flag_get_content_id($fcid) { +function flag_get_entity_id($fcid) { return db_select('flagging', 'fc') ->fields('fc', array('content_id')) ->condition('fcid', $fcid) diff --git a/flag.rules.inc b/flag.rules.inc index 815462a..e03c9ab 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -300,14 +300,14 @@ function flag_rules_action_info() { * Base action implementation: Flag. */ function flag_rules_action_flag($flag, $entity, $flagging_user, $permissions_check) { - $flag->flag('flag', $flag->get_content_id($entity), $flagging_user, $permissions_check); + $flag->flag('flag', $flag->get_entity_id($entity), $flagging_user, $permissions_check); } /** * Base action implementation: Unflag. */ function flag_rules_action_unflag($flag, $entity, $flagging_user, $permissions_check) { - $flag->flag('unflag', $flag->get_content_id($entity), $flagging_user, $permissions_check); + $flag->flag('unflag', $flag->get_entity_id($entity), $flagging_user, $permissions_check); } /** @@ -324,7 +324,7 @@ function flag_rules_action_fetch_users($flag, $entity) { $result = db_select('flagging', 'fc') ->fields('fc', array('uid')) ->condition('entity_type', $flag->entity_type) - ->condition('content_id', $flag->get_content_id($entity)) + ->condition('entity_id', $flag->get_entity_id($entity)) ->condition('fid', $flag->fid) ->execute(); $uids = $result->fetchCol(); @@ -433,7 +433,7 @@ function flag_rules_condition_threshold_operator_options() { * Condition: Check flagging count. */ function flag_rules_condition_threshold($flag, $entity, $number, $operator = '=') { - $count = $flag->get_count($flag->get_content_id($entity)); + $count = $flag->get_count($flag->get_entity_id($entity)); switch ($operator) { case '>' : return $count > $number; @@ -448,7 +448,7 @@ function flag_rules_condition_threshold($flag, $entity, $number, $operator = '=' * Condition: Flag is flagged. */ function flag_rules_condition_flagged($flag, $entity, $account) { - return $flag->is_flagged($flag->get_content_id($entity), $account->uid); + return $flag->is_flagged($flag->get_entity_id($entity), $account->uid); } /** diff --git a/flag.tokens.inc b/flag.tokens.inc index 4fd4e99..711da1c 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -163,10 +163,10 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr $flag_count_token = 'flag-' . str_replace('_', '-', $flag->name) . '-count'; $flag_link_token = 'flag-' . str_replace('_', '-', $flag->name) . '-link'; if ($name == $flag_count_token) { - $replacements[$original] = $flag->get_count($flag->get_content_id($object)); + $replacements[$original] = $flag->get_count($flag->get_entity_id($object)); } elseif ($name == $flag_link_token) { - $replacements[$original] = flag_create_link($flag->name, $flag->get_content_id($object)); + $replacements[$original] = flag_create_link($flag->name, $flag->get_entity_id($object)); } } } diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 8bc3d32..892c5f0 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -69,7 +69,7 @@ class flag_comment extends flag_entity { return $access; } - function get_content_id($comment) { + function get_entity_id($comment) { // Store the comment object in the static cache, to avoid getting it // again unneedlessly. $this->remember_content($comment->cid, $comment); diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 8ae3b3d..153e1ea 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -84,7 +84,7 @@ class flag_entity extends flag_flag { /** * Returns the entity id, if it already exists. */ - function get_content_id($entity) { + function get_entity_id($entity) { $entity_info = entity_get_info($this->entity_type); if ($entity && isset($entity->{$entity_info['entity keys']['id']})) { return $entity->{$entity_info['entity keys']['id']}; @@ -127,7 +127,7 @@ class flag_entity extends flag_flag { $flag_action = parent::get_flag_action($entity_id); $entity = $this->fetch_content($entity_id); $flag_action->content_title = entity_label($this->entity_type, $entity); - $flag_action->content_url = _flag_url($this->entity_type . '/' . $this->get_content_id($entity)); + $flag_action->content_url = _flag_url($this->entity_type . '/' . $this->get_entity_id($entity)); return $flag_action; } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index dcfa732..2cbe936 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -473,7 +473,7 @@ class flag_flag { * * @abstract */ - function get_content_id($content) { + function get_entity_id($content) { return NULL; } From de0e44695d4d68a00edcbd54ed9c443d7670dc9b Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 20:30:22 +0100 Subject: [PATCH 113/629] Changed method applies_to_content_id() to applies_to_entity_id(). --- includes/flag/flag_comment.inc | 2 +- includes/flag/flag_flag.inc | 6 +++--- includes/flag/flag_node.inc | 2 +- .../views/flag_plugin_argument_validate_flaggability.inc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 892c5f0..ee1acec 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -54,7 +54,7 @@ class flag_comment extends flag_entity { $access = array(); // Ensure node types are granted access. This avoids a - // node_load() on every type, usually done by applies_to_content_id(). + // node_load() on every type, usually done by applies_to_entity_id(). $query = db_select('comment', 'c'); $query->innerJoin('node', 'n', 'c.nid = n.nid'); $result = $query diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 2cbe936..ddf5080 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -301,7 +301,7 @@ class flag_flag { * applies_to_content_object(). If you already have the object, don't call * this function: call applies_to_content_object() directly. */ - function applies_to_content_id($entity_id) { + function applies_to_entity_id($entity_id) { return $this->applies_to_content_object($this->fetch_content($entity_id)); } @@ -355,7 +355,7 @@ class flag_flag { $account = $GLOBALS['user']; } - if (isset($entity_id) && !$this->applies_to_content_id($entity_id)) { + if (isset($entity_id) && !$this->applies_to_entity_id($entity_id)) { // Flag does not apply to this content. return FALSE; } @@ -531,7 +531,7 @@ class flag_flag { else { // We are skipping permission checks. However, at a minimum we must make // sure the flag applies to this content type: - if (!$this->applies_to_content_id($entity_id)) { + if (!$this->applies_to_entity_id($entity_id)) { return FALSE; } } diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index c900220..7a5dd13 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -87,7 +87,7 @@ class flag_node extends flag_entity { $access = array(); // Ensure that only flaggable node types are granted access. This avoids a - // node_load() on every type, usually done by applies_to_content_id(). + // node_load() on every type, usually done by applies_to_entity_id(). $result = db_select('node', 'n')->fields('n', array('nid')) ->condition('nid', array_keys($entity_ids), 'IN') ->condition('type', $this->types, 'NOT IN') diff --git a/includes/views/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc index a361458..22b651d 100644 --- a/includes/views/flag_plugin_argument_validate_flaggability.inc +++ b/includes/views/flag_plugin_argument_validate_flaggability.inc @@ -206,7 +206,7 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v // function test_flaggable($ids, $flag) { - return array_filter($ids, array($flag, 'applies_to_content_id')); + return array_filter($ids, array($flag, 'applies_to_entity_id')); } function test_flagged($ids, $flag) { From 8b0c9ba62fae9a7b549731e51089fba1fa269002 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 20:35:49 +0100 Subject: [PATCH 114/629] Changed database column 'content_id' to 'entity_id' on all tables. Replaced s/'content_id'/'entity_id'/, except in update functions and Views handler flag_handler_argument_content_id. --- flag.install | 14 ++--- flag.module | 54 +++++++++---------- flag.rules.inc | 2 +- flag.tokens.inc | 2 +- includes/flag/flag_flag.inc | 22 ++++---- includes/views/flag.views.inc | 9 ++-- includes/views/flag_handler_field_ops.inc | 12 ++--- ..._plugin_argument_validate_flaggability.inc | 8 +-- 8 files changed, 63 insertions(+), 60 deletions(-) diff --git a/flag.install b/flag.install index c10a80e..19fbd90 100644 --- a/flag.install +++ b/flag.install @@ -166,7 +166,7 @@ function flag_schema() { 'not null' => TRUE, 'default' => '', ), - 'content_id' => array( + 'entity_id' => array( 'description' => 'The unique ID of the content, such as either the {cid}, {uid}, or {nid}.', 'type' => 'int', 'unsigned' => TRUE, @@ -198,12 +198,12 @@ function flag_schema() { ), 'primary key' => array('fcid'), 'unique keys' => array( - 'fid_content_id_uid_sid' => array('fid', 'content_id', 'uid', 'sid'), + 'fid_entity_id_uid_sid' => array('fid', 'entity_id', 'uid', 'sid'), ), 'indexes' => array( 'entity_type_uid_sid' => array('entity_type', 'uid', 'sid'), - 'entity_type_content_id_uid_sid' => array('entity_type', 'content_id', 'uid', 'sid'), - 'content_id_fid' => array('content_id', 'fid'), + 'entity_type_entity_id_uid_sid' => array('entity_type', 'entity_id', 'uid', 'sid'), + 'entity_id_fid' => array('entity_id', 'fid'), ), ); @@ -248,7 +248,7 @@ function flag_schema() { 'not null' => TRUE, 'default' => '', ), - 'content_id' => array( + 'entity_id' => array( 'description' => 'The unique ID of the content, usually either the {cid}, {uid}, or {nid}.', 'type' => 'int', 'unsigned' => TRUE, @@ -273,10 +273,10 @@ function flag_schema() { 'disp-size' => 11, ) ), - 'primary key' => array('fid', 'content_id'), + 'primary key' => array('fid', 'entity_id'), 'indexes' => array( 'fid_entity_type' => array('fid', 'entity_type'), - 'entity_type_content_id' => array('entity_type', 'content_id'), + 'entity_type_entity_id' => array('entity_type', 'entity_id'), 'fid_count' => array('fid', 'count'), 'fid_last_updated' => array('fid', 'last_updated'), ), diff --git a/flag.module b/flag.module index ce5a274..64c4ccf 100644 --- a/flag.module +++ b/flag.module @@ -800,13 +800,13 @@ function flag_node_translation_change($node) { $entity_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid']; foreach (flag_get_flags('node') as $flag) { if ($flag->i18n) { - db_update('flagging')->fields(array('content_id' => $entity_id)) + db_update('flagging')->fields(array('entity_id' => $entity_id)) ->condition('fid', $flag->fid) - ->condition('content_id', $node->translation_change['old_tnid']) + ->condition('entity_id', $node->translation_change['old_tnid']) ->execute(); - db_update('flag_counts')->fields(array('content_id' => $entity_id)) + db_update('flag_counts')->fields(array('entity_id' => $entity_id)) ->condition('fid', $flag->fid) - ->condition('content_id', $node->translation_change['old_tnid']) + ->condition('entity_id', $node->translation_change['old_tnid']) ->execute(); } } @@ -826,10 +826,10 @@ function flag_node_translation_change($node) { function _flag_content_delete($entity_type, $entity_id, $fid = NULL) { $query_content = db_delete('flagging') ->condition('entity_type', $entity_type) - ->condition('content_id', $entity_id); + ->condition('entity_id', $entity_id); $query_counts = db_delete('flag_counts') ->condition('entity_type', $entity_type) - ->condition('content_id', $entity_id); + ->condition('entity_id', $entity_id); if (isset($fid)) { $query_content->condition('fid', $fid); $query_counts->condition('fid', $fid); @@ -847,7 +847,7 @@ function flag_user_login(&$edit, &$account) { // Get a list of flagging IDs that will be moved over. $duplicate_flaggings = array(); $flaggings = db_select('flagging', 'fc') - ->fields('fc', array('fcid', 'fid', 'content_id')) + ->fields('fc', array('fcid', 'fid', 'entity_id')) ->condition('uid', 0) ->condition('sid', $sid) ->execute() @@ -878,7 +878,7 @@ function flag_user_login(&$edit, &$account) { $anonymous_user = drupal_anonymous_user(); foreach ($duplicate_flaggings as $fcid => $flagging) { $flag = flag_get_flag(NULL, $flagging['fid']); - $flag->flag('unflag', $flagging['content_id'], $anonymous_user, TRUE); + $flag->flag('unflag', $flagging['entity_id'], $anonymous_user, TRUE); } // Clean up anonymous cookies. @@ -906,9 +906,9 @@ function flag_user_delete($account) { function flag_user_account_removal($account) { // Remove flags by this user. $query = db_select('flagging', 'fc'); - $query->leftJoin('flag_counts', 'c', 'fc.content_id = c.content_id AND fc.entity_type = c.entity_type'); + $query->leftJoin('flag_counts', 'c', 'fc.entity_id = c.entity_id AND fc.entity_type = c.entity_type'); $result = $query - ->fields('fc', array('fid', 'content_id')) + ->fields('fc', array('fid', 'entity_id')) ->fields('c', array('count')) ->condition('fc.uid', $account->uid) ->execute(); @@ -922,13 +922,13 @@ function flag_user_account_removal($account) { 'count' => $flag_data->count, )) ->condition('fid', $flag_data->fid) - ->condition('content_id', $flag_data->content_id) + ->condition('entity_id', $flag_data->entity_id) ->execute(); } elseif ($flag_data->count == 0) { db_delete('flag_counts') ->condition('fid', $flag_data->fid) - ->condition('content_id', $flag_data->content_id) + ->condition('entity_id', $flag_data->entity_id) ->execute(); } } @@ -1114,7 +1114,7 @@ function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { '#type' => 'value', '#value' => $flag->name, ); - $form['content_id'] = array( + $form['entity_id'] = array( '#type' => 'value', '#value' => $entity_id, ); @@ -1145,7 +1145,7 @@ function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { function flag_confirm_submit(&$form, &$form_state) { $action = $form_state['values']['action']; $flag_name = $form_state['values']['flag_name']; - $entity_id = $form_state['values']['content_id']; + $entity_id = $form_state['values']['entity_id']; $flag = flag_get_flag($flag_name); @@ -1360,7 +1360,7 @@ function flag_trim_flag($flag, $account, $cutoff_size) { $i = 1; foreach ($result as $row) { if ($i++ > $cutoff_size) { - flag('unflag', $flag->name, $row->content_id, $account); + flag('unflag', $flag->name, $row->entity_id, $account); } } } @@ -1380,7 +1380,7 @@ function flag_reset_flag($flag, $entity_id = NULL) { ->condition('fid', $flag->fid); if ($entity_id) { - $query->condition('content_id', $entity_id); + $query->condition('entity_id', $entity_id); } $result = $query->execute()->fetchAllAssoc('fcid', PDO::FETCH_ASSOC); @@ -1394,8 +1394,8 @@ function flag_reset_flag($flag, $entity_id = NULL) { // Update the flag_counts table. $count_query = db_delete('flag_counts')->condition('fid', $flag->fid); if ($entity_id) { - $query->condition('content_id', $entity_id); - $count_query->condition('content_id', $entity_id); + $query->condition('entity_id', $entity_id); + $count_query->condition('entity_id', $entity_id); } $count_query->execute(); return $query->execute(); @@ -1494,7 +1494,7 @@ function flag_theme() { return array( 'flag' => array( - 'variables' => array('flag' => NULL, 'action' => NULL, 'content_id' => NULL, 'after_flagging' => FALSE), + 'variables' => array('flag' => NULL, 'action' => NULL, 'entity_id' => NULL, 'after_flagging' => FALSE), 'template' => 'flag', 'pattern' => 'flag__', 'path' => $path, @@ -1541,7 +1541,7 @@ function template_preprocess_flag(&$variables) { // Some typing shotcuts: $flag =& $variables['flag']; $action = $variables['action']; - $entity_id = $variables['content_id']; + $entity_id = $variables['entity_id']; $flag_css_name = str_replace('_', '-', $flag->name); // Generate the link URL. @@ -1690,7 +1690,7 @@ function flag_get_counts($entity_type, $entity_id, $reset = FALSE) { ->fields('f', array('name')) ->fields('fc', array('count')) ->condition('fc.entity_type', $entity_type) - ->condition('fc.content_id', $entity_id) + ->condition('fc.entity_id', $entity_id) ->execute(); foreach ($result as $row) { $counts[$entity_type][$entity_id][$row->name] = $row->count; @@ -1950,7 +1950,7 @@ function flag_get_flagged_content($flag_name) { */ function flag_get_entity_id($fcid) { return db_select('flagging', 'fc') - ->fields('fc', array('content_id')) + ->fields('fc', array('entity_id')) ->condition('fcid', $fcid) ->execute() ->fetchField(); @@ -1977,10 +1977,10 @@ function flag_get_entity_id($fcid) { * @return $flags * If returning a single item's flags (that is, when $entity_id isn't NULL), * an array of the structure - * [flag_name] => (fcid => [fcid], uid => [uid], content_id => [content_id], timestamp => [timestamp], ...) + * [flag_name] => (fcid => [fcid], uid => [uid], entity_id => [entity_id], timestamp => [timestamp], ...) * * If returning all items' flags, an array of arrays for each flag: - * [flag_name] => [content_id] => Object from above. + * [flag_name] => [entity_id] => Object from above. * */ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) { @@ -2003,7 +2003,7 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid $result = db_select('flagging', 'fc') ->fields('fc') ->condition('entity_type', $entity_type) - ->condition('content_id', $entity_id) + ->condition('entity_id', $entity_id) ->condition(db_or() ->condition('uid', $uid) ->condition('uid', 0) @@ -2032,7 +2032,7 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid ->condition('sid', $sid) ->execute(); foreach ($result as $flag_content) { - $flagged_content[$uid][$sid][$entity_type]['all'][$flag_names[$flag_content->fid]][$flag_content->content_id] = $flag_content; + $flagged_content[$uid][$sid][$entity_type]['all'][$flag_names[$flag_content->fid]][$flag_content->entity_id] = $flag_content; } } return $flagged_content[$uid][$sid][$entity_type]['all']; @@ -2064,7 +2064,7 @@ function flag_get_content_flags($entity_type, $entity_id, $flag_name = NULL) { $result = db_select('flagging', 'fc') ->fields('fc') ->condition('entity_type', $entity_type) - ->condition('content_id', $entity_id) + ->condition('entity_id', $entity_id) ->orderBy('timestamp', 'DESC') ->execute(); foreach ($result as $flag_content) { diff --git a/flag.rules.inc b/flag.rules.inc index e03c9ab..2b98f74 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -337,7 +337,7 @@ function flag_rules_action_fetch_users($flag, $entity) { */ function flag_rules_action_fetch_entity_by_user($flag, $user) { $result = db_select('flagging', 'fc') - ->fields('fc', array('content_id')) + ->fields('fc', array('entity_id')) ->condition('entity_type', $flag->entity_type) ->condition('uid', $user->uid) ->condition('fid', $flag->fid) diff --git a/flag.tokens.inc b/flag.tokens.inc index 711da1c..e967836 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -146,7 +146,7 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr $replacements[$original] = $action->entity_type; break; case 'content-id': - $replacements[$original] = $action->content_id; + $replacements[$original] = $action->entity_id; break; case 'count': $replacements[$original] = $action->count; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index ddf5080..7bd90f0 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -656,13 +656,13 @@ class flag_flag { * @return stdClass * The returned object has at least the 'flag_name' property set, which * enables Field API to figure out the bundle, but it's your responsibility - * to eventually populate 'content_id' and 'fcid'. + * to eventually populate 'entity_id' and 'fcid'. */ function new_flagging($entity_id = NULL, $uid = NULL, $sid = NULL) { return (object) array( 'fcid' => NULL, 'flag_name' => $this->name, - 'content_id' => $entity_id, + 'entity_id' => $entity_id, 'uid' => $uid, 'sid' => $sid, ); @@ -738,7 +738,7 @@ class flag_flag { ->condition('fid', $this->fid) ->condition('uid', $uid) ->condition('sid', $sid) - ->condition('content_id', $entity_id) + ->condition('entity_id', $entity_id) ->execute() ->fetchField(); } @@ -759,7 +759,7 @@ class flag_flag { ->fields(array( 'fid' => $this->fid, 'entity_type' => $this->entity_type, - 'content_id' => $entity_id, + 'entity_id' => $entity_id, 'uid' => $uid, 'sid' => $sid, 'timestamp' => REQUEST_TIME, @@ -787,7 +787,7 @@ class flag_flag { ->condition('fid', $this->fid) ->condition('uid', $uid) ->condition('sid', $sid) - ->condition('content_id', $entity_id) + ->condition('entity_id', $entity_id) ->execute() ->fetchField(); if ($fcid) { @@ -811,7 +811,7 @@ class flag_flag { db_merge('flag_counts') ->key(array( 'fid' => $this->fid, - 'content_id' => $entity_id, + 'entity_id' => $entity_id, )) ->fields(array( 'entity_type' => $this->entity_type, @@ -840,7 +840,7 @@ class flag_flag { // Done before the db_update() to prevent out-of-bounds errors on "count". db_delete('flag_counts') ->condition('fid', $this->fid) - ->condition('content_id', $entity_id) + ->condition('entity_id', $entity_id) ->condition('count', $number, '<=') ->execute(); @@ -851,7 +851,7 @@ class flag_flag { 'last_updated' => REQUEST_TIME, )) ->condition('fid', $this->fid) - ->condition('content_id', $entity_id) + ->condition('entity_id', $entity_id) ->execute(); } @@ -988,7 +988,7 @@ class flag_flag { $flag_action = new stdClass(); $flag_action->flag = $this->name; $flag_action->entity_type = $this->entity_type; - $flag_action->content_id = $entity_id; + $flag_action->entity_id = $entity_id; return $flag_action; } @@ -1267,12 +1267,12 @@ class flag_flag { } if (!isset($js_added[$this->name . '_' . $entity_id])) { $js_added[$this->name . '_' . $entity_id] = TRUE; - $js_template = theme($this->theme_suggestions(), array('flag' => $this, 'action' => $js_action, 'content_id' => $entity_id, 'after_flagging' => $after_flagging)); + $js_template = theme($this->theme_suggestions(), array('flag' => $this, 'action' => $js_action, 'entity_id' => $entity_id, 'after_flagging' => $after_flagging)); drupal_add_js(array('flag' => array('templates' => array($this->name . '_' . $entity_id => $js_template))), 'setting'); } } - return theme($this->theme_suggestions(), array('flag' => $this, 'action' => $action, 'content_id' => $entity_id, 'after_flagging' => $after_flagging)); + return theme($this->theme_suggestions(), array('flag' => $this, 'action' => $action, 'entity_id' => $entity_id, 'after_flagging' => $after_flagging)); } /** diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index 840c3cb..3c84ea7 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -41,6 +41,9 @@ function flag_views_data() { // Notify views from flag 2.x of our changes to views data. // @see flag_update_7301(). $data['flag_content']['moved to'] = 'flagging'; + // @see flag_update_7303(). + $data['flag_content']['content_id']['moved to'] = array('flagging', 'entity_id'); + $data['flagging']['uid'] = array( 'title' => t('User uid'), 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), @@ -81,7 +84,7 @@ function flag_views_data() { ); // Argument for content ID, used for "Who's flagged this" views. - $data['flagging']['content_id'] = array( + $data['flagging']['entity_id'] = array( 'title' => t('Content ID'), 'help' => t('The unique ID of the object that has been flagged.'), 'argument' => array( @@ -168,7 +171,7 @@ function flag_views_data_alter(&$data) { 'handler' => 'flag_handler_relationship_content', 'label' => t('flag'), 'base' => 'flagging', - 'base field' => 'content_id', + 'base field' => 'entity_id', 'relationship field' => $info['join field'], ), ); @@ -183,7 +186,7 @@ function flag_views_data_alter(&$data) { 'handler' => 'flag_handler_relationship_counts', 'label' => t('counter'), 'base' => 'flag_counts', - 'base field' => 'content_id', + 'base field' => 'entity_id', 'relationship field' => $info['join field'], ), ); diff --git a/includes/views/flag_handler_field_ops.inc b/includes/views/flag_handler_field_ops.inc index 52ec38f..7203908 100644 --- a/includes/views/flag_handler_field_ops.inc +++ b/includes/views/flag_handler_field_ops.inc @@ -75,7 +75,7 @@ class flag_handler_field_ops extends views_handler_field { // our loaded table because it doesn't always reflect the user browsing the // page. So we explicitly add the flagging table to find this out. $join = new views_join(); - $join->construct('flagging', $info['views table'], $info['join field'], 'content_id'); + $join->construct('flagging', $info['views table'], $info['join field'], 'entity_id'); $join->extra[] = array( 'field' => 'fid', 'value' => $flag->fid, @@ -94,14 +94,14 @@ class flag_handler_field_ops extends views_handler_field { ); } $flag_table = $this->query->add_table('flagging', $parent, $join); - $this->aliases['is_flagged'] = $this->query->add_field($flag_table, 'content_id'); + $this->aliases['is_flagged'] = $this->query->add_field($flag_table, 'entity_id'); // Next, find out the content ID. We can't add_field() on this table - // (flagging), because its content_id may be NULL (in case no user has + // (flagging), because its entity_id may be NULL (in case no user has // flagged this content, and it's a LEFT JOIN). So we reach to the parent // relationship and add_field() *its* content ID column. $left_table = $this->view->relationship[$this->options['relationship']]->table_alias; - $this->aliases['content_id'] = $this->query->add_field($left_table, $info['join field']); + $this->aliases['entity_id'] = $this->query->add_field($left_table, $info['join field']); } /** @@ -116,7 +116,7 @@ class flag_handler_field_ops extends views_handler_field { $ids = array(); foreach ($values as $row) { - $entity_id = $row->{$this->aliases['content_id']}; + $entity_id = $row->{$this->aliases['entity_id']}; $is_flagged = $row->{$this->aliases['is_flagged']}; if (isset($entity_id)) { $ids[$entity_id] = $is_flagged ? 'unflag' : 'flag'; @@ -130,7 +130,7 @@ class flag_handler_field_ops extends views_handler_field { return t('Missing flag'); // get_flag() itself will print a more detailed message. } - $entity_id = $values->{$this->aliases['content_id']}; + $entity_id = $values->{$this->aliases['entity_id']}; $is_flagged = $values->{$this->aliases['is_flagged']}; if (empty($this->flag_applies[$entity_id])) { diff --git a/includes/views/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc index 22b651d..b36379c 100644 --- a/includes/views/flag_plugin_argument_validate_flaggability.inc +++ b/includes/views/flag_plugin_argument_validate_flaggability.inc @@ -212,7 +212,7 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v function test_flagged($ids, $flag) { // view_break_phrase() is guaranteed to return only integers, so this is SQL safe. $flattened_ids = implode(',', $ids); - return $this->_test_by_sql("SELECT content_id FROM {flag_counts} WHERE fid = :fid AND content_id IN ($flattened_ids) AND count > 0", array(':fid' => $flag->fid)); + return $this->_test_by_sql("SELECT entity_id FROM {flag_counts} WHERE fid = :fid AND entity_id IN ($flattened_ids) AND count > 0", array(':fid' => $flag->fid)); } function test_flagged_by_current_user($ids, $flag) { @@ -222,15 +222,15 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v return array(); } $flattened_ids = implode(',', $ids); - return $this->_test_by_sql("SELECT content_id FROM {flagging} WHERE fid = :fid AND content_id IN ($flattened_ids) AND uid = :uid", array(':fid' => $flag->fid, ':uid' => $user->uid)); + return $this->_test_by_sql("SELECT entity_id FROM {flagging} WHERE fid = :fid AND entity_id IN ($flattened_ids) AND uid = :uid", array(':fid' => $flag->fid, ':uid' => $user->uid)); } - // Helper: executes an SQL query and returns all the content_id's. + // Helper: executes an SQL query and returns all the entity_id's. function _test_by_sql($sql, $args) { $passed = array(); $result = db_query($sql, $args); foreach ($result as $row) { - $passed[] = $row->content_id; + $passed[] = $row->entity_id; } return $passed; } From b1e4fb275351454d658f57beccc20bd14cfe7154 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 20:49:42 +0100 Subject: [PATCH 115/629] Changed token names. --- flag.tokens.inc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/flag.tokens.inc b/flag.tokens.inc index e967836..2d7dcf0 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -53,21 +53,21 @@ function flag_token_info() { 'name' => t('Flag action'), 'description' => t('The flagging action taking place, either "flag" or "unflag".'), ); - $tokens['flag-action']['content-url'] = array( - 'name' => t('Flag content URL'), - 'description' => t('The URL of the content being flagged.'), + $tokens['flag-action']['entity-url'] = array( + 'name' => t('Flag entity URL'), + 'description' => t('The URL of the entity being flagged.'), ); - $tokens['flag-action']['content-title'] = array( - 'name' => t('Flag content title'), - 'description' => t('The title of the content being flagged.'), + $tokens['flag-action']['entity-title'] = array( + 'name' => t('Flag entity title'), + 'description' => t('The title of the entity being flagged.'), ); - $tokens['flag-action']['content-type'] = array( - 'name' => t('Flag content type'), - 'description' => t('The type of content being flagged, such as node or comment.'), + $tokens['flag-action']['entity-type'] = array( + 'name' => t('Flag entity type'), + 'description' => t('The type of entity being flagged, such as node or comment.'), ); - $tokens['flag-action']['content-id'] = array( - 'name' => t('Flag content ID'), - 'description' => t('The ID of content being flagged, may be a nid or cid.'), + $tokens['flag-action']['entity-id'] = array( + 'name' => t('Flag entity ID'), + 'description' => t('The ID of entity being flagged, such as a nid or cid.'), ); $tokens['flag-action']['count'] = array( 'name' => t('Flag count'), @@ -136,16 +136,16 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr case 'action': $replacements[$original] = $action->action; break; - case 'content-url': - $replacements[$original] = $sanitize ? check_url($action->content_url) : $action->content_url; + case 'entity-url': + $replacements[$original] = $sanitize ? check_url($action->entity_url) : $action->entity_url; break; - case 'content-title': - $replacements[$original] = $sanitize ? check_plain($action->content_title) : $action->content_title; + case 'entity-title': + $replacements[$original] = $sanitize ? check_plain($action->entity_title) : $action->entity_title; break; - case 'content-type': + case 'entity-type': $replacements[$original] = $action->entity_type; break; - case 'content-id': + case 'entity-id': $replacements[$original] = $action->entity_id; break; case 'count': From 2eafce31fc6d8e9b890ce7c96ff84020ec04d193 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:32:50 +0100 Subject: [PATCH 116/629] Changed 'content' to 'entity' or 'object'. --- flag.api.php | 8 +++---- flag.inc | 2 +- includes/flag/flag_flag.inc | 48 ++++++++++++++++++------------------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/flag.api.php b/flag.api.php index 0ab7e27..9a5a64c 100644 --- a/flag.api.php +++ b/flag.api.php @@ -16,8 +16,8 @@ * @return * An array whose keys are flag type names and whose values are properties of * the flag type. - * Flag type names must match the content type (in the rest of Drupal: entity - * type) a flag type works with. + * When a flag type is for an entity, the flag type name must match the entity + * type. * Properties for flag types are as follows: * - 'title': The main label of the flag type. * - 'description': A longer description shown in the UI when creating a new @@ -89,7 +89,7 @@ function hook_flag_options_alter(&$options, $flag) { * @param $flag * The flag object. * @param $entity_id - * The id of the content (aka entity) the flag is on. + * The id of the entity the flag is on. * @param $account * The user account performing the action. * @param $fcid @@ -112,7 +112,7 @@ function hook_flag($op, $flag, $entity_id, $account, $fcid) { * The user on whose behalf to test the flagging action. * * @return - * Boolean TRUE if the user is allowed to flag/unflag the given content. + * Boolean TRUE if the user is allowed to flag/unflag the given entity. * FALSE otherwise. * * @see flag_flag:access() diff --git a/flag.inc b/flag.inc index 762b486..ca71c6b 100644 --- a/flag.inc +++ b/flag.inc @@ -6,7 +6,7 @@ * Defines the flag types this module implements. * * @return - * An "array of arrays", keyed by content-types. The 'handler' slot + * An "array of arrays", keyed by object type. The 'handler' slot * should point to the PHP class implementing this flag. */ function flag_flag_definitions() { diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 7bd90f0..20e6baa 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -18,7 +18,7 @@ class flag_flag { // The database ID. Null for flags that haven't been saved to the database yet. var $fid = NULL; - // The content-type this flag works with. + // The entity type this flag works with. var $entity_type = NULL; // The flag's "machine readable" name. @@ -104,7 +104,7 @@ class flag_flag { 'flag_short' => '', // The description of the "flag this" link. 'flag_long' => '', - // Message displayed after flagging content. + // Message displayed after flagging an entity. 'flag_message' => '', // Likewise but for unflagged. 'unflag_short' => '', @@ -240,7 +240,7 @@ class flag_flag { } /** - * Fetches, possibly from some cache, a content object this flag works with. + * Fetches, possibly from some cache, an entity this flag works with. */ function fetch_content($entity_id, $object_to_remember = NULL) { static $cache = array(); @@ -255,7 +255,7 @@ class flag_flag { } /** - * Loads a content object this flag works with. + * Loads an entity this flag works with. * Derived classes must implement this. * * @abstract @@ -284,7 +284,7 @@ class flag_flag { */ /** - * Returns TRUE if the flag applies to the given content. + * Returns TRUE if the flag applies to the given entity. * * Derived classes must implement this. * @@ -295,7 +295,7 @@ class flag_flag { } /** - * Returns TRUE if the flag applies to the content with the given ID. + * Returns TRUE if the flag applies to the entity with the given ID. * * This is a convenience method that simply loads the object and calls * applies_to_content_object(). If you already have the object, don't call @@ -332,13 +332,13 @@ class flag_flag { } /** - * Determines whether the user may flag, or unflag, the given content. + * Determines whether the user may flag, or unflag, the given entity. * * This method typically should not be overridden by child classes. Instead * they should implement type_access(), which is called by this method. * * @param $entity_id - * The content ID to flag/unflag. + * The entity ID to flag/unflag. * @param $action * The action to test. Either 'flag' or 'unflag'. Leave NULL to determine * by flag status. @@ -347,7 +347,7 @@ class flag_flag { * current user. * * @return - * Boolean TRUE if the user is allowed to flag/unflag the given content. + * Boolean TRUE if the user is allowed to flag/unflag the given entity. * FALSE otherwise. */ function access($entity_id, $action = NULL, $account = NULL) { @@ -356,7 +356,7 @@ class flag_flag { } if (isset($entity_id) && !$this->applies_to_entity_id($entity_id)) { - // Flag does not apply to this content. + // Flag does not apply to this entity. return FALSE; } @@ -401,7 +401,7 @@ class flag_flag { * method. * * @param $entity_ids - * The array of content IDs to check. The keys are the content IDs, the + * The array of entity IDs to check. The keys are the entity IDs, the * values are the actions to test: either 'flag' or 'unflag'. * @param $account * Optional. The account for which the actions will be compared against. @@ -468,7 +468,7 @@ class flag_flag { */ /** - * Given a content object, returns its ID. + * Given an entity, returns its ID. * Derived classes must implement this. * * @abstract @@ -530,7 +530,7 @@ class flag_flag { } else { // We are skipping permission checks. However, at a minimum we must make - // sure the flag applies to this content type: + // sure the flag applies to this entity type: if (!$this->applies_to_entity_id($entity_id)) { return FALSE; } @@ -646,7 +646,7 @@ class flag_flag { * Construct a new, empty flagging entity object. * * @param mixed $entity_id - * The unique identifier of the content being flagged. + * The unique identifier of the object being flagged. * @param int $uid * Optional. The user id of the user doing the flagging. * @param mixed $sid @@ -669,7 +669,7 @@ class flag_flag { } /** - * Determines if a certain user has flagged this content. + * Determines if a certain user has flagged this object. * * Thanks to using a cache, inquiring several different flags about the same * item results in only one SQL query. @@ -679,7 +679,7 @@ class flag_flag { * current user will be used. * * @return - * TRUE if the content is flagged, FALSE otherwise. + * TRUE if the object is flagged, FALSE otherwise. */ function is_flagged($entity_id, $uid = NULL, $sid = NULL) { return (bool) $this->get_flagging_record($entity_id, $uid, $sid); @@ -717,7 +717,7 @@ class flag_flag { } /** - * Determines if a certain user has flagged this content. + * Determines if a certain user has flagged this object. * * You probably shouldn't call this raw private method: call the * is_flagged() method instead. @@ -727,7 +727,7 @@ class flag_flag { * bypass it. * * @return - * If the content is flagged, returns the value of the 'fcid' column. + * If the object is flagged, returns the value of the 'fcid' column. * Else, returns FALSE. * * @private @@ -744,7 +744,7 @@ class flag_flag { } /** - * A low-level method to flag content. + * A low-level method to flag an object. * * You probably shouldn't call this raw private method: call the flag() * function instead. @@ -770,13 +770,13 @@ class flag_flag { } /** - * A low-level method to unflag content. + * A low-level method to unflag an object. * * You probably shouldn't call this raw private method: call the flag() * function instead. * * @return - * If the content was flagged, returns the value of the now deleted 'fcid' + * If the object was flagged, returns the value of the now deleted 'fcid' * column. Else, returns FALSE. * * @private @@ -798,7 +798,7 @@ class flag_flag { } /** - * Increases the flag count for a piece of content. + * Increases the flag count for an object. * * @param $entity_id * For which item should the count be increased. @@ -826,7 +826,7 @@ class flag_flag { } /** - * Decreases the flag count for a piece of content. + * Decreases the flag count for an object. * * @param $entity_id * For which item should the count be descreased. @@ -1040,7 +1040,7 @@ class flag_flag { /** * Returns information needed for Views integration. E.g., the Views table - * holding the flagged content, its primary key, and various labels. See + * holding the flagged object, its primary key, and various labels. See * derived classes for examples. * * @static From 49780366c045bfb494d3b5123fad598aa4853b87 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:35:01 +0100 Subject: [PATCH 117/629] Changed fetch_content() method to fetch_entity(). --- flag.module | 4 ++-- includes/flag/flag_comment.inc | 6 +++--- includes/flag/flag_entity.inc | 6 +++--- includes/flag/flag_flag.inc | 10 +++++----- includes/flag/flag_node.inc | 4 ++-- includes/flag/flag_user.inc | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/flag.module b/flag.module index 64c4ccf..554089e 100644 --- a/flag.module +++ b/flag.module @@ -1197,7 +1197,7 @@ function flag_flag($action, $flag, $entity_id, $account) { // We add to the $context all the objects we know about: $context = array_merge($flag->get_relevant_action_objects($entity_id), $context); // The primary object the actions work on. - $object = $flag->fetch_content($entity_id); + $object = $flag->fetch_entity($entity_id); // Generic "all flags" actions. foreach (trigger_get_assigned_actions('flag_' . $action) as $aid => $action_info) { @@ -1259,7 +1259,7 @@ function flag_flag_access($flag, $entity_id, $action, $account) { if ($flag->entity_type == 'comment') { // For non-existent comments (such as on the comment add form), assume that // the current user is creating the content. - if (empty($entity_id) || !($comment = $flag->fetch_content($entity_id))) { + if (empty($entity_id) || !($comment = $flag->fetch_entity($entity_id))) { return $flag->access_author == 'comment_others' ? FALSE : NULL; } diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index ee1acec..d0a16fe 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -86,7 +86,7 @@ class flag_comment extends flag_entity { function replace_tokens($label, $contexts, $options, $entity_id) { if ($entity_id) { - if (($comment = $this->fetch_content($entity_id)) && ($node = node_load($comment->nid))) { + if (($comment = $this->fetch_entity($entity_id)) && ($node = node_load($comment->nid))) { $contexts['node'] = $node; $contexts['comment'] = $comment; } @@ -96,14 +96,14 @@ class flag_comment extends flag_entity { function get_flag_action($entity_id) { $flag_action = parent::get_flag_action($entity_id); - $comment = $this->fetch_content($entity_id); + $comment = $this->fetch_entity($entity_id); $flag_action->content_title = $comment->subject; $flag_action->content_url = _flag_url("comment/$comment->cid", "comment-$comment->cid"); return $flag_action; } function get_relevant_action_objects($entity_id) { - $comment = $this->fetch_content($entity_id); + $comment = $this->fetch_entity($entity_id); return array( 'comment' => $comment, 'node' => node_load($comment->nid), diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 153e1ea..8388873 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -114,7 +114,7 @@ class flag_entity extends flag_flag { * Replaces tokens. */ function replace_tokens($label, $contexts, $options, $entity_id) { - if ($entity_id && ($entity = $this->fetch_content($entity_id))) { + if ($entity_id && ($entity = $this->fetch_entity($entity_id))) { $contexts[$this->entity_type] = $entity; } return parent::replace_tokens($label, $contexts, $options, $entity_id); @@ -125,7 +125,7 @@ class flag_entity extends flag_flag { */ function get_flag_action($entity_id) { $flag_action = parent::get_flag_action($entity_id); - $entity = $this->fetch_content($entity_id); + $entity = $this->fetch_entity($entity_id); $flag_action->content_title = entity_label($this->entity_type, $entity); $flag_action->content_url = _flag_url($this->entity_type . '/' . $this->get_entity_id($entity)); return $flag_action; @@ -136,7 +136,7 @@ class flag_entity extends flag_flag { */ function get_relevant_action_objects($entity_id) { return array( - $this->entity_type => $this->fetch_content($entity_id), + $this->entity_type => $this->fetch_entity($entity_id), ); } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 20e6baa..90eae35 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -242,7 +242,7 @@ class flag_flag { /** * Fetches, possibly from some cache, an entity this flag works with. */ - function fetch_content($entity_id, $object_to_remember = NULL) { + function fetch_entity($entity_id, $object_to_remember = NULL) { static $cache = array(); if (isset($object_to_remember)) { $cache[$entity_id] = $object_to_remember; @@ -267,15 +267,15 @@ class flag_flag { } /** - * Stores some object in fetch_content()'s cache, so subsequenet calls to - * fetch_content() return it. + * Stores some object in fetch_entity()'s cache, so subsequenet calls to + * fetch_entity() return it. * * This is needed because otherwise fetch_object() loads the object from the * database (by calling _load_content()), whereas sometimes we want to fetch * an object that hasn't yet been saved to the database. See flag_nodeapi(). */ function remember_content($entity_id, $object) { - $this->fetch_content($entity_id, $object); + $this->fetch_entity($entity_id, $object); } /** @@ -302,7 +302,7 @@ class flag_flag { * this function: call applies_to_content_object() directly. */ function applies_to_entity_id($entity_id) { - return $this->applies_to_content_object($this->fetch_content($entity_id)); + return $this->applies_to_content_object($this->fetch_entity($entity_id)); } /** diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index 7a5dd13..5a61b52 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -109,7 +109,7 @@ class flag_node extends flag_entity { */ function get_translation_id($entity_id) { if ($this->i18n) { - $node = $this->fetch_content($entity_id); + $node = $this->fetch_entity($entity_id); if (!empty($node->tnid)) { $entity_id = $node->tnid; } @@ -137,7 +137,7 @@ class flag_node extends flag_entity { } function replace_tokens($label, $contexts, $options, $entity_id) { - if (is_numeric($entity_id) && ($node = $this->fetch_content($entity_id))) { + if (is_numeric($entity_id) && ($node = $this->fetch_entity($entity_id))) { $contexts['node'] = $node; } // Nodes accept the node-type as a $entity_id in the case that a new node diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc index 5185d67..5c43c31 100644 --- a/includes/flag/flag_user.inc +++ b/includes/flag/flag_user.inc @@ -86,7 +86,7 @@ class flag_user extends flag_entity { function get_flag_action($entity_id) { $flag_action = parent::get_flag_action($entity_id); - $user = $this->fetch_content($entity_id); + $user = $this->fetch_entity($entity_id); $flag_action->content_title = $user->name; $flag_action->content_url = _flag_url('user/' . $user->uid); return $flag_action; @@ -94,7 +94,7 @@ class flag_user extends flag_entity { function get_relevant_action_objects($entity_id) { return array( - 'user' => $this->fetch_content($entity_id), + 'user' => $this->fetch_entity($entity_id), ); } From 677a31bf0efa2fc92ae0bc8ef98d938a53c1a5ff Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:42:04 +0100 Subject: [PATCH 118/629] Changed applies_to_content_object() method to applies_to_entity(). --- includes/flag/flag_entity.inc | 2 +- includes/flag/flag_flag.inc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 8388873..cb098ae 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -73,7 +73,7 @@ class flag_entity extends flag_flag { /** * Checks whether the flag applies for the current entity bundle. */ - function applies_to_content_object($entity) { + function applies_to_entity($entity) { $entity_info = entity_get_info($this->entity_type); if (empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { return TRUE; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 90eae35..29fb1e5 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -290,7 +290,7 @@ class flag_flag { * * @abstract */ - function applies_to_content_object($content) { + function applies_to_entity($content) { return FALSE; } @@ -298,11 +298,11 @@ class flag_flag { * Returns TRUE if the flag applies to the entity with the given ID. * * This is a convenience method that simply loads the object and calls - * applies_to_content_object(). If you already have the object, don't call - * this function: call applies_to_content_object() directly. + * applies_to_entity(). If you already have the object, don't call + * this function: call applies_to_entity() directly. */ function applies_to_entity_id($entity_id) { - return $this->applies_to_content_object($this->fetch_entity($entity_id)); + return $this->applies_to_entity($this->fetch_entity($entity_id)); } /** From 0f3f807190c824e1fc02e7b4a1ec5ddbc37ac15f Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:57:17 +0100 Subject: [PATCH 119/629] Changed method _load_content() to _load_entity(). --- includes/flag/flag_entity.inc | 2 +- includes/flag/flag_flag.inc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index cb098ae..1f0f958 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -62,7 +62,7 @@ class flag_entity extends flag_flag { /** * Loads the entity object. */ - function _load_content($entity_id) { + function _load_entity($entity_id) { if (is_numeric($entity_id)) { $entity = entity_load($this->entity_type, array($entity_id)); return reset($entity); diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 29fb1e5..8c1020f 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -248,7 +248,7 @@ class flag_flag { $cache[$entity_id] = $object_to_remember; } if (!array_key_exists($entity_id, $cache)) { - $content = $this->_load_content($entity_id); + $content = $this->_load_entity($entity_id); $cache[$entity_id] = $content ? $content : NULL; } return $cache[$entity_id]; @@ -262,7 +262,7 @@ class flag_flag { * @private * @static */ - function _load_content($entity_id) { + function _load_entity($entity_id) { return NULL; } @@ -271,7 +271,7 @@ class flag_flag { * fetch_entity() return it. * * This is needed because otherwise fetch_object() loads the object from the - * database (by calling _load_content()), whereas sometimes we want to fetch + * database (by calling _load_entity()), whereas sometimes we want to fetch * an object that hasn't yet been saved to the database. See flag_nodeapi(). */ function remember_content($entity_id, $object) { From 7e8ae7a1f4c9ba72d9d0c37aeb9bd300c9504354 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:47:11 +0100 Subject: [PATCH 120/629] Changed remember_content() method to remember_entity(). --- flag.module | 2 +- includes/flag/flag_comment.inc | 2 +- includes/flag/flag_flag.inc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flag.module b/flag.module index 554089e..a15ee07 100644 --- a/flag.module +++ b/flag.module @@ -750,7 +750,7 @@ function flag_node_save($node) { // Flagging may trigger actions. We want actions to get the current // node, not a stale database-loaded one: if (!$remembered) { - $flag->remember_content($node->nid, $node); + $flag->remember_entity($node->nid, $node); // Actions may modify a node, and we don't want to overwrite this // modification: $remembered = TRUE; diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index d0a16fe..4bf46c3 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -72,7 +72,7 @@ class flag_comment extends flag_entity { function get_entity_id($comment) { // Store the comment object in the static cache, to avoid getting it // again unneedlessly. - $this->remember_content($comment->cid, $comment); + $this->remember_entity($comment->cid, $comment); return $comment->cid; } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 8c1020f..90390f5 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -274,7 +274,7 @@ class flag_flag { * database (by calling _load_entity()), whereas sometimes we want to fetch * an object that hasn't yet been saved to the database. See flag_nodeapi(). */ - function remember_content($entity_id, $object) { + function remember_entity($entity_id, $object) { $this->fetch_entity($entity_id, $object); } From d9e97571a2a7f87522067fc99c5dab4ac89e2f8e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:47:44 +0100 Subject: [PATCH 121/629] Removed documentation note on 6.x era terminology. --- flag.module | 9 --------- 1 file changed, 9 deletions(-) diff --git a/flag.module b/flag.module index a15ee07..fdc47d7 100644 --- a/flag.module +++ b/flag.module @@ -3,15 +3,6 @@ /** * @file * The Flag module. - * - * A note on terminology: due to the 7.x-2.x branch of flag being a reasonably - * straight port of 6.x-2.x, the Drupal 6 term 'content type' persists in - * function names, database fields, and variables. - * Thus: - * 'content type' -> 'entity type' (though not exclusively, as a flag type - * may be defined for any kind of object) - * 'content' -> 'entity' - * 'sub-type' -> 'bundle' ('type' is also used sometimes!) */ define('FLAG_API_VERSION', 2); From 65fe08862ff7afd1531657ca4b4cebedee0f026d Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:49:05 +0100 Subject: [PATCH 122/629] Changed use of variable $content to $entity. --- includes/flag/flag_flag.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 90390f5..701d1cf 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -248,8 +248,8 @@ class flag_flag { $cache[$entity_id] = $object_to_remember; } if (!array_key_exists($entity_id, $cache)) { - $content = $this->_load_entity($entity_id); - $cache[$entity_id] = $content ? $content : NULL; + $entity = $this->_load_entity($entity_id); + $cache[$entity_id] = $entity ? $entity : NULL; } return $cache[$entity_id]; } @@ -290,7 +290,7 @@ class flag_flag { * * @abstract */ - function applies_to_entity($content) { + function applies_to_entity($entity) { return FALSE; } @@ -473,7 +473,7 @@ class flag_flag { * * @abstract */ - function get_entity_id($content) { + function get_entity_id($entity) { return NULL; } From 8c6a7d68932c9ed02599b94a7a764acfb3243417 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:50:14 +0100 Subject: [PATCH 123/629] Changed use of variable $content_access to $entity_access. --- includes/flag/flag_flag.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 701d1cf..5fe6d26 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -425,9 +425,9 @@ class flag_flag { // Check for additional access rules provided by sub-classes. $child_access = $this->type_access_multiple($entity_ids, $account); if (isset($child_access)) { - foreach ($child_access as $entity_id => $content_access) { - if (isset($content_access)) { - $access[$entity_id] = $content_access; + foreach ($child_access as $entity_id => $entity_access) { + if (isset($entity_access)) { + $access[$entity_id] = $entity_access; } } } @@ -435,9 +435,9 @@ class flag_flag { // Merge in module-defined access. foreach (module_implements('flag_access_multiple') as $module) { $module_access = module_invoke($module, 'flag_access_multiple', $this, $entity_ids, $account); - foreach ($module_access as $entity_id => $content_access) { - if (isset($content_access)) { - $access[$entity_id] = $content_access; + foreach ($module_access as $entity_id => $entity_access) { + if (isset($entity_access)) { + $access[$entity_id] = $entity_access; } } } From 8f14df99d5c71cc6f5ae1be125052667405e8d4e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:51:10 +0100 Subject: [PATCH 124/629] Changed module description. --- flag.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.info b/flag.info index a5c4055..7d6be45 100644 --- a/flag.info +++ b/flag.info @@ -1,5 +1,5 @@ name = Flag -description = Create customized flags that users can set on content. +description = Create customized flags that users can set on entities. core = 7.x package = Flags configure = admin/structure/flags From 7460b44b926e699eb04861d825a7afe3314d94ce Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 29 Jul 2012 22:59:08 +0100 Subject: [PATCH 125/629] Changed UI strings for actions. --- includes/flag.actions.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/flag.actions.inc b/includes/flag.actions.inc index 5b6bdf0..0ec6ab3 100644 --- a/includes/flag.actions.inc +++ b/includes/flag.actions.inc @@ -12,10 +12,10 @@ function flag_trigger_info() { $hooks = array( 'flag' => array( 'flag_flag' => array( - 'label' => t('Content has been flagged with any flag'), + 'label' => t('Object has been flagged with any flag'), ), 'flag_unflag' => array( - 'label' => t('Content has been unflagged with any flag') + 'label' => t('Object has been unflagged with any flag') ), ), ); From e0c2ba8c1e2e5b1af9514bcd7c2c2d20287f0461 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:11:52 +0100 Subject: [PATCH 126/629] Changed comment. --- includes/flag.actions.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.actions.inc b/includes/flag.actions.inc index 0ec6ab3..f414431 100644 --- a/includes/flag.actions.inc +++ b/includes/flag.actions.inc @@ -180,7 +180,7 @@ function flag_user_action_submit($form, $form_state) { * @param $context * The current action context. * @param $entity_type - * The content type applicable to this action, such as "node" or "comment". + * The entity type applicable to this action, such as "node" or "comment". */ function flag_action_form($context, $entity_type) { $form = array(); From f3e9108248fdb860a023ce184a1573c358f56dbd Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:27:15 +0100 Subject: [PATCH 127/629] Changed comments to use 'entity' instead of 'content'. --- flag.module | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/flag.module b/flag.module index fdc47d7..f11652f 100644 --- a/flag.module +++ b/flag.module @@ -327,7 +327,7 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { } global $user; - // Get all possible flags for this content-type. + // Get all possible flags for this entity type. $flags = flag_get_flags($type); foreach ($flags as $flag) { @@ -339,7 +339,7 @@ function flag_link($type, $object = NULL, $teaser = FALSE) { } if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this - // content. The link is not skipped if the user has "flag" access but + // entity. The link is not skipped if the user has "flag" access but // not "unflag" access (this way the unflag denied message is shown). continue; } @@ -480,7 +480,7 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la $id = NULL; } - // Get all possible flags for this content-type. + // Get all possible flags for this entity type. $flags = flag_get_flags($entity_type); // Filter out flags which need to be included on the node form. @@ -671,7 +671,7 @@ function flag_contextual_links_view_alter(&$element, $items) { if (isset($element['#element']['#node']->nid)) { $node = $element['#element']['#node']; - // Get all possible flags for this content-type. + // Get all possible flags for this entity type. $flags = flag_get_flags('node'); foreach ($flags as $name => $flag) { @@ -682,7 +682,7 @@ function flag_contextual_links_view_alter(&$element, $items) { $entity_id = $flag->get_entity_id($node); if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this - // content. The link is not skipped if the user has "flag" access but + // object. The link is not skipped if the user has "flag" access but // not "unflag" access (this way the unflag denied message is shown). continue; } @@ -847,7 +847,7 @@ function flag_user_login(&$edit, &$account) { // Convert anonymous flaggings to their authenticated account. foreach ($flaggings as $fcid => $flagging) { // Each update is wrapped in a try block to prevent unique key errors. - // Any duplicate content that was flagged as anonoymous is deleted in the + // Any duplicate object that was flagged as anonoymous is deleted in the // subsequent db_delete() call. try { db_update('flagging') @@ -1085,14 +1085,14 @@ function flag_build_javascript_info($flag, $entity_id) { } /** - * Form for confirming the (un)flagging of a piece of content. + * Form for confirming the (un)flagging of an entity. * * @param $action * Either 'flag' or 'unflag'. * @param $flag * A loaded flag object. * @param $entity_id - * The id of the content to operate on. The type is implicit in the flag. + * The id of the entity to operate on. The type is implicit in the flag. * * @see flag_confirm_submit() */ @@ -1357,13 +1357,13 @@ function flag_trim_flag($flag, $account, $cutoff_size) { } /** - * Remove all flagged content from a flag. + * Remove all flagged entities from a flag. * * @param $flag * The flag object. * @param $entity_id - * Optional. The content ID on which all flaggings will be removed. If left - * empty, this will remove all of this flag's content. + * Optional. The entity ID on which all flaggings will be removed. If left + * empty, this will remove all of this flag's entities. */ function flag_reset_flag($flag, $entity_id = NULL) { $query = db_select('flagging', 'fc') @@ -1654,9 +1654,9 @@ function _flag_link_type_fields() { * Get flag counts for all flags on a node. * * @param $entity_type - * The content type (usually 'node'). + * The entity type (usually 'node'). * @param $entity_id - * The content ID (usually the node ID). + * The entity ID (usually the node ID). * @param $reset * Reset the internal cache and execute the SQL query another time. * @@ -1749,7 +1749,7 @@ function flag_get_flag($name = NULL, $fid = NULL) { * returned. * * @param $entity_type - * Optional. The type of content for which to load the flags. Usually 'node'. + * Optional. The type of entity for which to load the flags. Usually 'node'. * @param $content_subtype * Optional. The node type for which to load the flags. * @param $account @@ -1854,10 +1854,10 @@ function _flag_compare_weight($flag1, $flag2) { /** * Utility function: Checks whether a flag applies to a certain type, and - * possibly subtype, of content. + * possibly subtype, of entity. * * @param $entity_type - * The type of content being checked, usually "node". + * The type of entity being checked, usually "node". * @param $content_subtype * The subtype (node type) being checked. * @@ -1915,10 +1915,10 @@ function flag_get_default_flags($include_disabled = FALSE) { } /** - * Get all flagged content in a flag. + * Get all flagged entities in a flag. * * @param - * The flag name for which to retrieve flagged content. + * The flag name for which to retrieve flagged entites. */ function flag_get_flagged_content($flag_name) { $return = array(); @@ -1934,10 +1934,10 @@ function flag_get_flagged_content($flag_name) { } /** - * Get content ID from a flag content ID. + * Get entity ID from a flag content ID. * * @param $fcid - * The flag content ID for which to look up the content ID. + * The flag content ID for which to look up the entity ID. */ function flag_get_entity_id($fcid) { return db_select('flagging', 'fc') @@ -1951,10 +1951,10 @@ function flag_get_entity_id($fcid) { * Find what a user has flagged, either a single node or on the entire site. * * @param $entity_type - * The type of content that will be retrieved. Usually 'node'. + * The type of entity that will be retrieved. Usually 'node'. * @param $entity_id - * Optional. The content ID to check for flagging. If none given, all - * content flagged by this user will be returned. + * Optional. The entity ID to check for flagging. If none given, all + * entities flagged by this user will be returned. * @param $uid * Optional. The user ID whose flags we're checking. If none given, the * current user will be used. @@ -2032,18 +2032,18 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid } /** - * Return a list of users who have flagged a piece of content. + * Return a list of users who have flagged an entity. * * @param $entity_type - * The type of content that will be retrieved. Usually 'node'. + * The type of entity that will be retrieved. Usually 'node'. * @param $entity_id - * The content ID to check for flagging. + * The entity ID to check for flagging. * @param $flag_name * Optional. The name of a flag if wanting a list specific to a single flag. * * @return - * If no flag name is given, an array of flagged content, keyed by the user - * ID that flagged the content. Each flagged content array is structured as + * If no flag name is given, an array of flaging data, keyed by the user + * ID that flagged the entity. Each flagging array is structured as * an array of flag information for each flag, keyed by the flag name. If * a flag name is specified, only the information for that flag is returned. */ @@ -2081,7 +2081,7 @@ function flag_get_content_flags($entity_type, $entity_id, $flag_name = NULL) { * @param $flag_name * The "machine readable" name of the flag; e.g. 'bookmarks'. * @param $entity_id - * The content ID to check for flagging. This is usually a node ID. + * The entity ID to check for flagging, for example a node ID. */ function flag_create_link($flag_name, $entity_id) { $flag = flag_get_flag($flag_name); From c34cee4dd4c491cd8f8283aca0b005461d9ab353 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:36:21 +0100 Subject: [PATCH 128/629] Changed _flag_content_delete() to _flag_entity_delete(). --- flag.module | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flag.module b/flag.module index f11652f..942fda3 100644 --- a/flag.module +++ b/flag.module @@ -762,7 +762,7 @@ function flag_entity_delete($entity, $type) { } list($id) = entity_extract_ids($type, $entity); - _flag_content_delete($type, $id); + _flag_entity_delete($type, $id); } /** @@ -774,7 +774,7 @@ function flag_node_delete($node) { // of a translation set, don't delete the flagging record. // Instead, data will be updated in hook_node_translation_change(), below. if (!$flag->i18n || empty($node->tnid)) { - _flag_content_delete('node', $node->nid, $flag->fid); + _flag_entity_delete('node', $node->nid, $flag->fid); } } } @@ -814,7 +814,7 @@ function flag_node_translation_change($node) { * @param $fid * The flag id */ -function _flag_content_delete($entity_type, $entity_id, $fid = NULL) { +function _flag_entity_delete($entity_type, $entity_id, $fid = NULL) { $query_content = db_delete('flagging') ->condition('entity_type', $entity_type) ->condition('entity_id', $entity_id); @@ -928,7 +928,7 @@ function flag_user_account_removal($account) { ->execute(); // Remove flags that have been done to this user. - _flag_content_delete('user', $account->uid); + _flag_entity_delete('user', $account->uid); } /** From f9823fe66a1857e7407c26cb323b530a730d350e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:37:34 +0100 Subject: [PATCH 129/629] Changed _flag_content_enabled() to _flag_entity_enabled(). --- flag.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 942fda3..2b7bf5b 100644 --- a/flag.module +++ b/flag.module @@ -1822,7 +1822,7 @@ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = // Filter out flags based on type and subtype. if (isset($entity_type) || isset($content_subtype)) { foreach ($filtered_flags as $name => $flag) { - if (!_flag_content_enabled($flag, $entity_type, $content_subtype)) { + if (!_flag_entity_enabled($flag, $entity_type, $content_subtype)) { unset($filtered_flags[$name]); } } @@ -1864,7 +1864,7 @@ function _flag_compare_weight($flag1, $flag2) { * @return * TRUE if the flag is enabled for this type and subtype. */ -function _flag_content_enabled($flag, $entity_type, $content_subtype = NULL) { +function _flag_entity_enabled($flag, $entity_type, $content_subtype = NULL) { $return = $flag->entity_type == $entity_type && (!isset($content_subtype) || in_array($content_subtype, $flag->types)); return $return; } From e83d5fb78b5eb6b3463d7366daf9e93d42998e1a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:39:35 +0100 Subject: [PATCH 130/629] Changed flag_get_flagged_content() to flag_get_flagged_entities(). --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 2b7bf5b..312eaad 100644 --- a/flag.module +++ b/flag.module @@ -1920,7 +1920,7 @@ function flag_get_default_flags($include_disabled = FALSE) { * @param * The flag name for which to retrieve flagged entites. */ -function flag_get_flagged_content($flag_name) { +function flag_get_flagged_entities($flag_name) { $return = array(); $flag = flag_get_flag($flag_name); $result = db_select('flagging', 'fc') From 316e3ed5963a4bd0bf2dc04fcf95723fa0c7ae8a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:41:47 +0100 Subject: [PATCH 131/629] Changed flag_get_content_flags() to flag_get_entity_flags(). --- flag.module | 2 +- includes/flag/flag_flag.inc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 312eaad..24d9279 100644 --- a/flag.module +++ b/flag.module @@ -2047,7 +2047,7 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid * an array of flag information for each flag, keyed by the flag name. If * a flag name is specified, only the information for that flag is returned. */ -function flag_get_content_flags($entity_type, $entity_id, $flag_name = NULL) { +function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { $content_flags = &drupal_static(__FUNCTION__, array()); if (!isset($content_flags[$entity_type][$entity_id])) { diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 5fe6d26..28e8956 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -540,7 +540,7 @@ class flag_flag { // wrong counts or false flaggings. flag_get_counts(NULL, NULL, TRUE); flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE); - drupal_static_reset('flag_get_content_flags'); + drupal_static_reset('flag_get_entity_flags'); // Find out which user id to use. $uid = $this->global ? 0 : $account->uid; From 4d4f0bc0b8306b045c401be32c661467942fd24f Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 30 Jul 2012 22:44:37 +0100 Subject: [PATCH 132/629] Changed name of variable in flag_get_entity_flags(). --- flag.module | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/flag.module b/flag.module index 24d9279..0604c0e 100644 --- a/flag.module +++ b/flag.module @@ -2048,9 +2048,9 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid * a flag name is specified, only the information for that flag is returned. */ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { - $content_flags = &drupal_static(__FUNCTION__, array()); + $entity_flags = &drupal_static(__FUNCTION__, array()); - if (!isset($content_flags[$entity_type][$entity_id])) { + if (!isset($entity_flags[$entity_type][$entity_id])) { $flag_names = _flag_get_flag_names(); $result = db_select('flagging', 'fc') ->fields('fc') @@ -2060,13 +2060,13 @@ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { ->execute(); foreach ($result as $flag_content) { // Build a list of flaggings for all flags by user. - $content_flags[$entity_type][$entity_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; + $entity_flags[$entity_type][$entity_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; // Build a list of flaggings for each individual flag. - $content_flags[$entity_type][$entity_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; + $entity_flags[$entity_type][$entity_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; } } - return isset($flag_name) ? $content_flags[$entity_type][$entity_id]['flags'][$flag_name] : $content_flags[$entity_type][$entity_id]['users']; + return isset($flag_name) ? $entity_flags[$entity_type][$entity_id]['flags'][$flag_name] : $entity_flags[$entity_type][$entity_id]['users']; } /** From 2a882a3b13abf47336328d464c445c5f66596ff0 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 1 Aug 2012 11:10:16 +0100 Subject: [PATCH 133/629] Changed hook_schema() descriptions. --- flag.install | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flag.install b/flag.install index 19fbd90..e114b96 100644 --- a/flag.install +++ b/flag.install @@ -143,7 +143,7 @@ function flag_schema() { ); $schema['flagging'] = array( - 'description' => 'Content that has been flagged.', + 'description' => 'Objects that have been flagged.', 'fields' => array( 'fcid' => array( 'description' => 'The unique ID for this particular tag.', @@ -152,7 +152,7 @@ function flag_schema() { 'not null' => TRUE, ), 'fid' => array( - 'description' => 'The unqiue flag ID this content has been flagged with, from {flags}.', + 'description' => 'The unique flag ID this object has been flagged with, from {flags}.', 'type' => 'int', 'size' => 'small', 'unsigned' => TRUE, @@ -160,21 +160,21 @@ function flag_schema() { 'default' => 0, ), 'entity_type' => array( - 'description' => 'The flag type, one of "node", "comment", "user".', + 'description' => 'The flag type, eg "node", "comment", "user".', 'type' => 'varchar', 'length' => '128', 'not null' => TRUE, 'default' => '', ), 'entity_id' => array( - 'description' => 'The unique ID of the content, such as either the {cid}, {uid}, or {nid}.', + 'description' => 'The unique ID of the object, such as either the {cid}, {uid}, or {nid}.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'uid' => array( - 'description' => 'The user ID by which this content was created.', + 'description' => 'The user ID by whom this object was flagged.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -257,7 +257,7 @@ function flag_schema() { 'disp-width' => '10', ), 'count' => array( - 'description' => 'The number of times this content has been flagged for this flag.', + 'description' => 'The number of times this object has been flagged for this flag.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, From ae4e50f239bdb2d48c4e658fcad92fe78e9eb77c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 1 Aug 2012 17:01:19 +0100 Subject: [PATCH 134/629] Added update 7302 to change column names on the {flag} table. --- flag.install | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/flag.install b/flag.install index e114b96..4ffba63 100644 --- a/flag.install +++ b/flag.install @@ -456,3 +456,23 @@ function flag_update_7301() { // A second cache clear appears to be required here. cache_clear_all(); } + +/** + * Rename database columns on the {flag} table. + */ +function flag_update_7302() { + // No keys or indexes are affected. + // Change field 'content_type' to 'entity_type'. + db_change_field('flag', 'content_type', 'entity_type', + // Spec of the field. Identical to our current hook_schema(): we're not + // changing anything except the name. + array( + 'description' => 'The flag type, such as one of "node", "comment", or "user".', + 'type' => 'varchar', + 'length' => '32', + 'not null' => TRUE, + 'default' => '', + ) + // No keys to re-add. + ); +} From daed24a34f52b7775fd394d43e32a503d7c36ef6 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 1 Aug 2012 17:01:38 +0100 Subject: [PATCH 135/629] Added update 7303 to change column names on the {flagging} table. --- flag.install | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/flag.install b/flag.install index 4ffba63..df4f2da 100644 --- a/flag.install +++ b/flag.install @@ -476,3 +476,69 @@ function flag_update_7302() { // No keys to re-add. ); } + +/** + * Rename database columns on the {flagging} table. + */ +function flag_update_7303() { + // Drop affected keys and indexes. + db_drop_unique_key('flagging', 'fid_content_id_uid_sid'); + db_drop_index('flagging', 'content_type_uid_sid'); + db_drop_index('flagging', 'content_type_content_id_uid_sid'); + db_drop_index('flagging', 'content_id_fid'); + + // Change field 'content_type' to 'entity_type'. + db_change_field('flagging', 'content_type', 'entity_type', + // Spec of the field. Identical to our current hook_schema(): we're not + // changing anything except the name. + array( + 'description' => 'The flag type, eg "node", "comment", "user".', + 'type' => 'varchar', + 'length' => '32', + 'not null' => TRUE, + 'default' => '', + ), + // Keys spec. Some are short-lived, as they are about to be dropped again + // and have hybrid names that refer to 'content_id' still. + array( + 'unique keys' => array( + 'fid_content_id_uid_sid' => array('fid', 'content_id', 'uid', 'sid'), + ), + 'indexes' => array( + 'entity_type_uid_sid' => array('entity_type', 'uid', 'sid'), + 'entity_type_content_id_uid_sid' => array('entity_type', 'content_id', 'uid', 'sid'), + 'content_id_fid' => array('content_id', 'fid'), + ), + ) + ); + + // Now we have to drop keys and indexes all over again! + db_drop_unique_key('flagging', 'fid_content_id_uid_sid'); + db_drop_index('flagging', 'entity_type_content_id_uid_sid'); + db_drop_index('flagging', 'content_id_fid'); + + // Change field 'content_id' to 'entity_id'. + db_change_field('flagging', 'content_id', 'entity_id', + // Spec of the field. Identical to our current hook_schema(): we're not + // changing anything except the name. + array( + 'description' => 'The unique ID of the content, such as either the {cid}, {uid}, or {nid}.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + // Keys spec. Identical to current hook_schema() now we're finished. + array( + 'unique keys' => array( + 'fid_entity_id_uid_sid' => array('fid', 'entity_id', 'uid', 'sid'), + ), + 'indexes' => array( + 'entity_type_entity_id_uid_sid' => array('entity_type', 'entity_id', 'uid', 'sid'), + 'entity_id_fid' => array('entity_id', 'fid'), + ), + ) + ); + + cache_clear_all(); +} From 8ae10f4d25a13e35e41aeda38e33fe9db72056ed Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 1 Aug 2012 17:15:16 +0100 Subject: [PATCH 136/629] Added update 7304 to change column names on the {flag_counts} table. --- flag.install | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/flag.install b/flag.install index df4f2da..09d498a 100644 --- a/flag.install +++ b/flag.install @@ -542,3 +542,58 @@ function flag_update_7303() { cache_clear_all(); } + +/** + * Rename database columns on the {flag_counts} table. + */ +function flag_update_7304() { + // Drop keys and indexes using 'content_type'. + db_drop_index('flag_counts', 'fid_content_type'); + db_drop_index('flag_counts', 'content_type_content_id'); + + // Change field 'content_type' to 'entity_type'. + db_change_field('flag_counts', 'content_type', 'entity_type', + // Spec of the field. Identical to our current hook_schema(): we're not + // changing anything except the name. + array( + 'description' => 'The flag type, usually one of "node", "comment", "user".', + 'type' => 'varchar', + 'length' => '32', + 'not null' => TRUE, + 'default' => '', + ), + // Keys spec. Some are short-lived, as they are about to be dropped again. + // Note the hybrid names refer to 'content_id' still. + array( + 'indexes' => array( + 'fid_entity_type' => array('fid', 'entity_type'), + 'entity_type_content_id' => array('entity_type', 'content_id'), + ) + ) + ); + + // Now drop keys and indexes using 'content_id'. + db_drop_primary_key('flag_counts'); + db_drop_index('flag_counts', 'entity_type_content_id'); + + // Change field 'content_id' to 'entity_id'. + db_change_field('flag_counts', 'content_id', 'entity_id', + // Spec of the field. Identical to our current hook_schema(): we're not + // changing anything except the name. + array( + 'description' => 'The unique ID of the content, usually either the {cid}, {uid}, or {nid}.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '10', + ), + // Keys spec. Identical to current hook_schema() now we're finished. + array( + 'primary key' => array('fid', 'entity_id'), + 'indexes' => array( + 'entity_type_entity_id' => array('entity_type', 'entity_id'), + ), + ) + ); +} From 9a89ca6b14c26094a95e5ac030cd2bd0d5b638b7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 1 Aug 2012 22:16:26 +0100 Subject: [PATCH 137/629] Fixed error messages on column change updates caused by schema being stale due to table name changes. --- flag.install | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 09d498a..c284e40 100644 --- a/flag.install +++ b/flag.install @@ -453,8 +453,12 @@ function flag_update_7300() { function flag_update_7301() { db_rename_table('flag_content', 'flagging'); db_rename_table('flags', 'flag'); - // A second cache clear appears to be required here. + // A second cache clear appears to be required here... cache_clear_all(); + // ...which in fact isn't enough, as the schema cache appears to need explicit + // clearing to prevent the next updates failing to get the schema for the new + // table names. + drupal_get_schema(NULL, TRUE); } /** From e63e4d0ce465d920b9be8be098a7e9b053dcd315 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 2 Aug 2012 19:46:07 +0100 Subject: [PATCH 138/629] Removed now unnecessary translation of variables in flag_field_extra_fields(). --- flag.module | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/flag.module b/flag.module index 0604c0e..b3279a9 100644 --- a/flag.module +++ b/flag.module @@ -411,12 +411,9 @@ function flag_field_extra_fields() { continue; } - // In order to make sense with this hook's structure, we use D7 lingo, hence - // some translation is required... - $entity_type = $flag->entity_type; foreach ($flag->types as $bundle_name) { if ($flag->show_on_form) { - $extra[$entity_type][$bundle_name]['form']['flag'] = array( + $extra[$flag->entity_type][$bundle_name]['form']['flag'] = array( 'label' => t('Flags'), 'description' => t('Checkboxes for toggling flags'), 'weight' => 10 From 605f690c8a3fd8df6862853868b1e24e14a3cb8b Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 3 Aug 2012 09:00:16 +0100 Subject: [PATCH 139/629] Changed database column 'fcid' to 'flagging_id' on {flagging} table. Replaced s/fcid/flagging_id/ throughout. --- flag.api.php | 4 +-- flag.install | 4 +-- flag.module | 34 +++++++++++----------- includes/flag/flag_flag.inc | 58 ++++++++++++++++++------------------- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/flag.api.php b/flag.api.php index 9a5a64c..3965317 100644 --- a/flag.api.php +++ b/flag.api.php @@ -92,10 +92,10 @@ function hook_flag_options_alter(&$options, $flag) { * The id of the entity the flag is on. * @param $account * The user account performing the action. - * @param $fcid + * @param $flagging_id * The id of the flagging in the {flagging} table. */ -function hook_flag($op, $flag, $entity_id, $account, $fcid) { +function hook_flag($op, $flag, $entity_id, $account, $flagging_id) { } diff --git a/flag.install b/flag.install index c284e40..78ecd1b 100644 --- a/flag.install +++ b/flag.install @@ -145,7 +145,7 @@ function flag_schema() { $schema['flagging'] = array( 'description' => 'Objects that have been flagged.', 'fields' => array( - 'fcid' => array( + 'flagging_id' => array( 'description' => 'The unique ID for this particular tag.', 'type' => 'serial', 'unsigned' => TRUE, @@ -196,7 +196,7 @@ function flag_schema() { 'disp-size' => 11, ) ), - 'primary key' => array('fcid'), + 'primary key' => array('flagging_id'), 'unique keys' => array( 'fid_entity_id_uid_sid' => array('fid', 'entity_id', 'uid', 'sid'), ), diff --git a/flag.module b/flag.module index b3279a9..faec809 100644 --- a/flag.module +++ b/flag.module @@ -23,7 +23,7 @@ function flag_entity_info() { 'base table' => 'flagging', 'fieldable' => TRUE, 'entity keys' => array( - 'id' => 'fcid', + 'id' => 'flagging_id', 'bundle' => 'flag_name', ), // The following tells Field UI how to extract the bundle name from a @@ -53,16 +53,16 @@ function flag_entity_info() { /** * Loads a flagging entity. * - * @param $fcid - * The 'fcid' database serial column. + * @param $flagging_id + * The 'flagging_id' database serial column. * @param $reset * Whether to reset the DrupalDefaultEntityController cache. * * @return * The entity object, or FALSE if it can't be found. */ -function flagging_load($fcid, $reset = FALSE) { - $result = entity_load('flagging', array($fcid), array(), $reset); +function flagging_load($flagging_id, $reset = FALSE) { + $result = entity_load('flagging', array($flagging_id), array(), $reset); return reset($result); } @@ -835,14 +835,14 @@ function flag_user_login(&$edit, &$account) { // Get a list of flagging IDs that will be moved over. $duplicate_flaggings = array(); $flaggings = db_select('flagging', 'fc') - ->fields('fc', array('fcid', 'fid', 'entity_id')) + ->fields('fc', array('flagging_id', 'fid', 'entity_id')) ->condition('uid', 0) ->condition('sid', $sid) ->execute() - ->fetchAllAssoc('fcid', PDO::FETCH_ASSOC); + ->fetchAllAssoc('flagging_id', PDO::FETCH_ASSOC); // Convert anonymous flaggings to their authenticated account. - foreach ($flaggings as $fcid => $flagging) { + foreach ($flaggings as $flagging_id => $flagging) { // Each update is wrapped in a try block to prevent unique key errors. // Any duplicate object that was flagged as anonoymous is deleted in the // subsequent db_delete() call. @@ -852,11 +852,11 @@ function flag_user_login(&$edit, &$account) { 'uid' => $account->uid, 'sid' => 0, )) - ->condition('fcid', $fcid) + ->condition('flagging_id', $flagging_id) ->execute(); } catch (Exception $e) { - $duplicate_flaggings[$fcid] = $flagging; + $duplicate_flaggings[$flagging_id] = $flagging; } } @@ -864,7 +864,7 @@ function flag_user_login(&$edit, &$account) { // proper unflag action here to make sure the count gets decremented again // and so that other modules can clean up their tables if needed. $anonymous_user = drupal_anonymous_user(); - foreach ($duplicate_flaggings as $fcid => $flagging) { + foreach ($duplicate_flaggings as $flagging_id => $flagging) { $flag = flag_get_flag(NULL, $flagging['fid']); $flag->flag('unflag', $flagging['entity_id'], $anonymous_user, TRUE); } @@ -1371,7 +1371,7 @@ function flag_reset_flag($flag, $entity_id = NULL) { $query->condition('entity_id', $entity_id); } - $result = $query->execute()->fetchAllAssoc('fcid', PDO::FETCH_ASSOC); + $result = $query->execute()->fetchAllAssoc('flagging_id', PDO::FETCH_ASSOC); $rows = array(); foreach ($result as $row) { $rows[] = $row; @@ -1704,7 +1704,7 @@ function flag_get_flag_counts($flag_name, $reset = FALSE) { } if (!isset($counts[$flag_name])) { $flag = flag_get_flag($flag_name); - $counts[$flag_name] = db_select('flag_counts', 'fc')->fields('fc', array('fcid')) + $counts[$flag_name] = db_select('flag_counts', 'fc')->fields('fc', array('flagging_id')) ->condition('fid', $flag->fid)->countQuery()->execute()->fetchField(); } @@ -1933,13 +1933,13 @@ function flag_get_flagged_entities($flag_name) { /** * Get entity ID from a flag content ID. * - * @param $fcid + * @param $flagging_id * The flag content ID for which to look up the entity ID. */ -function flag_get_entity_id($fcid) { +function flag_get_entity_id($flagging_id) { return db_select('flagging', 'fc') ->fields('fc', array('entity_id')) - ->condition('fcid', $fcid) + ->condition('flagging_id', $flagging_id) ->execute() ->fetchField(); } @@ -1965,7 +1965,7 @@ function flag_get_entity_id($fcid) { * @return $flags * If returning a single item's flags (that is, when $entity_id isn't NULL), * an array of the structure - * [flag_name] => (fcid => [fcid], uid => [uid], entity_id => [entity_id], timestamp => [timestamp], ...) + * [flag_name] => (flagging_id => [flagging_id], uid => [uid], entity_id => [entity_id], timestamp => [timestamp], ...) * * If returning all items' flags, an array of arrays for each flag: * [flag_name] => [entity_id] => Object from above. diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 28e8956..a440199 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -570,8 +570,8 @@ class flag_flag { // @todo: Discuss: Core wraps everything in a try { }, should we? // Perform the flagging or unflagging of this flag. - $existing_fcid = $this->_is_flagged($entity_id, $uid, $sid); - $flagged = (bool) $existing_fcid; + $existing_flagging_id = $this->_is_flagged($entity_id, $uid, $sid); + $flagged = (bool) $existing_flagging_id; if ($action == 'unflag') { if ($this->uses_anonymous_cookies()) { $this->_unflag_anonymous($entity_id); @@ -579,9 +579,9 @@ class flag_flag { if ($flagged) { // Note the order: We delete the entity before calling _unflag() to // delete the {flagging} record. - $this->_delete_flagging($existing_fcid); + $this->_delete_flagging($existing_flagging_id); $this->_unflag($entity_id, $uid, $sid); - module_invoke_all('flag', 'unflag', $this, $entity_id, $account, $existing_fcid); + module_invoke_all('flag', 'unflag', $this, $entity_id, $account, $existing_flagging_id); } } elseif ($action == 'flag') { @@ -593,12 +593,12 @@ class flag_flag { // Construct a new flagging object if we don't have one. $flagging = $this->new_flagging($entity_id, $uid, $sid); } - $fcid = $this->_flag($entity_id, $uid, $sid); + $flagging_id = $this->_flag($entity_id, $uid, $sid); // We're writing out a flagging entity even when we aren't passed one // (e.g., when flagging via JavaScript toggle links); in this case // Field API will assign the fields their default values. - $this->_insert_flagging($flagging, $entity_id, $fcid); - module_invoke_all('flag', 'flag', $this, $entity_id, $account, $fcid); + $this->_insert_flagging($flagging, $entity_id, $flagging_id); + module_invoke_all('flag', 'flag', $this, $entity_id, $account, $flagging_id); } else { // Nothing to do. Item is already flagged. @@ -623,8 +623,8 @@ class flag_flag { * operation is also accompanied by some bookkeeping (calling hooks, updating * counters) or access control. These tasks are handled by the flag() method. */ - private function _insert_flagging($flagging, $entity_id, $fcid) { - $flagging->fcid = $fcid; + private function _insert_flagging($flagging, $entity_id, $flagging_id) { + $flagging->flagging_id = $flagging_id; field_attach_presave('flagging', $flagging); field_attach_insert('flagging', $flagging); } @@ -632,13 +632,13 @@ class flag_flag { field_attach_presave('flagging', $flagging); field_attach_update('flagging', $flagging); // Update the cache. - flagging_load($flagging->fcid, TRUE); + flagging_load($flagging->flagging_id, TRUE); } - private function _delete_flagging($fcid) { - if (($flagging = flagging_load($fcid))) { + private function _delete_flagging($flagging_id) { + if (($flagging = flagging_load($flagging_id))) { field_attach_delete('flagging', $flagging); // Remove from the cache. - flagging_load($fcid, TRUE); + flagging_load($flagging_id, TRUE); } } @@ -656,11 +656,11 @@ class flag_flag { * @return stdClass * The returned object has at least the 'flag_name' property set, which * enables Field API to figure out the bundle, but it's your responsibility - * to eventually populate 'entity_id' and 'fcid'. + * to eventually populate 'entity_id' and 'flagging_id'. */ function new_flagging($entity_id = NULL, $uid = NULL, $sid = NULL) { return (object) array( - 'fcid' => NULL, + 'flagging_id' => NULL, 'flag_name' => $this->name, 'entity_id' => $entity_id, 'uid' => $uid, @@ -691,7 +691,7 @@ class flag_flag { * This method returns the "flagging record": the {flagging} record that * exists for each flagged item (for a certain user). If the item isn't * flagged, returns NULL. This method could be useful, for example, when you - * want to find out the 'fcid' or 'timestamp' values. + * want to find out the 'flagging_id' or 'timestamp' values. * * Thanks to using a cache, inquiring several different flags about the same * item results in only one SQL query. @@ -712,7 +712,7 @@ class flag_flag { */ function get_flagging($entity_id, $uid = NULL, $sid = NULL) { if (($record = $this->get_flagging_record($entity_id, $uid, $sid))) { - return flagging_load($record->fcid); + return flagging_load($record->flagging_id); } } @@ -727,14 +727,14 @@ class flag_flag { * bypass it. * * @return - * If the object is flagged, returns the value of the 'fcid' column. + * If the object is flagged, returns the value of the 'flagging_id' column. * Else, returns FALSE. * * @private */ function _is_flagged($entity_id, $uid, $sid) { return db_select('flagging', 'fc') - ->fields('fc', array('fcid')) + ->fields('fc', array('flagging_id')) ->condition('fid', $this->fid) ->condition('uid', $uid) ->condition('sid', $sid) @@ -750,12 +750,12 @@ class flag_flag { * function instead. * * @return - * The 'fcid' column of the new {flagging} record. + * The 'flagging_id' column of the new {flagging} record. * * @private */ function _flag($entity_id, $uid, $sid) { - $fcid = db_insert('flagging') + $flagging_id = db_insert('flagging') ->fields(array( 'fid' => $this->fid, 'entity_type' => $this->entity_type, @@ -766,7 +766,7 @@ class flag_flag { )) ->execute(); $this->_increase_count($entity_id); - return $fcid; + return $flagging_id; } /** @@ -776,25 +776,25 @@ class flag_flag { * function instead. * * @return - * If the object was flagged, returns the value of the now deleted 'fcid' + * If the object was flagged, returns the value of the now deleted 'flagging_id' * column. Else, returns FALSE. * * @private */ function _unflag($entity_id, $uid, $sid) { - $fcid = db_select('flagging', 'fc') - ->fields('fc', array('fcid')) + $flagging_id = db_select('flagging', 'fc') + ->fields('fc', array('flagging_id')) ->condition('fid', $this->fid) ->condition('uid', $uid) ->condition('sid', $sid) ->condition('entity_id', $entity_id) ->execute() ->fetchField(); - if ($fcid) { - db_delete('flagging')->condition('fcid', $fcid)->execute(); + if ($flagging_id) { + db_delete('flagging')->condition('flagging_id', $flagging_id)->execute(); $this->_decrease_count($entity_id); } - return $fcid; + return $flagging_id; } /** @@ -895,7 +895,7 @@ class flag_flag { if (!isset($sid)) { $sid = flag_get_sid($uid); } - return db_select('flagging', 'fc')->fields('fc', array('fcid')) + return db_select('flagging', 'fc')->fields('fc', array('flagging_id')) ->condition('fid', $this->fid)->condition('uid', $uid)->condition('sid', $sid) ->countQuery()->execute()->fetchField(); } From 3e01462489d4a04788dfa8cc4108b363c1d81935 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 4 Aug 2012 20:08:41 +0100 Subject: [PATCH 140/629] Added handling of rename of fcid to update hook. --- flag.install | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 78ecd1b..84fe1a7 100644 --- a/flag.install +++ b/flag.install @@ -532,7 +532,7 @@ function flag_update_7303() { 'not null' => TRUE, 'default' => 0, ), - // Keys spec. Identical to current hook_schema() now we're finished. + // Keys spec. Identical to current hook_schema(). array( 'unique keys' => array( 'fid_entity_id_uid_sid' => array('fid', 'entity_id', 'uid', 'sid'), @@ -544,6 +544,25 @@ function flag_update_7303() { ) ); + // Drop the primary key. + db_drop_primary_key('flagging'); + + // Change field 'fcid' to 'flagging_id'. + db_change_field('flagging', 'fcid', 'flagging_id', + // Spec of the field. Identical to our current hook_schema(): we're not + // changing anything except the name. + array( + 'description' => 'The unique ID for this particular tag.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + // Keys spec. Identical to current hook_schema(). + array( + 'primary key' => array('flagging_id'), + ) + ); + cache_clear_all(); } From 9e5c5efcf53d26090d1dc671859adb57aa38843c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 5 Aug 2012 09:41:20 +0100 Subject: [PATCH 141/629] Added workaround for http://drupal.org/node/190027: Dropping a primary key requires a temporary index to be created first. --- flag.install | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/flag.install b/flag.install index 84fe1a7..3fa1634 100644 --- a/flag.install +++ b/flag.install @@ -544,7 +544,11 @@ function flag_update_7303() { ) ); - // Drop the primary key. + // A serial field must be defined as a key, so make a temporary index on + // 'fcid' so we can safely drop the primary key. + // @see http://drupal.org/node/190027 + db_add_index('flagging', 'temp', array('fcid')); + // Drop the primary key so we can rename the field. db_drop_primary_key('flagging'); // Change field 'fcid' to 'flagging_id'. @@ -562,6 +566,8 @@ function flag_update_7303() { 'primary key' => array('flagging_id'), ) ); + // Drop our temporary index. + db_drop_index('flagging', 'temp'); cache_clear_all(); } From 5e9c4b05d5b026982cd89f1e6d35055a27ed849c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 5 Aug 2012 11:12:47 +0100 Subject: [PATCH 142/629] Renamed views handler class flag_handler_argument_content_id to flag_handler_argument_entity_id. --- flag.info | 2 +- includes/views/flag.views.inc | 2 +- ...ument_content_id.inc => flag_handler_argument_entity_id.inc} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename includes/views/{flag_handler_argument_content_id.inc => flag_handler_argument_entity_id.inc} (93%) diff --git a/flag.info b/flag.info index 7d6be45..bf64556 100644 --- a/flag.info +++ b/flag.info @@ -17,7 +17,7 @@ files[] = includes/flag.entity.inc files[] = flag.rules.inc ; Views -files[] = includes/views/flag_handler_argument_content_id.inc +files[] = includes/views/flag_handler_argument_entity_id.inc files[] = includes/views/flag_handler_field_ops.inc files[] = includes/views/flag_handler_filter_flagged.inc files[] = includes/views/flag_handler_relationships.inc diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index 3c84ea7..b4129dd 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -88,7 +88,7 @@ function flag_views_data() { 'title' => t('Content ID'), 'help' => t('The unique ID of the object that has been flagged.'), 'argument' => array( - 'handler' => 'flag_handler_argument_content_id', + 'handler' => 'flag_handler_argument_entity_id', ), ); diff --git a/includes/views/flag_handler_argument_content_id.inc b/includes/views/flag_handler_argument_entity_id.inc similarity index 93% rename from includes/views/flag_handler_argument_content_id.inc rename to includes/views/flag_handler_argument_entity_id.inc index ee18743..f5d3b1a 100644 --- a/includes/views/flag_handler_argument_content_id.inc +++ b/includes/views/flag_handler_argument_entity_id.inc @@ -10,7 +10,7 @@ * * @ingroup views */ -class flag_handler_argument_content_id extends views_handler_argument_numeric { +class flag_handler_argument_entity_id extends views_handler_argument_numeric { /** * Returns the flag object associated with our argument. From dff4206c7ebed0d48ec7bce8455f7b6670801ffa Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 8 Aug 2012 08:44:31 +0100 Subject: [PATCH 143/629] Issue #1698994 by Scyther: Moved menu callbacks to a flag.pages.inc file. --- flag.module | 156 +-------------------------------------- includes/flag.pages.inc | 160 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 154 deletions(-) create mode 100644 includes/flag.pages.inc diff --git a/flag.module b/flag.module index faec809..be13fad 100644 --- a/flag.module +++ b/flag.module @@ -188,6 +188,7 @@ function flag_menu() { 'page arguments' => array(1, 2, 3), 'access callback' => 'user_access', 'access arguments' => array('access content'), + 'file' => 'includes/flag.pages.inc', 'type' => MENU_CALLBACK, ); $items['flag/confirm/%/%flag/%'] = array( @@ -196,6 +197,7 @@ function flag_menu() { 'page arguments' => array('flag_confirm', 2, 3, 4), 'access callback' => 'user_access', 'access arguments' => array('access content'), + 'file' => 'includes/flag.pages.inc', 'type' => MENU_CALLBACK, ); @@ -1002,160 +1004,6 @@ function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { )); } -/** - * Menu callback for (un)flagging a node. - * - * Used both for the regular callback as well as the JS version. - * - * @param $action - * Either 'flag' or 'unflag'. - */ -function flag_page($action, $flag, $entity_id) { - global $user; - - // Shorten up the variables that affect the behavior of this page. - $js = isset($_REQUEST['js']); - $token = $_REQUEST['token']; - - // Specifically $_GET to avoid getting the $_COOKIE variable by the same key. - $has_js = isset($_GET['has_js']); - - // Check the flag token, then perform the flagging. - if (!flag_check_token($token, $entity_id)) { - $error = t('Bad token. You seem to have followed an invalid link.'); - } - elseif ($user->uid == 0 && !$has_js) { - $error = t('You must have JavaScript and cookies enabled in your browser to flag content.'); - } - else { - $result = $flag->flag($action, $entity_id); - if (!$result) { - $error = t('You are not allowed to flag, or unflag, this content.'); - } - } - - // If an error was received, set a message and exit. - if (isset($error)) { - if ($js) { - drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); - print drupal_json_encode(array( - 'status' => FALSE, - 'errorMessage' => $error, - )); - drupal_exit(); - } - else { - drupal_set_message($error); - drupal_access_denied(); - return; - } - } - - // If successful, return data according to the request type. - if ($js) { - drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); - $flag->link_type = 'toggle'; - print drupal_json_encode(flag_build_javascript_info($flag, $entity_id)); - drupal_exit(); - } - else { - drupal_set_message($flag->get_label($action . '_message', $entity_id)); - drupal_goto(); - } -} - -/** - * Builds the JavaScript structure describing the flagging operation. - */ -function flag_build_javascript_info($flag, $entity_id) { - $info = array( - 'status' => TRUE, - 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, TRUE), - // Further information for the benefit of custom JavaScript event handlers: - 'contentId' => $entity_id, - 'entityType' => $flag->entity_type, - 'flagName' => $flag->name, - 'flagStatus' => $flag->is_flagged($entity_id) ? 'flagged' : 'unflagged', - ); - drupal_alter('flag_javascript_info', $info); - return $info; -} - -/** - * Form for confirming the (un)flagging of an entity. - * - * @param $action - * Either 'flag' or 'unflag'. - * @param $flag - * A loaded flag object. - * @param $entity_id - * The id of the entity to operate on. The type is implicit in the flag. - * - * @see flag_confirm_submit() - */ -function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { - $form['action'] = array( - '#type' => 'value', - '#value' => $action, - ); - $form['flag_name'] = array( - '#type' => 'value', - '#value' => $flag->name, - ); - $form['entity_id'] = array( - '#type' => 'value', - '#value' => $entity_id, - ); - - $question = $flag->get_label($action . '_confirmation', $entity_id); - $path = isset($_GET['destination']) ? $_GET['destination'] : ''; - $yes = $flag->get_label($action . '_short', $entity_id); - - if ($action == 'flag') { - // If the action 'flag', we're potentially about to create a new - // flagging entity. We need an empty new entity to pass to FieldAPI. - $flagging = $flag->new_flagging($entity_id); - field_attach_form('flagging', $flagging, $form, $form_state); - $form['#flagging'] = $flagging; - } - - return confirm_form($form, $question, $path, '', $yes); -} - -/** - * Submit handler for the flag confirm form. - * - * Note that validating whether the user may perform the action is done here, - * rather than in a form validation handler. - * - * @see flag_confirm() - */ -function flag_confirm_submit(&$form, &$form_state) { - $action = $form_state['values']['action']; - $flag_name = $form_state['values']['flag_name']; - $entity_id = $form_state['values']['entity_id']; - - $flag = flag_get_flag($flag_name); - - if ($action == 'flag') { - // If the action 'flag', further build up the new entity from form values. - $flagging = $form['#flagging']; - entity_form_submit_build_entity('flagging', $flagging, $form, $form_state); - - $result = $flag->flag($action, $entity_id, NULL, FALSE, $flagging); - } - else { - $result = $flag->flag($action, $entity_id, NULL, FALSE); - } - - if (!$result) { - drupal_set_message(t('You are not allowed to flag, or unflag, this content.')); - } - else { - drupal_set_message($flag->get_label($action . '_message', $entity_id)); - } -} - /** * Flags or unflags an item. * diff --git a/includes/flag.pages.inc b/includes/flag.pages.inc new file mode 100644 index 0000000..d7334e0 --- /dev/null +++ b/includes/flag.pages.inc @@ -0,0 +1,160 @@ +uid == 0 && !$has_js) { + $error = t('You must have JavaScript and cookies enabled in your browser to flag content.'); + } + else { + $result = $flag->flag($action, $entity_id); + if (!$result) { + $error = t('You are not allowed to flag, or unflag, this content.'); + } + } + + // If an error was received, set a message and exit. + if (isset($error)) { + if ($js) { + drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); + print drupal_json_encode(array( + 'status' => FALSE, + 'errorMessage' => $error, + )); + drupal_exit(); + } + else { + drupal_set_message($error); + drupal_access_denied(); + return; + } + } + + // If successful, return data according to the request type. + if ($js) { + drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); + $flag->link_type = 'toggle'; + print drupal_json_encode(flag_build_javascript_info($flag, $entity_id)); + drupal_exit(); + } + else { + drupal_set_message($flag->get_label($action . '_message', $entity_id)); + drupal_goto(); + } +} + +/** + * Form for confirming the (un)flagging of an entity. + * + * @param $action + * Either 'flag' or 'unflag'. + * @param $flag + * A loaded flag object. + * @param $entity_id + * The id of the entity to operate on. The type is implicit in the flag. + * + * @see flag_confirm_submit() + */ +function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { + $form['action'] = array( + '#type' => 'value', + '#value' => $action, + ); + $form['flag_name'] = array( + '#type' => 'value', + '#value' => $flag->name, + ); + $form['entity_id'] = array( + '#type' => 'value', + '#value' => $entity_id, + ); + + $question = $flag->get_label($action . '_confirmation', $entity_id); + $path = isset($_GET['destination']) ? $_GET['destination'] : ''; + $yes = $flag->get_label($action . '_short', $entity_id); + + if ($action == 'flag') { + // If the action 'flag', we're potentially about to create a new + // flagging entity. We need an empty new entity to pass to FieldAPI. + $flagging = $flag->new_flagging($entity_id); + field_attach_form('flagging', $flagging, $form, $form_state); + $form['#flagging'] = $flagging; + } + + return confirm_form($form, $question, $path, '', $yes); +} + +/** + * Submit handler for the flag confirm form. + * + * Note that validating whether the user may perform the action is done here, + * rather than in a form validation handler. + * + * @see flag_confirm() + */ +function flag_confirm_submit(&$form, &$form_state) { + $action = $form_state['values']['action']; + $flag_name = $form_state['values']['flag_name']; + $entity_id = $form_state['values']['entity_id']; + + $flag = flag_get_flag($flag_name); + + if ($action == 'flag') { + // If the action 'flag', further build up the new entity from form values. + $flagging = $form['#flagging']; + entity_form_submit_build_entity('flagging', $flagging, $form, $form_state); + + $result = $flag->flag($action, $entity_id, NULL, FALSE, $flagging); + } + else { + $result = $flag->flag($action, $entity_id, NULL, FALSE); + } + + if (!$result) { + drupal_set_message(t('You are not allowed to flag, or unflag, this content.')); + } + else { + drupal_set_message($flag->get_label($action . '_message', $entity_id)); + } +} + +/** + * Builds the JavaScript structure describing the flagging operation. + */ +function flag_build_javascript_info($flag, $entity_id) { + $info = array( + 'status' => TRUE, + 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, TRUE), + // Further information for the benefit of custom JavaScript event handlers: + 'contentId' => $entity_id, + 'entityType' => $flag->entity_type, + 'flagName' => $flag->name, + 'flagStatus' => $flag->is_flagged($entity_id) ? 'flagged' : 'unflagged', + ); + drupal_alter('flag_javascript_info', $info); + return $info; +} From 01bb223bcfcf0f53752585d9d8cf660f20aea66c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 8 Aug 2012 21:25:15 +0100 Subject: [PATCH 144/629] Issue #1689400 by Scyther: Changed flag form to use machine name form element. --- flag.module | 2 +- includes/flag.admin.inc | 71 +++++++++++++++++------------------------ tests/flag.test | 2 +- 3 files changed, 31 insertions(+), 44 deletions(-) diff --git a/flag.module b/flag.module index be13fad..2e33f73 100644 --- a/flag.module +++ b/flag.module @@ -109,7 +109,7 @@ function flag_menu() { 'weight' => -10, ); $items[FLAG_ADMIN_PATH . '/add'] = array( - 'title' => 'Add a new flag', + 'title' => 'Add flag', 'page callback' => 'flag_add_page', 'access callback' => 'user_access', 'access arguments' => array('administer flags'), diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 0ae0101..dc96119 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -195,30 +195,22 @@ function theme_flag_admin_page($variables) { /** * Menu callback for adding a new flag. */ -function flag_add_page($type = NULL, $name = NULL) { - drupal_set_title(t('Add new flag')); - if (isset($type) && isset($name)) { - $flag = flag_flag::factory_by_entity_type($type); - $flag->name = $name; +function flag_add_page($entity_type = NULL) { + if (isset($entity_type)) { + $flag = flag_flag::factory_by_entity_type($entity_type); + $type_info = flag_fetch_definition($entity_type); + drupal_set_title(t('Add new @type flag', array('@type' => $type_info['title']))); return drupal_get_form('flag_form', $flag); } - else { - return drupal_get_form('flag_add_form'); - } + + drupal_set_title(t('Select flag type')); + return drupal_get_form('flag_add_form'); } /** * Present a form for creating a new flag, setting the type of flag. */ function flag_add_form($form, &$form_state) { - $form['name'] = array( - '#type' => 'textfield', - '#title' => t('Flag name'), - '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#maxlength' => 32, - '#required' => TRUE, - ); - $types = array(); foreach (flag_fetch_definition() as $type => $info) { $types[$type] = $info['title'] . '
' . $info['description'] . '
'; @@ -239,7 +231,7 @@ function flag_add_form($form, &$form_state) { $form['actions']['submit'] = array( '#type' => 'submit', - '#value' => t('Add flag'), + '#value' => t('Continue'), ); return $form; @@ -247,17 +239,13 @@ function flag_add_form($form, &$form_state) { function flag_add_form_validate($form, &$form_state) { $flag = flag_flag::factory_by_entity_type($form_state['values']['type']); - $flag->name = $form_state['values']['name']; - $errors = $flag->validate_name(); - foreach ($errors as $field => $field_errors) { - foreach ($field_errors as $error) { - form_set_error($field, $error['message']); - } + if (get_class($flag) == 'flag_broken') { + form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); } } function flag_add_form_submit($form, &$form_state) { - $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type'] . '/' . $form_state['values']['name']; + $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type']; } /** @@ -266,21 +254,6 @@ function flag_add_form_submit($form, &$form_state) { function flag_form($form, &$form_state, $flag) { $form['#flag'] = $flag; - $form['name'] = array( - '#type' => 'textfield', - '#title' => t('Name'), - '#default_value' => $flag->name, - '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#maxlength' => 32, - '#required' => TRUE, - '#access' => empty($flag->locked['name']), - '#weight' => -3, - ); - - if (!empty($flag->fid)) { - $form['name']['#description'] .= ' ' . t('Change this value only with great care.') . ''; - } - $form['title'] = array( '#type' => 'textfield', '#title' => t('Title'), @@ -289,7 +262,21 @@ function flag_form($form, &$form_state, $flag) { '#maxlength' => 255, '#required' => TRUE, '#access' => empty($flag->locked['title']), + '#weight' => -3, + ); + + $form['name'] = array( + '#type' => 'machine_name', + '#title' => t('Machine name'), + '#default_value' => $flag->name, + '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), + '#maxlength' => 32, + '#access' => empty($flag->locked['name']), '#weight' => -2, + '#machine_name' => array( + 'exists' => 'flag_get_flag', + 'source' => array('title'), + ), ); $form['global'] = array( @@ -380,10 +367,10 @@ function flag_form($form, &$form_state, $flag) { ); $options = array(); - $node_types = node_type_get_types(); - foreach ($node_types as $node_type) { + foreach (node_type_get_types() as $node_type) { $options[$node_type->type] = check_plain($node_type->name); } + $form['access']['types'] = array( '#type' => 'checkboxes', '#title' => t('Flaggable content'), @@ -550,7 +537,7 @@ function flag_form_submit($form, &$form_state) { $flag->form_input($form_state['values']); $flag->save(); $flag->enable(); - drupal_set_message(t('Flag @name has been saved.', array('@name' => $flag->get_title()))); + drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); _flag_clear_cache(); $form_state['redirect'] = FLAG_ADMIN_PATH; } diff --git a/tests/flag.test b/tests/flag.test index 4580d7f..1eec30f 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -58,7 +58,7 @@ class FlagTestCase extends DrupalWebTestCase { $saved['types'] = array('page'); unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); - $this->drupalPost(FLAG_ADMIN_PATH . '/add/node/' . $edit['name'], $edit, t('Save flag')); + $this->drupalPost(FLAG_ADMIN_PATH . '/add/node', $edit, t('Save flag')); flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); From 44b8263871030f08b1f73c5c80022fc9383b17f8 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 8 Aug 2012 21:25:42 +0100 Subject: [PATCH 145/629] by Scyther: Fixed use of strtolower(). --- tests/flag.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/flag.test b/tests/flag.test index 1eec30f..8803507 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -36,7 +36,7 @@ class FlagTestCase extends DrupalWebTestCase { function testFlagAdmin() { // Add a new flag using the UI. $edit = array( - 'name' => strtolower($this->randomName()), + 'name' => drupal_strtolower($this->randomName()), 'title' => $this->randomName(), 'flag_short' => 'flag short [node:nid]', 'flag_long' => 'flag long [node:nid]', @@ -73,7 +73,7 @@ class FlagTestCase extends DrupalWebTestCase { // Edit the flag through the UI. $edit = array( - 'name' => strtolower($this->randomName()), + 'name' => drupal_strtolower($this->randomName()), 'title' => $this->randomName(), 'flag_short' => 'flag 2 short [node:nid]', 'flag_long' => 'flag 2 long [node:nid]', From 039707b4854288eb162162ff69c772fdd8fc6ca4 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 8 Aug 2012 21:37:52 +0100 Subject: [PATCH 146/629] Issue #1718678 by Scyther: Fixed incorrectly formatted error message on flag form for broken flags. --- includes/flag/flag_flag.inc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index a440199..f7d08f9 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1291,9 +1291,7 @@ class flag_flag { */ class flag_broken extends flag_flag { function options_form(&$form) { + drupal_set_message(t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->entity_type)), 'error'); $form = array(); - $form['error'] = array( - '#markup' => '
' . t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->entity_type)) . '
', - ); } } From f13a17ea9cb61081d82c2b8f9d37f126281c8a44 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 8 Aug 2012 22:32:24 +0100 Subject: [PATCH 147/629] Issue #1700010 by Scyther: Added defaults to required message fields in the flag add form. --- includes/flag.admin.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index dc96119..7113797 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -296,7 +296,7 @@ function flag_form($form, &$form_state, $flag) { $form['messages']['flag_short'] = array( '#type' => 'textfield', '#title' => t('Flag link text'), - '#default_value' => $flag->flag_short, + '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), '#description' => t('The text for the "flag this" link for this flag.'), '#required' => TRUE, '#access' => empty($flag->locked['flag_short']), @@ -321,7 +321,7 @@ function flag_form($form, &$form_state, $flag) { $form['messages']['unflag_short'] = array( '#type' => 'textfield', '#title' => t('Unflag link text'), - '#default_value' => $flag->unflag_short, + '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), '#description' => t('The text for the "unflag this" link for this flag.'), '#required' => TRUE, '#access' => empty($flag->locked['unflag_short']), From f9a1385674f4cfc93f222b0a28713b3cc11755c3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 9 Aug 2012 22:38:00 +0100 Subject: [PATCH 148/629] Issue #1699756 by joachim: Renamed info hooks: hook_flag_definitions() to hook_flag_type_info() and hook_flag_link_types() to hook_flag_link_type_info(). --- flag.api.php | 16 ++++++++-------- flag.inc | 16 ++++++++-------- flag.module | 18 +++++++++--------- includes/flag.features.inc | 2 +- includes/flag/flag_flag.inc | 2 +- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/flag.api.php b/flag.api.php index 3965317..dff8521 100644 --- a/flag.api.php +++ b/flag.api.php @@ -26,7 +26,7 @@ * * @see flag_fetch_definition() */ -function hook_flag_definitions() { +function hook_flag_type_info() { return array( 'node' => array( 'title' => t('Nodes'), @@ -40,9 +40,9 @@ function hook_flag_definitions() { * Alter flag type definitions provided by other modules. * * @param $definitions - * An array of flag definitions returned by hook_flag_definitions(). + * An array of flag definitions returned by hook_flag_type_info(). */ -function hook_flag_definitions_alter(&$definitions) { +function hook_flag_type_info_alter(&$definitions) { } @@ -160,9 +160,9 @@ function hook_flag_access_multiple($flag, $entity_ids, $account) { * module's own CSS file for links. * * @see flag_get_link_types() - * @see hook_flag_link_types_alter() + * @see hook_flag_link_type_info_alter() */ -function hook_flag_link_types() { +function hook_flag_link_type_info() { } @@ -173,9 +173,9 @@ function hook_flag_link_types() { * An array of the link types defined by all modules. * * @see flag_get_link_types() - * @see hook_flag_link_types() + * @see hook_flag_link_type_info() */ -function hook_flag_link_types_alter(&$link_types) { +function hook_flag_link_type_info_alter(&$link_types) { } @@ -200,7 +200,7 @@ function hook_flag_link_types_alter(&$link_types) { * @return * An array defining properties of the link. * - * @see hook_flag_link_types() + * @see hook_flag_link_type_info() * @see template_preprocess_flag() */ function hook_flag_link() { diff --git a/flag.inc b/flag.inc index ca71c6b..d552926 100644 --- a/flag.inc +++ b/flag.inc @@ -1,7 +1,7 @@ array( @@ -33,13 +33,13 @@ function flag_flag_definitions() { } /** - * Implements hook_flag_definitions_alter(). + * Implements hook_flag_type_info_alter(). * * Step in and add flag types for any entities not yet catered for, using the * basic flag_entity handler. This allows other modules to provide more - * specialized handlers for entities in hook_flag_definitions() as normal. + * specialized handlers for entities in hook_flag_type_info() as normal. */ -function flag_flag_definitions_alter(&$definitions) { +function flag_flag_type_info_alter(&$definitions) { foreach (entity_get_info() as $entity_type => $entity) { // Only add flag support for entities that don't yet have them, and which // are non-config entities. @@ -59,12 +59,12 @@ function flag_flag_definitions_alter(&$definitions) { function flag_fetch_definition($entity_type = NULL) { static $defintions; if (!isset($defintions)) { - $defintions = module_invoke_all('flag_definitions'); - drupal_alter('flag_definitions', $defintions); + $defintions = module_invoke_all('flag_type_info'); + drupal_alter('flag_type_info', $defintions); if (!isset($defintions['node'])) { // We want our API to be available in hook_install, but our module is not // enabled by then, so let's load our implementation directly: - $defintions += flag_flag_definitions(); + $defintions += flag_flag_type_info(); } } diff --git a/flag.module b/flag.module index 2e33f73..02afd96 100644 --- a/flag.module +++ b/flag.module @@ -371,9 +371,9 @@ function flag_flag_link($flag, $action, $entity_id) { } /** - * Implements hook_flag_link_types(). + * Implements hook_flag_link_type_info(). */ -function flag_flag_link_types() { +function flag_flag_link_type_info() { return array( 'toggle' => array( 'title' => t('JavaScript toggle'), @@ -1948,22 +1948,22 @@ function flag_create_link($flag_name, $entity_id) { * (Optional) Whether to reset the static cache. * * @return - * An array of link types as defined by hook_flag_link_types(). These are keyed + * An array of link types as defined by hook_flag_link_type_info(). These are keyed * by the type name, and each value is an array of properties. In addition to - * those defined in hook_flag_link_types(), the following properties are set: + * those defined in hook_flag_link_type_info(), the following properties are set: * - 'module': The providing module. * - 'name': The machine name of the type. * - * @see hook_flag_link_types() - * @see hook_flag_link_types_alter() + * @see hook_flag_link_type_info() + * @see hook_flag_link_type_info_alter() */ function flag_get_link_types($reset = FALSE) { static $link_types; if (!isset($link_types) || $reset) { $link_types = array(); - foreach (module_implements('flag_link_types') as $module) { - $module_types = module_invoke($module, 'flag_link_types'); + foreach (module_implements('flag_link_type_info') as $module) { + $module_types = module_invoke($module, 'flag_link_type_info'); foreach ($module_types as $type_name => $info) { $link_types[$type_name] = $info + array( 'module' => $module, @@ -1976,7 +1976,7 @@ function flag_get_link_types($reset = FALSE) { ); } } - drupal_alter('flag_link_types', $link_types); + drupal_alter('flag_link_type_info', $link_types); } return $link_types; diff --git a/includes/flag.features.inc b/includes/flag.features.inc index fed0b13..23ad242 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -82,7 +82,7 @@ function flag_features_revert($module = NULL) { */ function flag_features_providing_module() { $modules = array(); - $hook = 'flag_definitions'; + $hook = 'flag_type_info'; foreach (module_implements($hook) as $module) { foreach (module_invoke($module, $hook) as $key => $value) { $modules[$key] = $module; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index f7d08f9..5fa2cf5 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -111,7 +111,7 @@ class flag_flag { 'unflag_long' => '', 'unflag_message' => '', 'unflag_denied_text' => '', - // The link type used by the flag, as defined in hook_flag_link_types(). + // The link type used by the flag, as defined in hook_flag_link_type_info(). 'link_type' => 'toggle', 'roles' => array( 'flag' => array(DRUPAL_AUTHENTICATED_RID), From 836e55b828757993606f59992b0f19ac40263878 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 10 Aug 2012 07:58:06 +0100 Subject: [PATCH 149/629] Issue #1720196 by joachim: Changed Rules event to be invoked after hook_flag() rather than within it. --- flag.module | 14 -------------- includes/flag/flag_flag.inc | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/flag.module b/flag.module index 02afd96..1236cc6 100644 --- a/flag.module +++ b/flag.module @@ -1049,20 +1049,6 @@ function flag_flag($action, $flag, $entity_id, $account) { } } } - - if (module_exists('rules')) { - $event_name = ($action == 'flag' ? 'flag_flagged_' : 'flag_unflagged_') . $flag->name; - // We only support flags on entities. - if (entity_get_info($flag->entity_type)) { - $variables = array( - 'flag' => $flag, - 'flagged_' . $flag->entity_type => $entity_id, - 'flagging_user' => $account, - 'flagging' => $flag->get_flagging($entity_id,$account->uid), - ); - rules_invoke_event_by_args($event_name, $variables); - } - } } /** diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 5fa2cf5..d8050e4 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -582,6 +582,20 @@ class flag_flag { $this->_delete_flagging($existing_flagging_id); $this->_unflag($entity_id, $uid, $sid); module_invoke_all('flag', 'unflag', $this, $entity_id, $account, $existing_flagging_id); + // Invoke Rules event. + if (module_exists('rules')) { + $event_name = 'flag_unflagged_' . $this->name; + // We only support flags on entities. + if (entity_get_info($this->entity_type)) { + $variables = array( + 'flag' => $this, + 'flagged_' . $this->entity_type => $entity_id, + 'flagging_user' => $account, + 'flagging' => $this->get_flagging($entity_id, $account->uid), + ); + rules_invoke_event_by_args($event_name, $variables); + } + } } } elseif ($action == 'flag') { @@ -599,6 +613,20 @@ class flag_flag { // Field API will assign the fields their default values. $this->_insert_flagging($flagging, $entity_id, $flagging_id); module_invoke_all('flag', 'flag', $this, $entity_id, $account, $flagging_id); + // Invoke Rules event. + if (module_exists('rules')) { + $event_name = 'flag_flagged_' . $this->name; + // We only support flags on entities. + if (entity_get_info($this->entity_type)) { + $variables = array( + 'flag' => $this, + 'flagged_' . $this->entity_type => $entity_id, + 'flagging_user' => $account, + 'flagging' => $this->get_flagging($entity_id, $account->uid), + ); + rules_invoke_event_by_args($event_name, $variables); + } + } } else { // Nothing to do. Item is already flagged. From a7c2f02104a27036346012e14df7020e72a959de Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 10 Aug 2012 08:02:22 +0100 Subject: [PATCH 150/629] Issue #1719942 by joachim: Fixed RulesEvaluationException when unflagging Rules event is invoked. --- flag.rules.inc | 4 ++++ includes/flag/flag_flag.inc | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flag.rules.inc b/flag.rules.inc index 2b98f74..22896bb 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -152,6 +152,10 @@ function flag_rules_event_info() { 'variables' => $variables, 'access callback' => 'flag_rules_integration_access', ); + + // Remove the flagging variable: the flagging is already deleted when + // the rules event is invoked. + unset($variables['flagging']); $items['flag_unflagged_' . $flag->name] = array( 'group' => t('Flag'), 'label' => t('A @flag-type has been unflagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->entity_type))), diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index d8050e4..748de1d 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -591,7 +591,6 @@ class flag_flag { 'flag' => $this, 'flagged_' . $this->entity_type => $entity_id, 'flagging_user' => $account, - 'flagging' => $this->get_flagging($entity_id, $account->uid), ); rules_invoke_event_by_args($event_name, $variables); } From 5c4ad38ef2a5e99b077293b95dd7b1a5ce481c3a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 10 Aug 2012 22:59:55 +0100 Subject: [PATCH 151/629] Issue #1718744 by joachim: Added hook_help() text for flag type selection form and trimmed form element description accordingly. --- flag.module | 3 +++ includes/flag.admin.inc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 1236cc6..cb2296f 100644 --- a/flag.module +++ b/flag.module @@ -249,6 +249,9 @@ function flag_help($path, $arg) { case FLAG_ADMIN_PATH: $output = '

' . t('This page lists all the flags that are currently defined on this system.') . '

'; return $output; + case FLAG_ADMIN_PATH . '/add': + $output = '

' . t('Select the type of flag to create. An individual flag can only affect one type of object. This cannot be changed once the flag is created.') . '

'; + return $output; case FLAG_ADMIN_PATH . '/manage/%/fields': $output = '

' . t('Flags can have fields added to them. For example, a "Spam" flag could have a Reason field where a user could type in why he believes the item flagged is spam. A "Bookmarks" flag could have a Folder field into which a user could arrange her bookmarks.') . '

'; $output .= '

' . t('On this page you can add fields to flags, delete them, and otherwise manage them.') . '

'; diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 7113797..7a9b7f1 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -220,7 +220,7 @@ function flag_add_form($form, &$form_state) { '#type' => 'radios', '#title' => t('Flag type'), '#default_value' => 'node', - '#description' => t('The type of content this flag will affect. An individual flag can only affect one type of content. This cannot be changed once the flag is created.'), + '#description' => t('The type of object this flag will affect. This cannot be changed once the flag is created.'), '#required' => TRUE, '#options' => $types, ); From 525a313fa83278aeeca4610b8d7535d5a0f36afd Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 Aug 2012 11:13:35 +0100 Subject: [PATCH 152/629] Issue #471212 by joachim: Changed flag types property to allow an empty array to mean all object subtypes/bundles apply. --- includes/flag/flag_entity.inc | 10 +++++++--- includes/flag/flag_flag.inc | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 1f0f958..754597e 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -39,9 +39,8 @@ class flag_entity extends flag_flag { '#type' => 'checkboxes', '#title' => t('Bundles'), '#options' => $bundles, - '#description' => t('Check any bundle that this flag may be used on. You must check at least one bundle.'), + '#description' => t('Select the bundles that this flag may be used on. Leave blank to allow on all bundles for the entity type.'), '#default_value' => $this->types, - '#required' => TRUE, ); // Handlers may want to unset this option if they provide their own more // specific ways to show links. @@ -75,7 +74,12 @@ class flag_entity extends flag_flag { */ function applies_to_entity($entity) { $entity_info = entity_get_info($this->entity_type); - if (empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { + // The following conditions are applied: + // - if the types array is empty, the flag applies to all bundles and thus + // to this entity. + // - if the entity has no bundles, the flag applies to the entity. + // - if the entity's bundle is in the list of types. + if (empty($this->types) || empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { return TRUE; } return FALSE; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 748de1d..cc1146a 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -29,6 +29,7 @@ class flag_flag { var $title = ''; var $global = FALSE; // The sub-types, e.g. node types, this flag applies to. + // This may be an empty array to indicate all types apply. var $types = array(); /** From d3a49b49e6ace92d0b610b971f2e00baae8e63ba Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 Aug 2012 13:12:13 +0100 Subject: [PATCH 153/629] Issue #1113904 by katbailey, jaydub, joachim: Changed use of static to drupal_static(). --- flag.inc | 4 ++-- flag.module | 14 +++++++------- flag_actions.module | 2 +- includes/views/flag.views.inc | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/flag.inc b/flag.inc index d552926..51df079 100644 --- a/flag.inc +++ b/flag.inc @@ -57,7 +57,7 @@ function flag_flag_type_info_alter(&$definitions) { * Returns a flag definition. */ function flag_fetch_definition($entity_type = NULL) { - static $defintions; + $cache = &drupal_static(__FUNCTION__); if (!isset($defintions)) { $defintions = module_invoke_all('flag_type_info'); drupal_alter('flag_type_info', $defintions); @@ -82,7 +82,7 @@ function flag_fetch_definition($entity_type = NULL) { * Returns all flag types defined on the system. */ function flag_get_types() { - static $types; + $types = &drupal_static(__FUNCTION__); if (!isset($types)) { $types = array_keys(flag_fetch_definition()); } diff --git a/flag.module b/flag.module index cb2296f..b863f74 100644 --- a/flag.module +++ b/flag.module @@ -1361,7 +1361,7 @@ function flag_theme() { */ function template_preprocess_flag(&$variables) { global $user; - static $initialized = array(); + $initialized = &drupal_static(__FUNCTION__, array()); // Some typing shotcuts: $flag =& $variables['flag']; @@ -1498,7 +1498,7 @@ function _flag_link_type_fields() { * An array of the structure [name] => [number of flags]. */ function flag_get_counts($entity_type, $entity_id, $reset = FALSE) { - static $counts; + $counts = &drupal_static(__FUNCTION__); if ($reset) { $counts = array(); @@ -1534,7 +1534,7 @@ function flag_get_counts($entity_type, $entity_id, $reset = FALSE) { * Reset the internal cache and execute the SQL query another time. */ function flag_get_flag_counts($flag_name, $reset = FALSE) { - static $counts; + $counts = &drupal_static(__FUNCTION__); if ($reset) { $counts = array(); @@ -1596,7 +1596,7 @@ function flag_get_flag($name = NULL, $fid = NULL) { * An array of the structure [fid] = flag_object. */ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL, $reset = FALSE) { - static $flags; + $flags = &drupal_static(__FUNCTION__); // Retrieve a list of all flags, regardless of the parameters. if (!isset($flags) || $reset) { @@ -1809,7 +1809,7 @@ function flag_get_entity_id($flagging_id) { * */ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) { - static $flagged_content; + $flagged_content = &drupal_static(__FUNCTION__); if ($reset) { $flagged_content = array(); @@ -1947,7 +1947,7 @@ function flag_create_link($flag_name, $entity_id) { * @see hook_flag_link_type_info_alter() */ function flag_get_link_types($reset = FALSE) { - static $link_types; + $link_types = &drupal_static(__FUNCTION__); if (!isset($link_types) || $reset) { $link_types = array(); @@ -1991,7 +1991,7 @@ function flag_check_token($token, $entity_id) { * Set the Session ID for a user. Utilizes the Session API module. */ function flag_set_sid($uid = NULL, $create = TRUE) { - static $sids = array(); + $sids = &drupal_static(__FUNCTION__, array()); if (!isset($uid)) { $uid = $GLOBALS['user']->uid; diff --git a/flag_actions.module b/flag_actions.module index b3bed68..5669eb8 100644 --- a/flag_actions.module +++ b/flag_actions.module @@ -76,7 +76,7 @@ function flag_actions_get_action($aid) { } function flag_actions_get_actions($flag_name = NULL, $reset = FALSE) { - static $flag_actions; + $flag_actions = &drupal_static(__FUNCTION__); module_load_include('inc', 'flag', 'includes/flag.actions'); // Get a list of all possible actions defined by modules. diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index b4129dd..e8ab965 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -247,7 +247,7 @@ function flag_views_flag_config_form($form_type, $entity_type, $current_flag) { * Helper function that gets the first defined flag and returns its name. */ function flag_views_flag_default($entity_type) { - static $default_flag = array(); + $default_flag = &drupal_static(__FUNCTION__, array()); if (!array_key_exists($entity_type, $default_flag)) { $flag = array_shift(flag_get_flags($entity_type)); From 60b7ceac73b877bde3760dc114d55f6f0ff84ba7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 Aug 2012 13:15:43 +0100 Subject: [PATCH 154/629] by joachim: Fixed typo in variable name in flag_fetch_definition(). --- flag.inc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/flag.inc b/flag.inc index 51df079..ab3cd58 100644 --- a/flag.inc +++ b/flag.inc @@ -58,23 +58,23 @@ function flag_flag_type_info_alter(&$definitions) { */ function flag_fetch_definition($entity_type = NULL) { $cache = &drupal_static(__FUNCTION__); - if (!isset($defintions)) { - $defintions = module_invoke_all('flag_type_info'); - drupal_alter('flag_type_info', $defintions); - if (!isset($defintions['node'])) { + if (!isset($definitions)) { + $definitions = module_invoke_all('flag_type_info'); + drupal_alter('flag_type_info', $definitions); + if (!isset($definitions['node'])) { // We want our API to be available in hook_install, but our module is not // enabled by then, so let's load our implementation directly: - $defintions += flag_flag_type_info(); + $definitions += flag_flag_type_info(); } } if (isset($entity_type)) { - if (isset($defintions[$entity_type])) { - return $defintions[$entity_type]; + if (isset($definitions[$entity_type])) { + return $definitions[$entity_type]; } } else { - return $defintions; + return $definitions; } } From bba1d4e30584ffdcaeb1a9638f968ea590c0ada1 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 Aug 2012 19:48:14 +0100 Subject: [PATCH 155/629] Issue #1726994 by joachim: Fixed circularity in entity info and flag types. --- flag.module | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/flag.module b/flag.module index b863f74..269eef2 100644 --- a/flag.module +++ b/flag.module @@ -35,12 +35,16 @@ function flag_entity_info() { ), ); - foreach (flag_get_flags(NULL, NULL, NULL, TRUE) as $flag) { - $return['flagging']['bundles'][$flag->name] = array( - 'label' => $flag->title, + // Add bundle info but bypass flag_get_flags() as we cannot use it here, as + // it calls entity_get_info(). + $result = db_query("SELECT name, title FROM {flag}"); + $flag_names = $result->fetchAllKeyed(); + foreach ($flag_names as $flag_name => $flag_title) { + $return['flagging']['bundles'][$flag_name] = array( + 'label' => $flag_title, 'admin' => array( 'path' => FLAG_ADMIN_PATH . '/manage/%flag', - 'real path' => FLAG_ADMIN_PATH . '/manage/' . $flag->name, + 'real path' => FLAG_ADMIN_PATH . '/manage/' . $flag_name, 'bundle argument' => FLAG_ADMIN_PATH_START + 1, 'access arguments' => array('administer flags'), ), From 57ec8550545b848b76b585c29fcf42d029a01086 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 13 Aug 2012 08:17:56 +0100 Subject: [PATCH 156/629] Issue #1726724 by kid_icarus: Fixed documentation of flag_flag class variables. --- includes/flag/flag_flag.inc | 43 +++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index cc1146a..0e35892 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -15,21 +15,50 @@ */ class flag_flag { - // The database ID. Null for flags that haven't been saved to the database yet. + /** + * The database ID. + * + * NULL for flags that haven't been saved to the database yet. + * + * @var integer + */ var $fid = NULL; - // The entity type this flag works with. + /** + * The entity type this flag works with. + * + * @var string + */ var $entity_type = NULL; - // The flag's "machine readable" name. + /** + * The flag's "machine readable" name. + * + * @var string + */ var $name = ''; - // Various non-serialized properties of the flag, corresponding directly to - // database columns. + /** + * The human-readable title for this flag. + * + * @var string + */ var $title = ''; + + /** + * Whether this flag state should act as a single toggle to all users. + * + * @var bool + */ var $global = FALSE; - // The sub-types, e.g. node types, this flag applies to. - // This may be an empty array to indicate all types apply. + + /** + * The sub-types, AKA bundles, this flag applies to. + * + * This may be an empty array to indicate all types apply. + * + * @var array + */ var $types = array(); /** From 26b31d5348151ae1c9e79acd6af940fdc9962463 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 13 Aug 2012 08:23:04 +0100 Subject: [PATCH 157/629] Issue #1724288 by kid_icarus: Removed useless calls to flag_create_handler(). --- flag.rules.inc | 2 -- 1 file changed, 2 deletions(-) diff --git a/flag.rules.inc b/flag.rules.inc index 22896bb..e4f6dd5 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -232,7 +232,6 @@ function flag_rules_action_info() { ), ); foreach (flag_get_types() as $type) { - $flag = flag_create_handler($type); $entity_info = entity_get_info($type); $items += array( 'flag_flag' . $type => array( @@ -357,7 +356,6 @@ function flag_rules_action_fetch_entity_by_user($flag, $user) { function flag_rules_condition_info() { $items = array(); foreach (flag_get_types() as $type) { - $flag = flag_create_handler($type); $entity_info = entity_get_info($type); $label = isset($entity_info[$type]['label']) ? $entity_info[$type]['label'] : $type; $items += array( From 1a365d6c25a4812e23178861fc6aa2edc9f925c3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 13 Aug 2012 10:00:33 +0100 Subject: [PATCH 158/629] Issue #1726808 by joachim: Removed $reset param from flag_get_link_types(). --- flag.module | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/flag.module b/flag.module index 269eef2..5c75f37 100644 --- a/flag.module +++ b/flag.module @@ -1937,9 +1937,6 @@ function flag_create_link($flag_name, $entity_id) { /** * Return an array of link types provided by modules. * - * @param $reset - * (Optional) Whether to reset the static cache. - * * @return * An array of link types as defined by hook_flag_link_type_info(). These are keyed * by the type name, and each value is an array of properties. In addition to @@ -1950,10 +1947,10 @@ function flag_create_link($flag_name, $entity_id) { * @see hook_flag_link_type_info() * @see hook_flag_link_type_info_alter() */ -function flag_get_link_types($reset = FALSE) { +function flag_get_link_types() { $link_types = &drupal_static(__FUNCTION__); - if (!isset($link_types) || $reset) { + if (!isset($link_types)) { $link_types = array(); foreach (module_implements('flag_link_type_info') as $module) { $module_types = module_invoke($module, 'flag_link_type_info'); From 6be1e91f175f860734f7f2bfaff8292b468ab936 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 13 Aug 2012 23:08:27 +0100 Subject: [PATCH 159/629] Issue #1726806 by kid_icarus, joachim: Fixed 'save flag order' button and flag weight showing when there are fewer than 2 flags. --- includes/flag.admin.inc | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 7a9b7f1..a21d692 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -35,10 +35,17 @@ function flag_admin_listing($form, &$form_state, $flags) { '#type' => 'actions', ); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save flag order'), - ); + if (count($flags) == 1) { + // Don't show weights with only one flag. + unset($form['flags'][$flag->name]['weight']); + } + elseif (count($flags) > 1) { + // Only show the form button if there are several flags. + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save flag order'), + ); + } return $form; } @@ -75,15 +82,17 @@ function theme_flag_admin_listing($variables) { unset($ops['flags_fields']); } $roles = array_flip(array_intersect(array_flip(user_roles()), $flag->roles['flag'])); - $row = array( - $flag->name, - drupal_render($form['flags'][$flag->name]['weight']), - $flag->entity_type, - empty($flag->roles['flag']) ? '' . t('No roles') . '' : implode(', ', $roles), - $flag->types ? implode(', ', $flag->types) : '-', - $flag->global ? t('Yes') : t('No'), - theme('links', array('links' => $ops)), - ); + $row = array(); + $row[] = $flag->name; + if (count($flags) > 1) { + $row[] = drupal_render($form['flags'][$flag->name]['weight']); + } + $row[] = $flag->entity_type; + $row[] = empty($flag->roles['flag']) ? '' . t('No roles') . '' : implode(', ', $roles); + $row[] = $flag->types ? implode(', ', $flag->types) : '-'; + $row[] = $flag->global ? t('Yes') : t('No'); + $row[] = theme('links', array('links' => $ops)); + $rows[] = array( 'data' => $row, 'class' => array('draggable'), @@ -94,11 +103,15 @@ function theme_flag_admin_listing($variables) { array('data' => t('No flags are currently defined.'), 'colspan' => 7), ); } - else { + elseif (count($flags) > 1) { drupal_add_tabledrag('flag-admin-listing-table', 'order', 'sibling', 'flag-weight'); } - $header = array(t('Flag'), t('Weight'), t('Flag type'), t('Roles'), t('Entity bundles'), t('Global?'), t('Operations')); + $header = array(t('Flag')); + if (count($flags) > 1) { + $header[] = t('Weight'); + } + $header = array_merge($header, array(t('Flag type'), t('Roles'), t('Entity bundles'), t('Global?'), t('Operations'))); $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'flag-admin-listing-table'))); $output .= drupal_render_children($form); From 4472c04604d33d090a4f24621daacdeb531cac12 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 16 Aug 2012 11:58:58 +0100 Subject: [PATCH 160/629] Issue #1734494 by joachim: Added property to hook_flag_link_type_info() to let link types declare they provide a flagging entity form. --- flag.api.php | 4 ++++ flag.module | 2 ++ 2 files changed, 6 insertions(+) diff --git a/flag.api.php b/flag.api.php index dff8521..65fb1e4 100644 --- a/flag.api.php +++ b/flag.api.php @@ -158,6 +158,10 @@ function hook_flag_access_multiple($flag, $entity_ids, $account) { * module's own JS file for links. * - 'uses standard css': Boolean, indicates whether the link requires Flag * module's own CSS file for links. + * - 'provides form': (optional) Boolean indicating that this link type shows + * the user a flagging entity form. This property is used in the UI, eg to + * warn the admin user of link types that are not compatible with other + * flag options. Defaults to FALSE. * * @see flag_get_link_types() * @see hook_flag_link_type_info_alter() diff --git a/flag.module b/flag.module index 5c75f37..ad3008b 100644 --- a/flag.module +++ b/flag.module @@ -403,6 +403,7 @@ function flag_flag_link_type_info() { ), 'uses standard js' => FALSE, 'uses standard css' => FALSE, + 'provides form' => TRUE, ), ); } @@ -1963,6 +1964,7 @@ function flag_get_link_types() { 'options' => array(), 'uses standard js' => TRUE, 'uses standard css' => TRUE, + 'provides form' => FALSE, ); } } From 24bd7921078c58c4db6015e924577245c375fbd5 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 16 Aug 2012 16:56:10 +0100 Subject: [PATCH 161/629] Issue #1720402 by joachim: Split hook_flag() into hook_flag_flag() and hook_flag_unflag(). --- flag.api.php | 22 +++++++++--- flag.module | 71 +++++++++++++++++++++++++------------ includes/flag/flag_flag.inc | 4 +-- 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/flag.api.php b/flag.api.php index 65fb1e4..a499bac 100644 --- a/flag.api.php +++ b/flag.api.php @@ -82,10 +82,8 @@ function hook_flag_options_alter(&$options, $flag) { } /** - * Act on a flagging. + * Act on an object being flagged. * - * @param $op - * The operation being performed: one of 'flag' or 'unflag'. * @param $flag * The flag object. * @param $entity_id @@ -95,7 +93,23 @@ function hook_flag_options_alter(&$options, $flag) { * @param $flagging_id * The id of the flagging in the {flagging} table. */ -function hook_flag($op, $flag, $entity_id, $account, $flagging_id) { +function hook_flag_flag($flag, $entity_id, $account, $flagging_id) { + +} + +/** + * Act on an object being unflagged. + * + * @param $flag + * The flag object. + * @param $entity_id + * The id of the entity the flag is on. + * @param $account + * The user account performing the action. + * @param $flagging_id + * The id of the flagging in the {flagging} table. + */ +function hook_flag_unflag($flag, $entity_id, $account, $flagging_id) { } diff --git a/flag.module b/flag.module index ad3008b..b3e2380 100644 --- a/flag.module +++ b/flag.module @@ -1030,31 +1030,58 @@ function flag($action, $flag_name, $entity_id, $account = NULL) { } /** - * Implements hook_flag(). Trigger actions if any are available. + * Implements hook_flag_flag(). */ -function flag_flag($action, $flag, $entity_id, $account) { +function flag_flag_flag($flag, $entity_id, $account, $flagging_id) { if (module_exists('trigger')) { - $context['hook'] = 'flag'; - $context['account'] = $account; - $context['flag'] = $flag; - $context['op'] = $action; - // We add to the $context all the objects we know about: - $context = array_merge($flag->get_relevant_action_objects($entity_id), $context); - // The primary object the actions work on. - $object = $flag->fetch_entity($entity_id); - - // Generic "all flags" actions. - foreach (trigger_get_assigned_actions('flag_' . $action) as $aid => $action_info) { - // The 'if ($aid)' is a safeguard against http://drupal.org/node/271460#comment-886564 - if ($aid) { - actions_do($aid, $object, $context); - } + flag_flag_trigger('flag', $flag, $entity_id, $account, $flagging_id); + } +} + +/** + * Implements hook_flag_unflag(). + */ +function flag_flag_unflag($flag, $entity_id, $account, $flagging_id) { + if (module_exists('trigger')) { + flag_flag_trigger('unflag', $flag, $entity_id, $account, $flagging_id); + } +} + +/** + * Trigger actions if any are available. Helper for hook_flag_(un)flag(). + * + * @param $op + * The operation being performed: one of 'flag' or 'unflag'. + * @param $flag + * The flag object. + * @param $entity_id + * The id of the entity the flag is on. + * @param $account + * The user account performing the action. + * @param $flagging_id + * The id of the flagging in the {flagging} table. + */ +function flag_flag_trigger($action, $flag, $entity_id, $account, $flagging_id) { + $context['hook'] = 'flag'; + $context['account'] = $account; + $context['flag'] = $flag; + $context['op'] = $action; + // We add to the $context all the objects we know about: + $context = array_merge($flag->get_relevant_action_objects($entity_id), $context); + // The primary object the actions work on. + $object = $flag->fetch_entity($entity_id); + + // Generic "all flags" actions. + foreach (trigger_get_assigned_actions('flag_' . $action) as $aid => $action_info) { + // The 'if ($aid)' is a safeguard against http://drupal.org/node/271460#comment-886564 + if ($aid) { + actions_do($aid, $object, $context); } - // Actions specifically for this flag. - foreach (trigger_get_assigned_actions('flag_' . $action . '_' . $flag->name) as $aid => $action_info) { - if ($aid) { - actions_do($aid, $object, $context); - } + } + // Actions specifically for this flag. + foreach (trigger_get_assigned_actions('flag_' . $action . '_' . $flag->name) as $aid => $action_info) { + if ($aid) { + actions_do($aid, $object, $context); } } } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 0e35892..178a3f5 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -611,7 +611,7 @@ class flag_flag { // delete the {flagging} record. $this->_delete_flagging($existing_flagging_id); $this->_unflag($entity_id, $uid, $sid); - module_invoke_all('flag', 'unflag', $this, $entity_id, $account, $existing_flagging_id); + module_invoke_all('flag_unflag', $this, $entity_id, $account, $existing_flagging_id); // Invoke Rules event. if (module_exists('rules')) { $event_name = 'flag_unflagged_' . $this->name; @@ -641,7 +641,7 @@ class flag_flag { // (e.g., when flagging via JavaScript toggle links); in this case // Field API will assign the fields their default values. $this->_insert_flagging($flagging, $entity_id, $flagging_id); - module_invoke_all('flag', 'flag', $this, $entity_id, $account, $flagging_id); + module_invoke_all('flag_flag', $this, $entity_id, $account, $flagging_id); // Invoke Rules event. if (module_exists('rules')) { $event_name = 'flag_flagged_' . $this->name; From 85b194852401c6640cf760b512c6842ad63c2221 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 16 Aug 2012 22:30:51 +0100 Subject: [PATCH 162/629] Issue #1698146 by bartmcpherson: Fixed hook_views_api() version. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index b3e2380..ad9fd6c 100644 --- a/flag.module +++ b/flag.module @@ -289,7 +289,7 @@ function flag_init() { */ function flag_views_api() { return array( - 'api' => 2.0, + 'api' => 3.0, 'path' => drupal_get_path('module', 'flag') . '/includes/views', ); } From 3a6879f0658f7d89515eb9642216bb2b5fedc4df Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 17 Aug 2012 09:20:06 +0100 Subject: [PATCH 163/629] Issue #1735714 by joachim: Removed needless query and return in _unflag(). --- includes/flag/flag_flag.inc | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 178a3f5..248cb3f 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -610,7 +610,7 @@ class flag_flag { // Note the order: We delete the entity before calling _unflag() to // delete the {flagging} record. $this->_delete_flagging($existing_flagging_id); - $this->_unflag($entity_id, $uid, $sid); + $this->_unflag($entity_id, $existing_flagging_id); module_invoke_all('flag_unflag', $this, $entity_id, $account, $existing_flagging_id); // Invoke Rules event. if (module_exists('rules')) { @@ -832,26 +832,11 @@ class flag_flag { * You probably shouldn't call this raw private method: call the flag() * function instead. * - * @return - * If the object was flagged, returns the value of the now deleted 'flagging_id' - * column. Else, returns FALSE. - * * @private */ - function _unflag($entity_id, $uid, $sid) { - $flagging_id = db_select('flagging', 'fc') - ->fields('fc', array('flagging_id')) - ->condition('fid', $this->fid) - ->condition('uid', $uid) - ->condition('sid', $sid) - ->condition('entity_id', $entity_id) - ->execute() - ->fetchField(); - if ($flagging_id) { - db_delete('flagging')->condition('flagging_id', $flagging_id)->execute(); - $this->_decrease_count($entity_id); - } - return $flagging_id; + function _unflag($entity_id, $flagging_id) { + db_delete('flagging')->condition('flagging_id', $flagging_id)->execute(); + $this->_decrease_count($entity_id); } /** From dfd18937fbcf8a3462292b8124b82bbac06be5c7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 17 Aug 2012 10:35:08 +0100 Subject: [PATCH 164/629] Issue #1736280 by joachim: Changed call to _increase_count()/_decrease_count() to not be nested in _flag()/_flag(). --- includes/flag/flag_flag.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 248cb3f..b2acdd6 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -611,6 +611,7 @@ class flag_flag { // delete the {flagging} record. $this->_delete_flagging($existing_flagging_id); $this->_unflag($entity_id, $existing_flagging_id); + $this->_decrease_count($entity_id); module_invoke_all('flag_unflag', $this, $entity_id, $account, $existing_flagging_id); // Invoke Rules event. if (module_exists('rules')) { @@ -637,6 +638,7 @@ class flag_flag { $flagging = $this->new_flagging($entity_id, $uid, $sid); } $flagging_id = $this->_flag($entity_id, $uid, $sid); + $this->_increase_count($entity_id); // We're writing out a flagging entity even when we aren't passed one // (e.g., when flagging via JavaScript toggle links); in this case // Field API will assign the fields their default values. @@ -822,7 +824,6 @@ class flag_flag { 'timestamp' => REQUEST_TIME, )) ->execute(); - $this->_increase_count($entity_id); return $flagging_id; } @@ -836,7 +837,6 @@ class flag_flag { */ function _unflag($entity_id, $flagging_id) { db_delete('flagging')->condition('flagging_id', $flagging_id)->execute(); - $this->_decrease_count($entity_id); } /** From 812f8da5806e8293b1b1fc2514d2911bc58c2334 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 17 Aug 2012 11:03:24 +0100 Subject: [PATCH 165/629] Issue #1720180 by joachim: Changed hook_flag_unflag() and Rules event to be invoked before the flagging entity is deleted. --- flag.api.php | 3 +++ flag.rules.inc | 4 ---- includes/flag/flag_flag.inc | 43 ++++++++++++++++++++++--------------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/flag.api.php b/flag.api.php index a499bac..a8929cb 100644 --- a/flag.api.php +++ b/flag.api.php @@ -100,6 +100,9 @@ function hook_flag_flag($flag, $entity_id, $account, $flagging_id) { /** * Act on an object being unflagged. * + * This is invoked after the flag count has been decreased, but before the + * flagging entity has been deleted. + * * @param $flag * The flag object. * @param $entity_id diff --git a/flag.rules.inc b/flag.rules.inc index e4f6dd5..cc387b5 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -152,10 +152,6 @@ function flag_rules_event_info() { 'variables' => $variables, 'access callback' => 'flag_rules_integration_access', ); - - // Remove the flagging variable: the flagging is already deleted when - // the rules event is invoked. - unset($variables['flagging']); $items['flag_unflagged_' . $flag->name] = array( 'group' => t('Flag'), 'label' => t('A @flag-type has been unflagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->entity_type))), diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index b2acdd6..98ea4e7 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -607,24 +607,33 @@ class flag_flag { $this->_unflag_anonymous($entity_id); } if ($flagged) { - // Note the order: We delete the entity before calling _unflag() to - // delete the {flagging} record. - $this->_delete_flagging($existing_flagging_id); - $this->_unflag($entity_id, $existing_flagging_id); - $this->_decrease_count($entity_id); - module_invoke_all('flag_unflag', $this, $entity_id, $account, $existing_flagging_id); - // Invoke Rules event. - if (module_exists('rules')) { - $event_name = 'flag_unflagged_' . $this->name; - // We only support flags on entities. - if (entity_get_info($this->entity_type)) { - $variables = array( - 'flag' => $this, - 'flagged_' . $this->entity_type => $entity_id, - 'flagging_user' => $account, - ); - rules_invoke_event_by_args($event_name, $variables); + $transaction = db_transaction(); + try { + // Note the order: We decrease the count first so hooks have accurate + // data, then invoke hooks, then delete the flagging entity. + $this->_decrease_count($entity_id); + module_invoke_all('flag_unflag', $this, $entity_id, $account, $existing_flagging_id); + // Invoke Rules event. + if (module_exists('rules')) { + $event_name = 'flag_unflagged_' . $this->name; + // We only support flags on entities. + if (entity_get_info($this->entity_type)) { + $variables = array( + 'flag' => $this, + 'flagged_' . $this->entity_type => $entity_id, + 'flagging_user' => $account, + 'flagging' => $this->get_flagging($entity_id, $account->uid), + ); + rules_invoke_event_by_args($event_name, $variables); + } } + $this->_delete_flagging($existing_flagging_id); + $this->_unflag($entity_id, $existing_flagging_id); + } + catch (Exception $e) { + $transaction->rollback(); + watchdog_exception('flag', $e); + throw $e; } } } From 7cd656d628ad2fc653e6befdeae37adc4caee425 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 17 Aug 2012 11:38:36 +0100 Subject: [PATCH 166/629] Issue #1736310 by joachim: Moved loading of flagging entity during unflagging to flag() method. --- includes/flag/flag_flag.inc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 98ea4e7..86e94b5 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -607,12 +607,15 @@ class flag_flag { $this->_unflag_anonymous($entity_id); } if ($flagged) { + if (!isset($flagging)) { + $flagging = flagging_load($existing_flagging_id); + } $transaction = db_transaction(); try { // Note the order: We decrease the count first so hooks have accurate // data, then invoke hooks, then delete the flagging entity. $this->_decrease_count($entity_id); - module_invoke_all('flag_unflag', $this, $entity_id, $account, $existing_flagging_id); + module_invoke_all('flag_unflag', $this, $entity_id, $account, $flagging->flagging_id); // Invoke Rules event. if (module_exists('rules')) { $event_name = 'flag_unflagged_' . $this->name; @@ -622,13 +625,13 @@ class flag_flag { 'flag' => $this, 'flagged_' . $this->entity_type => $entity_id, 'flagging_user' => $account, - 'flagging' => $this->get_flagging($entity_id, $account->uid), + 'flagging' => $flagging, ); rules_invoke_event_by_args($event_name, $variables); } } - $this->_delete_flagging($existing_flagging_id); - $this->_unflag($entity_id, $existing_flagging_id); + $this->_delete_flagging($flagging); + $this->_unflag($entity_id, $flagging->flagging_id); } catch (Exception $e) { $transaction->rollback(); @@ -702,12 +705,10 @@ class flag_flag { // Update the cache. flagging_load($flagging->flagging_id, TRUE); } - private function _delete_flagging($flagging_id) { - if (($flagging = flagging_load($flagging_id))) { - field_attach_delete('flagging', $flagging); - // Remove from the cache. - flagging_load($flagging_id, TRUE); - } + private function _delete_flagging($flagging) { + field_attach_delete('flagging', $flagging); + // Remove from the cache. + flagging_load($flagging_id, TRUE); } /** From 659717125e4a3249319e4e845bb65348b388a276 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 17 Aug 2012 20:14:57 +0100 Subject: [PATCH 167/629] Issue #1736352 by joachim: Changed hook_flag_flag() and hook_flag_unflag() to receive the flagging entity instead of the flagging id. --- flag.api.php | 10 +++++----- flag.module | 12 ++++++------ includes/flag/flag_flag.inc | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/flag.api.php b/flag.api.php index a8929cb..c32d4c4 100644 --- a/flag.api.php +++ b/flag.api.php @@ -91,9 +91,9 @@ function hook_flag_options_alter(&$options, $flag) { * @param $account * The user account performing the action. * @param $flagging_id - * The id of the flagging in the {flagging} table. + * The flagging entity. */ -function hook_flag_flag($flag, $entity_id, $account, $flagging_id) { +function hook_flag_flag($flag, $entity_id, $account, $flagging) { } @@ -109,10 +109,10 @@ function hook_flag_flag($flag, $entity_id, $account, $flagging_id) { * The id of the entity the flag is on. * @param $account * The user account performing the action. - * @param $flagging_id - * The id of the flagging in the {flagging} table. + * @param $flagging + * The flagging entity. */ -function hook_flag_unflag($flag, $entity_id, $account, $flagging_id) { +function hook_flag_unflag($flag, $entity_id, $account, $flagging) { } diff --git a/flag.module b/flag.module index ad9fd6c..c03bc8c 100644 --- a/flag.module +++ b/flag.module @@ -1032,18 +1032,18 @@ function flag($action, $flag_name, $entity_id, $account = NULL) { /** * Implements hook_flag_flag(). */ -function flag_flag_flag($flag, $entity_id, $account, $flagging_id) { +function flag_flag_flag($flag, $entity_id, $account, $flagging) { if (module_exists('trigger')) { - flag_flag_trigger('flag', $flag, $entity_id, $account, $flagging_id); + flag_flag_trigger('flag', $flag, $entity_id, $account, $flagging); } } /** * Implements hook_flag_unflag(). */ -function flag_flag_unflag($flag, $entity_id, $account, $flagging_id) { +function flag_flag_unflag($flag, $entity_id, $account, $flagging) { if (module_exists('trigger')) { - flag_flag_trigger('unflag', $flag, $entity_id, $account, $flagging_id); + flag_flag_trigger('unflag', $flag, $entity_id, $account, $flagging); } } @@ -1059,9 +1059,9 @@ function flag_flag_unflag($flag, $entity_id, $account, $flagging_id) { * @param $account * The user account performing the action. * @param $flagging_id - * The id of the flagging in the {flagging} table. + * The flagging entity. */ -function flag_flag_trigger($action, $flag, $entity_id, $account, $flagging_id) { +function flag_flag_trigger($action, $flag, $entity_id, $account, $flagging) { $context['hook'] = 'flag'; $context['account'] = $account; $context['flag'] = $flag; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 86e94b5..557d984 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -615,7 +615,7 @@ class flag_flag { // Note the order: We decrease the count first so hooks have accurate // data, then invoke hooks, then delete the flagging entity. $this->_decrease_count($entity_id); - module_invoke_all('flag_unflag', $this, $entity_id, $account, $flagging->flagging_id); + module_invoke_all('flag_unflag', $this, $entity_id, $account, $flagging); // Invoke Rules event. if (module_exists('rules')) { $event_name = 'flag_unflagged_' . $this->name; @@ -655,7 +655,7 @@ class flag_flag { // (e.g., when flagging via JavaScript toggle links); in this case // Field API will assign the fields their default values. $this->_insert_flagging($flagging, $entity_id, $flagging_id); - module_invoke_all('flag_flag', $this, $entity_id, $account, $flagging_id); + module_invoke_all('flag_flag', $this, $entity_id, $account, $flagging); // Invoke Rules event. if (module_exists('rules')) { $event_name = 'flag_flagged_' . $this->name; From f34e0e0d8d8d8c7acd7d71e9d66983b4ca228362 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 19 Aug 2012 21:23:22 +0100 Subject: [PATCH 168/629] Issue #1735760 by bartmcpherson: Fixed use of entity_load() to clear entity cache. --- includes/flag/flag_flag.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 557d984..b38b9c3 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -703,12 +703,12 @@ class flag_flag { field_attach_presave('flagging', $flagging); field_attach_update('flagging', $flagging); // Update the cache. - flagging_load($flagging->flagging_id, TRUE); + entity_get_controller('flagging')->resetCache(); } private function _delete_flagging($flagging) { field_attach_delete('flagging', $flagging); // Remove from the cache. - flagging_load($flagging_id, TRUE); + entity_get_controller('flagging')->resetCache(); } /** From 5f135eff13c01a220b9b2c37810a7fcd15929316 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 20 Aug 2012 20:13:45 +0100 Subject: [PATCH 169/629] Issue #1740068 by kid_icarus: Fixed missing 'not' in error message. --- includes/flag.export.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 51843da..e1e6c2b 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -96,7 +96,7 @@ function flag_import_form_validate($form, &$form_state) { ob_end_clean(); if (!isset($flags) || !is_array($flags)) { - form_set_error('import', t('A valid list of flags could be found in the import code.')); + form_set_error('import', t('A valid list of flags could not be found in the import code.')); return; } From ab8e3fb8f1d17cda8601d94111d60ce5d56c6c0b Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 21 Aug 2012 23:03:28 +0100 Subject: [PATCH 170/629] Issue #1743240 by joachim: Fixed type_access_multiple() for node and comment not working with an empty array of types. --- includes/flag/flag_comment.inc | 5 +++++ includes/flag/flag_node.inc | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 4bf46c3..66e9eeb 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -53,6 +53,11 @@ class flag_comment extends flag_entity { function type_access_multiple($entity_ids, $account) { $access = array(); + // If all subtypes are allowed, we have nothing to say here. + if (empty($this->types)) { + return $access; + } + // Ensure node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_entity_id(). $query = db_select('comment', 'c'); diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index 5a61b52..d724031 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -86,6 +86,11 @@ class flag_node extends flag_entity { function type_access_multiple($entity_ids, $account = NULL) { $access = array(); + // If all subtypes are allowed, we have nothing to say here. + if (empty($this->types)) { + return $access; + } + // Ensure that only flaggable node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_entity_id(). $result = db_select('node', 'n')->fields('n', array('nid')) From 25d56ae44b3592995e07d76ed01c03430be39ee7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 22 Aug 2012 08:02:11 +0100 Subject: [PATCH 171/629] by joachim: Added documentation for hook_flag_delete() and hook_flag_reset(). --- flag.api.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/flag.api.php b/flag.api.php index c32d4c4..ff1d9d7 100644 --- a/flag.api.php +++ b/flag.api.php @@ -229,16 +229,32 @@ function hook_flag_link() { } /** - * TODO + * Act on flag deletion. + * + * This is invoked after all the flag database tables have had their relevant + * entries deleted. + * + * @param $flag + * The flag object that has been deleted. */ -function flag_delete () { +function hook_flag_delete($flag) { } /** - * TODO + * Act when a flag is reset. + * + * @param $flag + * The flag object. + * @param $entity_id + * The entity ID on which all flaggings are to be removed. May be NULL, in + * which case all of this flag's entities are to be unflagged. + * @param $rows + * Database rows from the {flagging} table. + * + * @see flag_reset_flag() */ -function hook_flag_reset() { +function hook_flag_reset($flag, $entity_id, $rows) { } From 1e32620dfaff5974e850941767f65c2a25239272 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 22 Aug 2012 08:46:37 +0100 Subject: [PATCH 172/629] Issue #1355864 by joachim: Added a Views sort handler for flagged / unflagged. --- flag.info | 1 + includes/views/flag.views.inc | 7 ++- includes/views/flag_handler_sort_flagged.inc | 47 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 includes/views/flag_handler_sort_flagged.inc diff --git a/flag.info b/flag.info index bf64556..d921c28 100644 --- a/flag.info +++ b/flag.info @@ -20,6 +20,7 @@ files[] = flag.rules.inc files[] = includes/views/flag_handler_argument_entity_id.inc files[] = includes/views/flag_handler_field_ops.inc files[] = includes/views/flag_handler_filter_flagged.inc +files[] = includes/views/flag_handler_sort_flagged.inc files[] = includes/views/flag_handler_relationships.inc files[] = includes/views/flag_plugin_argument_validate_flaggability.inc files[] = tests/flag.test diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index e8ab965..31a7ebc 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -95,11 +95,16 @@ function flag_views_data() { // Specialized is null/is not null filter. $data['flagging']['flagged'] = array( 'title' => t('Flagged'), - 'help' => t('Filter to ensure content has or has not been flagged.'), 'real field' => 'uid', 'filter' => array( 'handler' => 'flag_handler_filter_flagged', 'label' => t('Flagged'), + 'help' => t('Filter to ensure content has or has not been flagged.'), + ), + 'sort' => array( + 'handler' => 'flag_handler_sort_flagged', + 'label' => t('Flagged'), + 'help' => t('Sort by whether entities have or have not been flagged.'), ), ); diff --git a/includes/views/flag_handler_sort_flagged.inc b/includes/views/flag_handler_sort_flagged.inc new file mode 100644 index 0000000..63c2787 --- /dev/null +++ b/includes/views/flag_handler_sort_flagged.inc @@ -0,0 +1,47 @@ + t('Unflagged first'), + 'DESC' => t('Flagged first'), + ); + } + + /** + * Display whether or not the sort order is ascending or descending + */ + function admin_summary() { + if (!empty($this->options['exposed'])) { + return t('Exposed'); + } + + // Get the labels defined in sort_options(). + $sort_options = $this->sort_options(); + return $sort_options[strtoupper($this->options['order'])]; + } + + function query() { + $this->ensure_my_table(); + // Add the ordering. + // Using IS NOT NULL means that the ASC/DESC ordering work in the same + // direction as sorting by flagging date: empty results come first. + $this->query->add_orderby(NULL, "($this->table_alias.uid IS NOT NULL)", $this->options['order']); + } + +} From 365c4e9a8ffcbd4d1747a4d69fce1f7b666cab54 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 23 Aug 2012 20:18:14 +0100 Subject: [PATCH 173/629] Issue #364236 by joachim: Added views field for flagged status. --- flag.info | 1 + includes/views/flag.views.inc | 5 +++ includes/views/flag_handler_field_flagged.inc | 36 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 includes/views/flag_handler_field_flagged.inc diff --git a/flag.info b/flag.info index d921c28..a718f39 100644 --- a/flag.info +++ b/flag.info @@ -19,6 +19,7 @@ files[] = flag.rules.inc ; Views files[] = includes/views/flag_handler_argument_entity_id.inc files[] = includes/views/flag_handler_field_ops.inc +files[] = includes/views/flag_handler_field_flagged.inc files[] = includes/views/flag_handler_filter_flagged.inc files[] = includes/views/flag_handler_sort_flagged.inc files[] = includes/views/flag_handler_relationships.inc diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index 31a7ebc..a0d9965 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -96,6 +96,11 @@ function flag_views_data() { $data['flagging']['flagged'] = array( 'title' => t('Flagged'), 'real field' => 'uid', + 'field' => array( + 'handler' => 'flag_handler_field_flagged', + 'label' => t('Flagged'), + 'help' => t('A boolean field to show whether the flag is set or not.'), + ), 'filter' => array( 'handler' => 'flag_handler_filter_flagged', 'label' => t('Flagged'), diff --git a/includes/views/flag_handler_field_flagged.inc b/includes/views/flag_handler_field_flagged.inc new file mode 100644 index 0000000..660f91d --- /dev/null +++ b/includes/views/flag_handler_field_flagged.inc @@ -0,0 +1,36 @@ +formats['flag'] = array(t('Flagged'), t('Not flagged')); + // TODO: We could probably lift the '(Un)Flagged message' strings from the + // flag object, but a) we need to lift that from the relationship we're on + // and b) they will not necessarily make sense in a static context. + } + + /** + * Called to add the field to a query. + */ + function query() { + $this->ensure_my_table(); + // Add the formula. + $this->field_alias = $this->query->add_field(NULL, "($this->table_alias.uid IS NOT NULL)", 'flagging_flagged'); + + $this->add_additional_fields(); + } + +} From 95ee598b72945abd2f5d9b9b896a9bf06a4bb8d7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 24 Aug 2012 13:59:39 +0100 Subject: [PATCH 174/629] Issue #1719234 by Scyther: Added output of flag titles to the admin list. --- includes/flag.admin.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index a21d692..786bbfc 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -83,7 +83,7 @@ function theme_flag_admin_listing($variables) { } $roles = array_flip(array_intersect(array_flip(user_roles()), $flag->roles['flag'])); $row = array(); - $row[] = $flag->name; + $row[] = $flag->title . ' (' . t('Machine name: @name', array('@name' => $flag->name)) . ')'; if (count($flags) > 1) { $row[] = drupal_render($form['flags'][$flag->name]['weight']); } From 6acec7aab44d5e3d3200669cc658340d0f73c520 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 30 Aug 2012 17:28:41 +0100 Subject: [PATCH 175/629] by joachim: Fixed formatting of chained query methods. --- flag.module | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index c03bc8c..c32d6b6 100644 --- a/flag.module +++ b/flag.module @@ -1573,8 +1573,12 @@ function flag_get_flag_counts($flag_name, $reset = FALSE) { } if (!isset($counts[$flag_name])) { $flag = flag_get_flag($flag_name); - $counts[$flag_name] = db_select('flag_counts', 'fc')->fields('fc', array('flagging_id')) - ->condition('fid', $flag->fid)->countQuery()->execute()->fetchField(); + $counts[$flag_name] = db_select('flag_counts', 'fc') + ->fields('fc', array('flagging_id')) + ->condition('fid', $flag->fid) + ->countQuery() + ->execute() + ->fetchField(); } return $counts[$flag_name]; From 2c3c31fc391c7ecd5b2ef66cf6f195f422f5be38 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 30 Aug 2012 11:10:20 +0100 Subject: [PATCH 176/629] Issue #1704534 by joachim: Changed flag_get_flagged_content() to flag_get_flag_flagging_data() and key results by flagging id. --- flag.module | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/flag.module b/flag.module index c32d6b6..e2ead5e 100644 --- a/flag.module +++ b/flag.module @@ -1790,17 +1790,14 @@ function flag_get_default_flags($include_disabled = FALSE) { * @param * The flag name for which to retrieve flagged entites. */ -function flag_get_flagged_entities($flag_name) { +function flag_get_flag_flagging_data($flag_name) { $return = array(); $flag = flag_get_flag($flag_name); $result = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid) ->execute(); - foreach ($result as $row) { - $return[] = $row; - } - return $return; + return $result->fetchAllAssoc('flagging_id'); } /** From 8d76eaed744e2a9bdc0f0fa70b5c0418bf58bee6 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 2 Sep 2012 22:00:44 +0100 Subject: [PATCH 177/629] Issue #1766242 by Scyther: Added support for Admin Menu's hook_admin_menu_map(). --- flag.module | 46 +++++++++++++++++++++++++++++++++++++++++++++ flag_actions.module | 1 + 2 files changed, 47 insertions(+) diff --git a/flag.module b/flag.module index e2ead5e..97e4adb 100644 --- a/flag.module +++ b/flag.module @@ -208,6 +208,52 @@ function flag_menu() { return $items; } +/** + * Implements hook_admin_menu_map(). + */ +function flag_admin_menu_map() { + if (!user_access('administer flags')) { + return; + } + + $map = array(); + $map[FLAG_ADMIN_PATH . '/manage/%flag'] = array( + 'parent' => FLAG_ADMIN_PATH, + 'arguments' => array( + array( + '%flag' => array_keys(flag_get_flags()), + ), + ), + ); + + if (module_exists('field_ui')) { + foreach (entity_get_info() as $obj_type => $info) { + if ($obj_type == 'flagging') { + foreach ($info['bundles'] as $bundle_name => $bundle_info) { + if (isset($bundle_info['admin'])) { + $fields = array(); + + foreach (field_info_instances($obj_type, $bundle_name) as $field) { + $fields[] = $field['field_name']; + } + + $arguments = array( + '%flag' => array($bundle_name), + '%field_ui_menu' => $fields, + ); + + $path = $bundle_info['admin']['path']; + $map["$path/fields/%field_ui_menu"]['parent'] = "$path/fields"; + $map["$path/fields/%field_ui_menu"]['arguments'][] = $arguments; + } + } + } + } + } + + return $map; +} + /** * Menu loader for '%flag' arguments. * diff --git a/flag_actions.module b/flag_actions.module index 5669eb8..6992c2b 100644 --- a/flag_actions.module +++ b/flag_actions.module @@ -24,6 +24,7 @@ function flag_actions_menu() { 'access callback' => 'user_access', 'access arguments' => array('administer actions'), 'type' => MENU_LOCAL_TASK, + 'weight' => 1, ); $items[FLAG_ADMIN_PATH . '/actions/add'] = array( 'title' => 'Add action', From 3e2ff70efb85bf544640328e80a15e6ee126b938 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 2 Sep 2012 22:09:28 +0100 Subject: [PATCH 178/629] Issue #1722928 by joachim: Added support for contextual links to generic entities. --- flag.module | 22 +++++++++++++++++----- includes/flag/flag_entity.inc | 8 ++++++++ includes/flag/flag_node.inc | 7 ------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/flag.module b/flag.module index 97e4adb..aca2b04 100644 --- a/flag.module +++ b/flag.module @@ -719,20 +719,32 @@ function flag_form_alter(&$form, &$form_state, $form_id) { * Implements hook_contextual_links_view_alter(). */ function flag_contextual_links_view_alter(&$element, $items) { + if (isset($element['#element']['#entity_type'])) { + $entity_type = $element['#element']['#entity_type']; - // Check if we have a node link to process - if (isset($element['#element']['#node']->nid)) { - $node = $element['#element']['#node']; + // Get the entity out of the element. This requires a bit of legwork. + if (isset($element['#element']['#entity'])) { + // EntityAPI entities will all have the entity in the same place. + $entity = $element['#element']['#entity']; + } + elseif (isset($element['#element']['#' . $entity_type])) { + // Node module at least puts it here. + $entity = $element['#element']['#' . $entity_type]; + } + else { + // Give up. + return; + } // Get all possible flags for this entity type. - $flags = flag_get_flags('node'); + $flags = flag_get_flags($entity_type); foreach ($flags as $name => $flag) { if (!$flag->show_contextual_link) { continue; } - $entity_id = $flag->get_entity_id($node); + list($entity_id) = entity_extract_ids($entity_type, $entity); if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this // object. The link is not skipped if the user has "flag" access but diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 754597e..a813165 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -22,6 +22,7 @@ class flag_entity extends flag_flag { // @see hook_field_attach_form(). 'show_on_form' => FALSE, 'access_author' => '', + 'show_contextual_link' => FALSE, ); return $options; } @@ -56,6 +57,13 @@ class flag_entity extends flag_flag { '#default_value' => $this->show_on_form, '#access' => empty($this->locked['show_on_form']), ); + $form['display']['show_contextual_link'] = array( + '#type' => 'checkbox', + '#title' => t('Display in contextual links'), + '#default_value' => $this->show_contextual_link, + '#description' => t('Note that not all entity types support contextual links.'), + '#access' => empty($this->locked['show_contextual_link']) && module_exists('contextual'), + ); } /** diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index d724031..e6811b6 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -17,7 +17,6 @@ class flag_node extends flag_entity { 'show_on_page' => TRUE, 'show_on_teaser' => TRUE, 'show_on_form' => FALSE, - 'show_contextual_link' => FALSE, 'i18n' => 0, ); return $options; @@ -73,12 +72,6 @@ class flag_node extends flag_entity { '#title' => t('Display checkbox on node edit form'), '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), ) + $form['display']['show_on_form']; - $form['display']['show_contextual_link'] = array( - '#type' => 'checkbox', - '#title' => t('Display in contextual links'), - '#default_value' => $this->show_contextual_link, - '#access' => empty($this->locked['show_contextual_link']) && module_exists('contextual'), - ); unset($form['display']['show_on_entity']); } From 37cc9a3aa35f4d39de3601350acf7204124475d8 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 2 Sep 2012 22:17:33 +0100 Subject: [PATCH 179/629] Issue #1736450 by bartmcpherson: Fixed label for Views relationship from users to flaggings. --- includes/views/flag.views.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index a0d9965..7d0cb01 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -206,8 +206,8 @@ function flag_views_data_alter(&$data) { // Add a relationship for the user that flagged any type of content. $data['users']['flag_user_content_rel'] = array( 'group' => t('Flags'), - 'title' => t("User's flagged content"), - 'help' => t('Limit results to users that have flagged certain content.'), + 'title' => t("User's flaggings"), + 'help' => t('Relate users to the flaggings they have made on objects, using a particular flag.'), 'relationship' => array( 'base' => 'flagging', 'base field' => 'uid', From e121bab264d8c2879a92e3ba7019161a6f41455b Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 4 Sep 2012 20:58:13 +0100 Subject: [PATCH 180/629] Issue #1719748 by joachim: Removed node-specific code in flag_form(). --- includes/flag.admin.inc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 786bbfc..5ac9c70 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -379,17 +379,13 @@ function flag_form($form, &$form_state, $flag) { '#weight' => 10, ); - $options = array(); - foreach (node_type_get_types() as $node_type) { - $options[$node_type->type] = check_plain($node_type->name); - } - + // Flag classes will want to override this form element. $form['access']['types'] = array( '#type' => 'checkboxes', - '#title' => t('Flaggable content'), - '#options' => $options, + '#title' => t('Flaggable types'), + '#options' => array(), '#default_value' => $flag->types, - '#description' => t('Check any node types that this flag may be used on. You must check at least one node type.'), + '#description' => t('Check any sub-types that this flag may be used on.'), '#required' => TRUE, '#weight' => 10, '#access' => empty($flag->locked['types']), From d1118a9d72e13c22705a1ca977b9094981b24bb5 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 7 Sep 2012 08:14:19 +0100 Subject: [PATCH 181/629] Changed Flag API version to 3. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index aca2b04..7389d2e 100644 --- a/flag.module +++ b/flag.module @@ -5,7 +5,7 @@ * The Flag module. */ -define('FLAG_API_VERSION', 2); +define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); From 767823a99be9bfa02d014170005ed0c12109f682 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 7 Sep 2012 07:53:22 +0100 Subject: [PATCH 182/629] Added setting of default entity_type in factory_by_array(). --- includes/flag/flag_flag.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index b38b9c3..63f55e7 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -102,6 +102,10 @@ class flag_flag { * Create a complete flag (except an FID) from an array definition. */ static function factory_by_array($config) { + // Allow for flags with a missing entity type. + $config += array( + 'entity_type' => FALSE, + ); $flag = flag_create_handler($config['entity_type']); foreach ($config as $option => $value) { From 26611a61414b10bec7f19a5b32b157fc17611f03 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 7 Sep 2012 07:54:22 +0100 Subject: [PATCH 183/629] Added documentation to flag_create_handler(), including handling of flags with entity_type set to FALSE. --- flag.inc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/flag.inc b/flag.inc index ab3cd58..714a00d 100644 --- a/flag.inc +++ b/flag.inc @@ -90,9 +90,18 @@ function flag_get_types() { } /** - * Instantiates a new flag handler. A flag handler is more commonly know as "a - * flag". A factory method usually populates this empty flag with settings - * loaded from the database. + * Instantiates a new flag handler. + * + * A flag handler is more commonly know as "a flag". A factory method usually + * populates this empty flag with settings loaded from the database. + * + * @param $entity_type + * The entity type to create a flag handler for. This may be FALSE if the + * entity type property could not be found in the flag configuration data. + * + * @return + * A flag handler object. This may be the special class flag_broken is there is + * a problem with the flag. */ function flag_create_handler($entity_type) { $definition = flag_fetch_definition($entity_type); From 0aa7a6043934b9fa2336007b95753fbdc965a600 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 7 Sep 2012 07:54:54 +0100 Subject: [PATCH 184/629] Added label to broken flags with no known type. --- includes/flag.admin.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 5ac9c70..95b2203 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -143,7 +143,7 @@ function theme_flag_admin_listing_disabled($variables) { $rows[] = array( $flag->name, $flag->module, - $flag->entity_type, + $flag->entity_type ? $flag->entity_type : t('Unknown'), theme('links', array('links' => $ops)), ); } From c7111bc12bfe1c94c2187798f79ceaa942e575c3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 7 Sep 2012 08:15:14 +0100 Subject: [PATCH 185/629] Changed update system to use a class for each API version change; added class for API 2 flags. --- includes/flag.export.inc | 46 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/includes/flag.export.inc b/includes/flag.export.inc index e1e6c2b..c8f6716 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -237,14 +237,54 @@ function flag_update_page($flag) { * The flag object passed by reference. */ function flag_update_export(&$flag) { - // Update differences. - if (empty($flag->api_version) || $flag->api_version == 1) { + // Set the API version to 1 by default. + if (empty($flag->api_version)) { + $flag->api_version = 1; + } + + // Loop through the classes until the API version is up to date. + while ($flag->api_version != FLAG_API_VERSION) { + // Get the class for the update. + $update_class = 'FlagUpdate_' . $flag->api_version; + + // Run the update and change the API version on the flag. + $update_class::update($flag); + $flag->api_version = $update_class::$new_api_version; + } +} + +/** + * Flag update class for API 1 flags. + */ +class FlagUpdate_1 { + /** + * The API version this class updates a flag to. + */ + public static $new_api_version = 2; + + /** + * The update function for the flag. + */ + static function update(&$flag) { if (isset($flag->roles) && !isset($flag->roles['flag'])) { $flag->roles = array( 'flag' => $flag->roles, 'unflag' => $flag->roles, ); } - $flag->api_version = FLAG_API_VERSION; + } +} + +/** + * Flag update class for API 2 flags. + */ +class FlagUpdate_2 { + public static $new_api_version = 3; + + static function update(&$flag) { + if (isset($flag->content_type)) { + $flag->entity_type = $flag->content_type; + unset($flag->content_type); + } } } From c87e089e2b9dacb685ead7737e8d19d3b5833891 Mon Sep 17 00:00:00 2001 From: alasdair86 Date: Fri, 7 Sep 2012 21:07:33 +0100 Subject: [PATCH 186/629] Issue #1777498 by ACF: Fixed missing placeholder in message on flag update page. --- includes/flag.export.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.export.inc b/includes/flag.export.inc index c8f6716..9d7024a 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -219,7 +219,7 @@ function flag_export_form_submit($form, &$form_state) { */ function flag_update_page($flag) { if ($flag->is_compatible()) { - drupal_set_message(t('The flag %name is already up-to-date with the latest Flag API and does not need upgrading.')); + drupal_set_message(t('The flag %name is already up-to-date with the latest Flag API and does not need upgrading.', array('%name' => $flag->name))); drupal_goto(FLAG_ADMIN_PATH); } From f9c1553a3cef966965272396c195c45891cc72a5 Mon Sep 17 00:00:00 2001 From: alasdair86 Date: Fri, 7 Sep 2012 21:10:53 +0100 Subject: [PATCH 187/629] Issue #1777500 by ACF: Fixed typo in confirmation message when deleting a flag defined in code. --- includes/flag.admin.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 95b2203..11ebaac 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -588,7 +588,7 @@ function flag_delete_confirm($form, &$form_state, $flag) { return confirm_form($form, t('Are you sure you want to delete %title?', array('%title' => $flag->get_title())), !empty($_GET['destination']) ? $_GET['destination'] : FLAG_ADMIN_PATH, - isset($flag->module) ? t('This flag is provided by the %module module. It will loose any customizations and be disabled.', array('%module' => $flag->module)) : t('This action cannot be undone.'), + isset($flag->module) ? t('This flag is provided by the %module module. It will lose any customizations and be disabled.', array('%module' => $flag->module)) : t('This action cannot be undone.'), t('Delete'), t('Cancel') ); } From 6027a6788b4e5511c295b50a1d6c77f606975d04 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 8 Sep 2012 22:31:18 +0100 Subject: [PATCH 188/629] Issue #1724282 by joachim: Added documentation on the various ways to get a $flag object. --- includes/flag/flag_flag.inc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 63f55e7..b763d7d 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -12,6 +12,30 @@ * * This is the base class for all flag implementations. Notable derived * classes are flag_node and flag_comment. + * + * There are several ways to obtain a flag handler, operating at different + * levels. + * + * To load an existing flag that's defined in database or code, use one of: + * - flag_get_flag(), the main flag API function. + * - flag_load(), the loader for hook_menu(). + * - flag_get_flags(), the main API function for loading all flags. This calls + * flag_get_default_flags() to get flags in code. + * + * The above all use factory methods to instantiate the object for the flag and + * load in its settings from configuration. The factory methods are: + * - flag_flag::factory_by_row(), creates a flag handler from a database row. + * This is used by all the API functions above. + * - flag_flag::factory_by_array(), creates a flag handler from a configuration + * array. This is used by flag_get_default_flags() and the flag import form. + * - flag_flag::factory_by_entity_type(), creates an empty flag handler for the + * given entity type. This is used when a new or dummy flag handler is required + * and there is no configuration yet. + * + * The factory methods in turn all call the low-level function + * flag_create_handler(), which obtains the correct handler for the flag, or if + * that can't be found, the special handler flag_broken. Finally, this calls + * $flag->construct() on the new handler object. */ class flag_flag { From 75972af19f7b9504303760de28875a1431c617b1 Mon Sep 17 00:00:00 2001 From: alasdair86 Date: Sun, 9 Sep 2012 08:19:14 +0100 Subject: [PATCH 189/629] Issue #1777518 by ACF: Fixed flag export code missing a final newline. --- includes/flag.export.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 9d7024a..76e3a64 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -60,7 +60,7 @@ function flag_export_flags($flags = array(), $module = '', $indent = '') { $output .= $indent . '// Exported flag: "' . check_plain($flag->get_title()) . '"' . ".\n"; $output .= $indent . '$flags[\'' . $flag->name . '\'] = ' . (function_exists('features_var_export') ? features_var_export($new_flag, $indent) : var_export($new_flag, TRUE)) . ";\n"; } - $output .= $indent . 'return $flags;'; + $output .= $indent . 'return $flags;' . "\n"; return $output; } From 7376c28559cb5b648ce73788ec88a18c0d175ff0 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 9 Sep 2012 08:24:49 +0100 Subject: [PATCH 190/629] Issue #1778628 by joachim: Fixed uses of variable classname, unsupported on PHP 5.2. --- includes/flag.export.inc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 76e3a64..8e2a799 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -248,8 +248,11 @@ function flag_update_export(&$flag) { $update_class = 'FlagUpdate_' . $flag->api_version; // Run the update and change the API version on the flag. - $update_class::update($flag); - $flag->api_version = $update_class::$new_api_version; + // @todo: change this to work with the static class when we drop support for + // PHP 5.2: see commit d5b517. + $update_handler = new $update_class; + $update_handler->update($flag); + $flag->api_version = $update_handler->new_api_version; } } @@ -259,8 +262,10 @@ function flag_update_export(&$flag) { class FlagUpdate_1 { /** * The API version this class updates a flag to. + * + * @todo: Change this to a class constant when we drop support for PHP 5.2. */ - public static $new_api_version = 2; + public $new_api_version = 2; /** * The update function for the flag. @@ -279,7 +284,7 @@ class FlagUpdate_1 { * Flag update class for API 2 flags. */ class FlagUpdate_2 { - public static $new_api_version = 3; + public $new_api_version = 3; static function update(&$flag) { if (isset($flag->content_type)) { From 42a70e681984e856c58d38cf9547541a31a8ef6f Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 11 Sep 2012 22:26:19 +0100 Subject: [PATCH 191/629] Issue #1525242 by joachim: Changed flags access system to use user permissions rather than roles in the flag configuration. --- flag.install | 54 ++++++++++++++++ flag.module | 30 ++++++++- flag_bookmark/flag_bookmark.install | 7 ++ .../includes/flag_bookmark.views_default.inc | 5 +- includes/flag.admin.inc | 59 ++++++++++++++--- includes/flag.export.inc | 14 ++++ includes/flag/flag_entity.inc | 26 ++++++++ includes/flag/flag_flag.inc | 64 ++++++++++++++++--- includes/views/flag_handler_relationships.inc | 3 +- tests/flag.test | 31 +++++++++ 10 files changed, 268 insertions(+), 25 deletions(-) diff --git a/flag.install b/flag.install index 3fa1634..905240a 100644 --- a/flag.install +++ b/flag.install @@ -626,3 +626,57 @@ function flag_update_7304() { ) ); } + +/** + * Convert flag roles to permissions. + */ +function flag_update_7305() { + // We can't use flag_get_flags() to get all flags to act on, because that + // now looks for user permissions and we want the old roles array to convert. + // Hence we need to get flags directly from the database. + // Flags defined in code are saved in the database by flag_get_flags(), so + // this will get them too, unless the module providing them was *only just* + // installed before update.php was run. This edge case is not covered. + + $result = db_query("SELECT name, options FROM {flag}"); + $flag_data = $result->fetchAllKeyed(); + + // Note we don't call hook_flag_alter() because we don't have a complete flag. + // If your custom module does something to flag roles, it is your + // responsibility to handle upgrading your extra role data. + + foreach ($flag_data as $flag_name => $flag_options) { + $flag_options = unserialize($flag_options); + $flag_roles = $flag_options['roles']; + + foreach ($flag_roles['flag'] as $rid) { + $permission = "flag $flag_name"; + user_role_grant_permissions($rid, array($permission)); + } + foreach ($flag_roles['unflag'] as $rid) { + $permission = "unflag $flag_name"; + user_role_grant_permissions($rid, array($permission)); + } + + // Save the flag options with the roles array removed. + unset($flag_options['roles']); + db_update('flag') + ->fields(array( + 'options' => serialize($flag_options), + )) + ->condition('name', $flag_name) + ->execute(); + } + + // Flags in code will now report as overridden because the roles option is no + // longer output. Notify the user that they should update them. + if (count(module_implements('flag_default_flags'))) { + drupal_set_message(t('Flags which are defined in code with hook_flag_default_flags() or Features need to be re-exported.')); + } + + // Direct the user to read the change notice, which has more details of how + // access to flag objects has been affected. + return t('Flag roles have been converted to user permissions. Permissions have been granted to each flag based on flag roles. You should review the consequences of this in the change record.', array( + '!url' => 'http://drupal.org/node/1724256', + )); +} diff --git a/flag.module b/flag.module index 7389d2e..afb23d3 100644 --- a/flag.module +++ b/flag.module @@ -358,7 +358,7 @@ function flag_features_api() { * Implements hook_permission(). */ function flag_permission() { - return array( + $permissions = array( 'administer flags' => array( 'title' => t('Administer flags'), 'description' => t('Create and edit site-wide flags.'), @@ -369,6 +369,32 @@ function flag_permission() { 'restrict access' => TRUE, ), ); + + $flags = flag_get_flags(); + $entity_info = entity_get_info(); + // Provide flag and unflag permissions for each flag. + foreach ($flags as $flag_name => $flag) { + $permissions += $flag->get_permissions(); + } + + return $permissions; +} + +/** + * Implements hook_form_FORM_ID_alter(): user_admin_permissions. + * + * Disable permission on the permissions form that don't make sense for + * anonymous users when Session API module is not enabled. + */ +function flag_form_user_admin_permissions_alter(&$form, &$form_state, $form_id) { + if (!module_exists('session_api')) { + $flags = flag_get_flags(); + // Disable flag and unflag permission checkboxes for anonymous users. + foreach ($flags as $flag_name => $flag) { + $form['checkboxes'][DRUPAL_ANONYMOUS_RID]["flag $flag_name"]['#disabled'] = TRUE; + $form['checkboxes'][DRUPAL_ANONYMOUS_RID]["unflag $flag_name"]['#disabled'] = TRUE; + } + } } /** @@ -1738,8 +1764,8 @@ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = // Sort the list of flags by weight. uasort($flags, '_flag_compare_weight'); - // Allow modules implementing hook_flag_alter(&$flag) to modify each flag. foreach ($flags as $flag) { + // Allow modules implementing hook_flag_alter(&$flag) to modify each flag. drupal_alter('flag', $flag); } } diff --git a/flag_bookmark/flag_bookmark.install b/flag_bookmark/flag_bookmark.install index aec3f78..b67910c 100644 --- a/flag_bookmark/flag_bookmark.install +++ b/flag_bookmark/flag_bookmark.install @@ -47,6 +47,13 @@ function flag_bookmark_enable() { ); $flag->form_input($configuration); $flag->save(); + + // Clear the flag cache so the new permission is seen by core. + drupal_static_reset('flag_get_flags'); + + // Grant permissions. + $permissions = array('flag bookmarks', 'unflag bookmarks'); + user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, $permissions); } } diff --git a/flag_bookmark/includes/flag_bookmark.views_default.inc b/flag_bookmark/includes/flag_bookmark.views_default.inc index 808d59d..416ec96 100644 --- a/flag_bookmark/includes/flag_bookmark.views_default.inc +++ b/flag_bookmark/includes/flag_bookmark.views_default.inc @@ -109,9 +109,8 @@ function flag_bookmark_views_default_views() { ); $access = array( - 'type' => 'role', - 'role' => drupal_map_assoc($flag->roles['flag']), - 'perm' => '', + 'type' => 'perm', + 'perm' => 'flag bookmarks', ); // Additional fields and style options if comment exists. diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 11ebaac..ec06763 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -81,14 +81,15 @@ function theme_flag_admin_listing($variables) { if (!module_exists('field_ui')) { unset($ops['flags_fields']); } - $roles = array_flip(array_intersect(array_flip(user_roles()), $flag->roles['flag'])); + $permission = "flag $flag->name"; + $roles = user_roles(FALSE, $permission); $row = array(); $row[] = $flag->title . ' (' . t('Machine name: @name', array('@name' => $flag->name)) . ')'; if (count($flags) > 1) { $row[] = drupal_render($form['flags'][$flag->name]['weight']); } $row[] = $flag->entity_type; - $row[] = empty($flag->roles['flag']) ? '' . t('No roles') . '' : implode(', ', $roles); + $row[] = empty($roles) ? '' . t('No roles') . '' : implode(', ', $roles); $row[] = $flag->types ? implode(', ', $flag->types) : '-'; $row[] = $flag->global ? t('Yes') : t('No'); $row[] = theme('links', array('links' => $ops)); @@ -266,6 +267,7 @@ function flag_add_form_submit($form, &$form_state) { */ function flag_form($form, &$form_state, $flag) { $form['#flag'] = $flag; + $form['#flag_name'] = $flag->name; $form['title'] = array( '#type' => 'textfield', @@ -396,9 +398,26 @@ function flag_form($form, &$form_state, $flag) { $form['access']['types']['#value'] = $flag->types; } + // Load the user permissions into the flag. + if (isset($flag->fid)) { + $flag->fetch_roles(); + } + elseif (isset($flag->import_roles)) { + // Convert the roles data from old API 2 flags that have been run through + // the update system. + // @see FlagUpdate_2::update() + $flag->roles = $flag->import_roles; + } + else { + // For new flags, provide a reasonable default value. + $flag->roles = array( + 'flag' => array(DRUPAL_AUTHENTICATED_RID), + 'unflag' => array(DRUPAL_AUTHENTICATED_RID), + ); + } + $form['access']['roles'] = array( '#title' => t('Roles that may use this flag'), - '#access' => empty($flag->locked['roles']), '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), '#theme' => 'flag_form_roles', '#theme_wrappers' => array('form_element'), @@ -428,12 +447,6 @@ function flag_form($form, &$form_state, $flag) { '#parents' => array('roles', 'unflag'), ); - // Disabled access breaks checkboxes unless #value is hard coded. - if (!empty($flag->locked['roles'])) { - $form['access']['roles']['#type'] = 'value'; - $form['access']['roles']['#value'] = $flag->roles; - } - $form['access']['unflag_denied_text'] = array( '#type' => 'textfield', '#title' => t('Unflag not allowed text'), @@ -544,10 +557,38 @@ function flag_form_validate($form, &$form_state) { function flag_form_submit($form, &$form_state) { $flag = $form['#flag']; $flag->form_input($form_state['values']); + $flag->save(); $flag->enable(); drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); _flag_clear_cache(); + + // Save permissions. + // This needs to be done after the flag cache has been cleared, so that + // the new permissions are picked up by hook_permission(). + // This may need to move to the flag class when we implement extra permissions + // for different flag types: http://drupal.org/node/879988 + + // If the flag machine name as changed, clean up all the obsolete permissions. + if ($flag->name != $form['#flag_name']) { + $old_name = $form['#flag_name']; + $permissions = array("flag $old_name", "unflag $old_name"); + foreach (array_keys(user_roles()) as $rid) { + user_role_revoke_permissions($rid, $permissions); + } + } + + foreach (array_keys(user_roles(!module_exists('session_api'))) as $rid) { + // Create an array of permissions, based on the checkboxes element name. + $permissions = array( + "flag $flag->name" => $flag->roles['flag'][$rid], + "unflag $flag->name" => $flag->roles['unflag'][$rid], + ); + user_role_change_permissions($rid, $permissions); + } + // @todo: when we add database caching for flags we'll have to clear the + // cache again here. + $form_state['redirect'] = FLAG_ADMIN_PATH; } diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 8e2a799..e19f38a 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -57,6 +57,9 @@ function flag_export_flags($flags = array(), $module = '', $indent = '') { unset($new_flag['entity_info']); } + // Remove roles. + unset($new_flag['roles']); + $output .= $indent . '// Exported flag: "' . check_plain($flag->get_title()) . '"' . ".\n"; $output .= $indent . '$flags[\'' . $flag->name . '\'] = ' . (function_exists('features_var_export') ? features_var_export($new_flag, $indent) : var_export($new_flag, TRUE)) . ";\n"; } @@ -287,9 +290,20 @@ class FlagUpdate_2 { public $new_api_version = 3; static function update(&$flag) { + // Change the content_type property to entity_type. if (isset($flag->content_type)) { $flag->entity_type = $flag->content_type; unset($flag->content_type); } + + // We can't convert the flag roles data to user permissions at this point + // because the flag is disabled and hence hook_permission() doesn't see it + // to define its permissions. + // Instead, we copy it to import_roles, which the flag add form will handle + // on new flags (which this flag will behave as when it is re-enabled). + // @see flag_form() + if (isset($flag->roles)) { + $flag->import_roles = $flag->roles; + } } } diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index a813165..2e79917 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -93,6 +93,32 @@ class flag_entity extends flag_flag { return FALSE; } + /** + * Provides permissions for this flag. + * + * @return + * An array of permissions for hook_permission(). + */ + function get_permissions() { + // For entity flags, use the human label of the entity. + $entity_info = entity_get_info($this->entity_type); + $entity_label = $entity_info['label']; + return array( + "flag $this->name" => array( + 'title' => t('Flag %entity entities as %flag_title', array( + '%flag_title' => $this->title, + '%entity' => $entity_label, + )), + ), + "unflag $this->name" => array( + 'title' => t('Unflag %entity entities as %flag_title', array( + '%flag_title' => $this->title, + '%entity' => $entity_label, + )), + ), + ); + } + /** * Returns the entity id, if it already exists. */ diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index b763d7d..ab59cfe 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -85,6 +85,14 @@ class flag_flag { */ var $types = array(); + /** + * The roles array. This can be populated by fetch_roles() when needed. + */ + var $roles = array( + 'flag' => array(), + 'unflag' => array(), + ); + /** * Creates a flag from a database row. Returns it. * @@ -171,10 +179,6 @@ class flag_flag { 'unflag_denied_text' => '', // The link type used by the flag, as defined in hook_flag_link_type_info(). 'link_type' => 'toggle', - 'roles' => array( - 'flag' => array(DRUPAL_AUTHENTICATED_RID), - 'unflag' => array(DRUPAL_AUTHENTICATED_RID), - ), 'weight' => 0, ); @@ -204,6 +208,26 @@ class flag_flag { } } + /** + * Load this flag's role data from permissions. + * + * Loads an array of roles into the flag, where each key is an action ('flag' + * and 'unflag'), and each value is a flat array of role ids which may perform + * that action. + * + * This should only be used when a complete overview of a flag's permissions + * is needed. Use $flag->access or $flag->user_access() instead. + */ + function fetch_roles() { + $actions = array('flag', 'unflag'); + foreach ($actions as $action) { + // Build the permission string. + $permission = "$action $this->name"; + // We want a flat array of rids rather than $rid => $role_name. + $this->roles[$action] = array_keys(user_roles(FALSE, $permission)); + } + } + /** * Update the flag with settings entered in a form. */ @@ -213,9 +237,6 @@ class flag_flag { foreach ($form_values as $field => $value) { $this->$field = $value; } - // But checkboxes need some massaging: - $this->roles['flag'] = array_values(array_filter($this->roles['flag'])); - $this->roles['unflag'] = array_values(array_filter($this->roles['unflag'])); $this->types = array_values(array_filter($this->types)); // Clear internal titles cache: $this->get_title(NULL, TRUE); @@ -364,7 +385,28 @@ class flag_flag { } /** - * Determines whether the user has access to use this flag. + * Provides permissions for this flag. + * + * @return + * An array of permissions for hook_permission(). + */ + function get_permissions() { + return array( + "flag $this->name" => array( + 'title' => t('Flag %flag_title', array( + '%flag_title' => $this->title, + )), + ), + "unflag $this->name" => array( + 'title' => t('Unflag %flag_title', array( + '%flag_title' => $this->title, + )), + ), + ); + } + + /** + * Determines whether the user has the permission to use this flag. * * @param $action * Optional. The action to test, either "flag" or "unflag". If none given, @@ -374,6 +416,8 @@ class flag_flag { * * @return * Boolean TRUE if the user is allowed to flag/unflag. FALSE otherwise. + * + * @see flag_permission() */ function user_access($action = 'flag', $account = NULL) { if (!isset($account)) { @@ -385,8 +429,8 @@ class flag_flag { return FALSE; } - $matched_roles = array_intersect($this->roles[$action], array_keys($account->roles)); - return !empty($matched_roles) || $account->uid == 1; + $permission_string = "$action $this->name"; + return user_access($permission_string, $account); } /** diff --git a/includes/views/flag_handler_relationships.inc b/includes/views/flag_handler_relationships.inc index d409c4e..9a7c964 100644 --- a/includes/views/flag_handler_relationships.inc +++ b/includes/views/flag_handler_relationships.inc @@ -154,7 +154,8 @@ class flag_handler_relationship_content extends flag_handler_relationship { 'value' => '***CURRENT_USER***', 'numeric' => TRUE, ); - if (array_search(DRUPAL_ANONYMOUS_RID, $flag->roles['flag']) !== FALSE) { + $flag_roles = user_roles(FALSE, "flag $flag->name"); + if (isset($flag_roles[DRUPAL_ANONYMOUS_RID])) { // Disable page caching for anonymous users. drupal_page_is_cacheable(FALSE); diff --git a/tests/flag.test b/tests/flag.test index 8803507..95fc2c9 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -62,6 +62,8 @@ class FlagTestCase extends DrupalWebTestCase { flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); + // Load the roles array for checking it matches. + $flag->fetch_roles(); // Check that the flag object is in the database. $this->assertTrue($flag != FALSE, t('Flag object found in database')); @@ -71,6 +73,17 @@ class FlagTestCase extends DrupalWebTestCase { $this->assertEqual($flag->$property, $value, t('Flag property %property properly saved.', array('%property' => $property))); } + // Check permissions. + $permissions = user_role_permissions(user_roles()); + foreach ($saved['roles'] as $action => $rids) { + foreach ($rids as $rid) { + $permission_string = "$action ". $saved['name']; + $this->assertTrue(isset($permissions[$rid][$permission_string]), t('Permission %perm set for flag.', array( + '%perm' => $permission_string, + ))); + } + } + // Edit the flag through the UI. $edit = array( 'name' => drupal_strtolower($this->randomName()), @@ -99,6 +112,8 @@ class FlagTestCase extends DrupalWebTestCase { flag_get_flags(NULL, NULL, NULL, TRUE); $flag = flag_get_flag($edit['name']); + // Load the roles array for checking it matches. + $flag->fetch_roles(); // Check that the flag object is in the database. $this->assertTrue($flag != FALSE, t('Flag object found in database')); @@ -108,6 +123,22 @@ class FlagTestCase extends DrupalWebTestCase { $this->assertEqual($flag->$property, $value, t('Flag property %property properly saved.', array('%property' => $property))); } + // Clear the user access cache so our changes to permissions are noticed. + drupal_static_reset('user_access'); + drupal_static_reset('user_role_permissions'); + + // Check permissions. + $permissions = user_role_permissions(user_roles()); + + foreach ($saved['roles'] as $action => $rids) { + foreach ($rids as $rid) { + $permission_string = "$action ". $saved['name']; + $this->assertTrue(isset($permissions[$rid][$permission_string]), t('Permission %perm set for flag.', array( + '%perm' => $permission_string, + ))); + } + } + // Delete the flag through the UI. $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name . '/delete', array(), t('Delete')); flag_get_flags(NULL, NULL, NULL, TRUE); From 3c64d18f7a8488039f6b4e01b8596cb1ed923b61 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 12 Sep 2012 09:11:27 +0100 Subject: [PATCH 192/629] Issue #1722936 by joachim: Fixed flag locked property system so it doesn't get broken by flag classes' options_form(). --- includes/flag.admin.inc | 49 ++++++++++++++++++++++++---------- includes/flag/flag_comment.inc | 1 - includes/flag/flag_entity.inc | 4 +-- includes/flag/flag_node.inc | 2 -- includes/flag/flag_user.inc | 1 - 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index ec06763..dfe5427 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -276,7 +276,6 @@ function flag_form($form, &$form_state, $flag) { '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), '#maxlength' => 255, '#required' => TRUE, - '#access' => empty($flag->locked['title']), '#weight' => -3, ); @@ -286,7 +285,6 @@ function flag_form($form, &$form_state, $flag) { '#default_value' => $flag->name, '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), '#maxlength' => 32, - '#access' => empty($flag->locked['name']), '#weight' => -2, '#machine_name' => array( 'exists' => 'flag_get_flag', @@ -299,7 +297,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Global flag'), '#default_value' => $flag->global, '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), - '#access' => empty($flag->locked['global']), '#weight' => -1, ); @@ -314,7 +311,6 @@ function flag_form($form, &$form_state, $flag) { '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), '#description' => t('The text for the "flag this" link for this flag.'), '#required' => TRUE, - '#access' => empty($flag->locked['flag_short']), ); $form['messages']['flag_long'] = array( @@ -322,7 +318,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Flag link description'), '#default_value' => $flag->flag_long, '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'), - '#access' => empty($flag->locked['flag_long']), ); $form['messages']['flag_message'] = array( @@ -330,7 +325,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Flagged message'), '#default_value' => $flag->flag_message, '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - '#access' => empty($flag->locked['flag_message']), ); $form['messages']['unflag_short'] = array( @@ -339,7 +333,6 @@ function flag_form($form, &$form_state, $flag) { '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), '#description' => t('The text for the "unflag this" link for this flag.'), '#required' => TRUE, - '#access' => empty($flag->locked['unflag_short']), ); $form['messages']['unflag_long'] = array( @@ -347,7 +340,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Unflag link description'), '#default_value' => $flag->unflag_long, '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'), - '#access' => empty($flag->locked['unflag_long']), ); $form['messages']['unflag_message'] = array( @@ -355,7 +347,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Unflagged message'), '#default_value' => $flag->unflag_message, '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - '#access' => empty($flag->locked['unflag_message']), ); $form['messages']['tokens_help'] = array( @@ -390,7 +381,6 @@ function flag_form($form, &$form_state, $flag) { '#description' => t('Check any sub-types that this flag may be used on.'), '#required' => TRUE, '#weight' => 10, - '#access' => empty($flag->locked['types']), ); // Disabled access breaks checkboxes unless #value is hard coded. @@ -452,7 +442,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Unflag not allowed text'), '#default_value' => $flag->unflag_denied_text, '#description' => t('If a user is allowed to flag but not unflag, this text will be displayed after flagging. Often this is the past-tense of the link text, such as "flagged".'), - '#access' => empty($flag->locked['unflag_denied_text']), '#weight' => -1, ); @@ -473,7 +462,6 @@ function flag_form($form, &$form_state, $flag) { '#after_build' => array('flag_expand_link_option', 'flag_check_link_types'), '#default_value' => $flag->link_type, '#weight' => 2, - '#access' => empty($flag->locked['link_type']), ); $form['display']['link_options_intro'] = array( @@ -497,7 +485,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Flag confirmation message'), '#default_value' => isset($flag->flag_confirmation) ? $flag->flag_confirmation : '', '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), - '#access' => empty($flag->locked['flag_confirmation']), ); $form['display']['link_options_confirm']['unflag_confirmation'] = array( @@ -505,7 +492,6 @@ function flag_form($form, &$form_state, $flag) { '#title' => t('Unflag confirmation message'), '#default_value' => isset($flag->unflag_confirmation) ? $flag->unflag_confirmation : '', '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), - '#access' => empty($flag->locked['unflag_confirmation']), ); $form['actions'] = array( @@ -522,9 +508,44 @@ function flag_form($form, &$form_state, $flag) { $flag->options_form($form); + // Add our process handler to disable access to locked properties. + $form['#process'][] = 'flag_form_locked_process'; + return $form; } +/** + * Form process handler for locking flag properties. + * + * Flags defined in code may define an array of properties in $flag->locked that + * are to be locked and may not be edited by the user. + */ +function flag_form_locked_process($element, &$form_state, $form) { + $flag = $form['#flag']; + + // Disable access to a form element whose name matches a locked flag property. + if (isset($element['#name']) && !empty($flag->locked[$element['#name']])) { + $element['#access'] = FALSE; + } + + // Recurse into the form array. + foreach (element_children($element) as $key) { + // Workaround for Core inconvenience: setting #process here prevents an + // element's essential #process handlers from its hook_element_info() + // definition from being set in form_builder(). + // @see http://drupal.org/node/1779496 + if (isset($element[$key]['#type']) && ($info = element_info($element[$key]['#type']))) { + if (isset($info['#process'])) { + $element[$key]['#process'] = $info['#process']; + } + } + + $element[$key]['#process'][] = 'flag_form_locked_process'; + } + + return $element; +} + /** * Add/Edit flag form validate. */ diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 66e9eeb..4930d77 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -44,7 +44,6 @@ class flag_comment extends flag_entity { '#type' => 'checkbox', '#title' => t('Display link under comment'), '#default_value' => $this->show_on_comment, - '#access' => empty($this->locked['show_on_comment']), ); unset($form['display']['show_on_entity']); diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 2e79917..cd6f172 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -49,20 +49,18 @@ class flag_entity extends flag_flag { '#type' => 'checkbox', '#title' => t('Display link on entity'), '#default_value' => isset($this->show_on_entity) ? $this->show_on_entity : TRUE, - '#access' => empty($this->locked['show_on_entity']), ); $form['display']['show_on_form'] = array( '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), '#default_value' => $this->show_on_form, - '#access' => empty($this->locked['show_on_form']), ); $form['display']['show_contextual_link'] = array( '#type' => 'checkbox', '#title' => t('Display in contextual links'), '#default_value' => $this->show_contextual_link, '#description' => t('Note that not all entity types support contextual links.'), - '#access' => empty($this->locked['show_contextual_link']) && module_exists('contextual'), + '#access' => module_exists('contextual'), ); } diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index e6811b6..5a87024 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -58,14 +58,12 @@ class flag_node extends flag_entity { '#type' => 'checkbox', '#title' => t('Display link on node teaser'), '#default_value' => $this->show_on_teaser, - '#access' => empty($this->locked['show_on_teaser']), ); $form['display']['show_on_page'] = array( '#type' => 'checkbox', '#title' => t('Display link on node page'), '#default_value' => $this->show_on_page, - '#access' => empty($this->locked['show_on_page']), ); // Override the UI texts for nodes. $form['display']['show_on_form'] = array( diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc index 5c43c31..156ff96 100644 --- a/includes/flag/flag_user.inc +++ b/includes/flag/flag_user.inc @@ -41,7 +41,6 @@ class flag_user extends flag_entity { '#type' => 'checkbox', '#title' => t('Display link on user profile page'), '#default_value' => $this->show_on_profile, - '#access' => empty($this->locked['show_on_profile']), ); unset($form['display']['show_on_entity']); From 848cabfab671c668e0bd7ccf86fc31897be7b79a Mon Sep 17 00:00:00 2001 From: rashfeather Date: Thu, 13 Sep 2012 08:13:18 +0100 Subject: [PATCH 193/629] Issue #1780520 by socketwench: Removed flag_get_flags() parameter, changed reset calls to use drupal_static_reset(). --- flag.module | 6 ++---- includes/flag.admin.inc | 2 +- includes/flag/flag_flag.inc | 2 +- tests/flag.test | 6 +++--- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/flag.module b/flag.module index afb23d3..ca2779d 100644 --- a/flag.module +++ b/flag.module @@ -1709,17 +1709,15 @@ function flag_get_flag($name = NULL, $fid = NULL) { * @param $account * Optional. The user accont to filter available flags. If not set, all * flags for will this node will be returned. - * @param $reset - * Optional. Reset the internal query cache. * * @return $flags * An array of the structure [fid] = flag_object. */ -function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL, $reset = FALSE) { +function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL) { $flags = &drupal_static(__FUNCTION__); // Retrieve a list of all flags, regardless of the parameters. - if (!isset($flags) || $reset) { + if (!isset($flags)) { $flags = array(); // Database flags. diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index dfe5427..0dd2b4c 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -705,7 +705,7 @@ function _flag_clear_cache() { } // Reset our flags cache, thereby making the following code aware of the // modifications. - flag_get_flags(NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_flags'); // The title of a flag may appear in the menu (indirectly, via our "default // views"), so we need to clear the menu cache. This call also clears the // page cache, which is desirable too because the flag labels may have diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index ab59cfe..70ede01 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1314,7 +1314,7 @@ class flag_flag { $default_flag = clone $default_flag; $default_flag->fid = $this->fid; $default_flag->save(); - flag_get_flags(NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_flags'); return TRUE; } else { diff --git a/tests/flag.test b/tests/flag.test index 95fc2c9..7b21e4d 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -60,7 +60,7 @@ class FlagTestCase extends DrupalWebTestCase { $this->drupalPost(FLAG_ADMIN_PATH . '/add/node', $edit, t('Save flag')); - flag_get_flags(NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_flags'); $flag = flag_get_flag($edit['name']); // Load the roles array for checking it matches. $flag->fetch_roles(); @@ -110,7 +110,7 @@ class FlagTestCase extends DrupalWebTestCase { $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name, $edit, t('Save flag')); - flag_get_flags(NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_flags'); $flag = flag_get_flag($edit['name']); // Load the roles array for checking it matches. $flag->fetch_roles(); @@ -141,7 +141,7 @@ class FlagTestCase extends DrupalWebTestCase { // Delete the flag through the UI. $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name . '/delete', array(), t('Delete')); - flag_get_flags(NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_flags'); $this->assertFalse(flag_get_flag($flag->name), t('Flag successfully deleted.')); } From 9ae7d5951fb2f47b810ddc5dd41ab39788d44f97 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 Aug 2012 13:43:38 +0100 Subject: [PATCH 194/629] Issue #1704120 by joachim: Added database caching to info gathering functions. --- flag.inc | 19 +++++++++++++------ flag.module | 37 ++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/flag.inc b/flag.inc index 714a00d..9f8ebb3 100644 --- a/flag.inc +++ b/flag.inc @@ -59,12 +59,19 @@ function flag_flag_type_info_alter(&$definitions) { function flag_fetch_definition($entity_type = NULL) { $cache = &drupal_static(__FUNCTION__); if (!isset($definitions)) { - $definitions = module_invoke_all('flag_type_info'); - drupal_alter('flag_type_info', $definitions); - if (!isset($definitions['node'])) { - // We want our API to be available in hook_install, but our module is not - // enabled by then, so let's load our implementation directly: - $definitions += flag_flag_type_info(); + if ($cache = cache_get('flag_type_info')) { + $definitions = $cache->data; + } + else { + $definitions = module_invoke_all('flag_type_info'); + drupal_alter('flag_type_info', $definitions); + if (!isset($definitions['node'])) { + // We want our API to be available in hook_install, but our module is not + // enabled by then, so let's load our implementation directly: + $definitions += flag_flag_type_info(); + } + + cache_set('flag_type_info', $definitions); } } diff --git a/flag.module b/flag.module index ca2779d..c8e369c 100644 --- a/flag.module +++ b/flag.module @@ -2062,23 +2062,30 @@ function flag_get_link_types() { $link_types = &drupal_static(__FUNCTION__); if (!isset($link_types)) { - $link_types = array(); - foreach (module_implements('flag_link_type_info') as $module) { - $module_types = module_invoke($module, 'flag_link_type_info'); - foreach ($module_types as $type_name => $info) { - $link_types[$type_name] = $info + array( - 'module' => $module, - 'name' => $type_name, - 'title' => '', - 'description' => '', - 'options' => array(), - 'uses standard js' => TRUE, - 'uses standard css' => TRUE, - 'provides form' => FALSE, - ); + if ($cache = cache_get('flag_link_type_info')) { + $link_types = $cache->data; + } + else { + $link_types = array(); + foreach (module_implements('flag_link_type_info') as $module) { + $module_types = module_invoke($module, 'flag_link_type_info'); + foreach ($module_types as $type_name => $info) { + $link_types[$type_name] = $info + array( + 'module' => $module, + 'name' => $type_name, + 'title' => '', + 'description' => '', + 'options' => array(), + 'uses standard js' => TRUE, + 'uses standard css' => TRUE, + 'provides form' => FALSE, + ); + } } + drupal_alter('flag_link_type_info', $link_types); + + cache_set('flag_link_type_info', $link_types); } - drupal_alter('flag_link_type_info', $link_types); } return $link_types; From 7bc9ec828f619bff775e33c53248c0116aba90a7 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 Aug 2012 15:10:09 +0100 Subject: [PATCH 195/629] Issue #1524816 by joachim: Added hook_hook_info() and moved hook implementations to new flag.flag.inc file. --- flag.api.php | 8 +++++ flag.flag.inc | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ flag.inc | 53 ------------------------------ flag.module | 50 +++++++++++----------------- 4 files changed, 117 insertions(+), 84 deletions(-) create mode 100644 flag.flag.inc diff --git a/flag.api.php b/flag.api.php index ff1d9d7..4c4e962 100644 --- a/flag.api.php +++ b/flag.api.php @@ -13,6 +13,8 @@ /** * Define one or more flag types. * + * This hook may be placed in a $module.flag.inc file. + * * @return * An array whose keys are flag type names and whose values are properties of * the flag type. @@ -39,6 +41,8 @@ function hook_flag_type_info() { /** * Alter flag type definitions provided by other modules. * + * This hook may be placed in a $module.flag.inc file. + * * @param $definitions * An array of flag definitions returned by hook_flag_type_info(). */ @@ -164,6 +168,8 @@ function hook_flag_access_multiple($flag, $entity_ids, $account) { * * Link types defined here must be returned by this module's hook_flag_link(). * + * This hook may be placed in a $module.flag.inc file. + * * @return * An array of one or more types, keyed by the machine name of the type, and * where each value is a link type definition as an array with the following @@ -190,6 +196,8 @@ function hook_flag_link_type_info() { /** * Alter other modules' definitions of flag link types. * + * This hook may be placed in a $module.flag.inc file. + * * @param $link_types * An array of the link types defined by all modules. * diff --git a/flag.flag.inc b/flag.flag.inc new file mode 100644 index 0000000..09c990a --- /dev/null +++ b/flag.flag.inc @@ -0,0 +1,90 @@ + array( + 'title' => t('Nodes'), + 'description' => t("Nodes are a Drupal site's primary content."), + 'handler' => 'flag_node', + ), + 'comment' => array( + 'title' => t('Comments'), + 'description' => t('Comments are responses to node content.'), + 'handler' => 'flag_comment', + ), + 'user' => array( + 'title' => t('Users'), + 'description' => t('Users who have created accounts on your site.'), + 'handler' => 'flag_user', + ), + ); + + return $flags; +} + +/** + * Implements hook_flag_type_info_alter(). + * + * Step in and add flag types for any entities not yet catered for, using the + * basic flag_entity handler. This allows other modules to provide more + * specialized handlers for entities in hook_flag_type_info() as normal. + */ +function flag_flag_type_info_alter(&$definitions) { + foreach (entity_get_info() as $entity_type => $entity) { + // Only add flag support for entities that don't yet have them, and which + // are non-config entities. + if (!isset($definitions[$entity_type]) && empty($entity['configuration'])) { + $definitions[$entity_type] = array( + 'title' => $entity['label'], + 'description' => t('@entity-type entity', array('@entity-type' => $entity['label'])), + 'handler' => 'flag_entity', + ); + } + } +} + +/** + * Implements hook_flag_link_type_info(). + */ +function flag_flag_link_type_info() { + return array( + 'toggle' => array( + 'title' => t('JavaScript toggle'), + 'description' => t('An AJAX request will be made and degrades to type "Normal link" if JavaScript is not available.'), + 'uses standard js' => TRUE, + 'uses standard css' => TRUE, + ), + 'normal' => array( + 'title' => t('Normal link'), + 'description' => t('A normal non-JavaScript request will be made and the current page will be reloaded.'), + 'uses standard js' => FALSE, + 'uses standard css' => FALSE, + ), + 'confirm' => array( + 'title' => t('Confirmation form'), + 'description' => t('The user will be taken to a confirmation form on a separate page to confirm the flag.'), + 'options' => array( + 'flag_confirmation' => '', + 'unflag_confirmation' => '', + ), + 'uses standard js' => FALSE, + 'uses standard css' => FALSE, + 'provides form' => TRUE, + ), + ); +} diff --git a/flag.inc b/flag.inc index 9f8ebb3..082272c 100644 --- a/flag.inc +++ b/flag.inc @@ -1,58 +1,5 @@ array( - 'title' => t('Nodes'), - 'description' => t("Nodes are a Drupal site's primary content."), - 'handler' => 'flag_node', - ), - 'comment' => array( - 'title' => t('Comments'), - 'description' => t('Comments are responses to node content.'), - 'handler' => 'flag_comment', - ), - 'user' => array( - 'title' => t('Users'), - 'description' => t('Users who have created accounts on your site.'), - 'handler' => 'flag_user', - ), - ); - - return $flags; -} - -/** - * Implements hook_flag_type_info_alter(). - * - * Step in and add flag types for any entities not yet catered for, using the - * basic flag_entity handler. This allows other modules to provide more - * specialized handlers for entities in hook_flag_type_info() as normal. - */ -function flag_flag_type_info_alter(&$definitions) { - foreach (entity_get_info() as $entity_type => $entity) { - // Only add flag support for entities that don't yet have them, and which - // are non-config entities. - if (!isset($definitions[$entity_type]) && empty($entity['configuration'])) { - $definitions[$entity_type] = array( - 'title' => $entity['label'], - 'description' => t('@entity-type entity', array('@entity-type' => $entity['label'])), - 'handler' => 'flag_entity', - ); - } - } -} - /** * Returns a flag definition. */ diff --git a/flag.module b/flag.module index c8e369c..a79a0ea 100644 --- a/flag.module +++ b/flag.module @@ -330,6 +330,25 @@ function flag_init() { include_once $path . '/includes/flag.actions.inc'; } +/** + * Implements hook_hook_info(). + */ +function flag_hook_info() { + $hooks['flag_type_info'] = array( + 'group' => 'flag', + ); + $hooks['flag_type_info_alter'] = array( + 'group' => 'flag', + ); + $hooks['flag_link_type_info'] = array( + 'group' => 'flag', + ); + $hooks['flag_link_type_info_alter'] = array( + 'group' => 'flag', + ); + return $hooks; +} + /** * Implements hook_views_api(). */ @@ -449,37 +468,6 @@ function flag_flag_link($flag, $action, $entity_id) { ); } -/** - * Implements hook_flag_link_type_info(). - */ -function flag_flag_link_type_info() { - return array( - 'toggle' => array( - 'title' => t('JavaScript toggle'), - 'description' => t('An AJAX request will be made and degrades to type "Normal link" if JavaScript is not available.'), - 'uses standard js' => TRUE, - 'uses standard css' => TRUE, - ), - 'normal' => array( - 'title' => t('Normal link'), - 'description' => t('A normal non-JavaScript request will be made and the current page will be reloaded.'), - 'uses standard js' => FALSE, - 'uses standard css' => FALSE, - ), - 'confirm' => array( - 'title' => t('Confirmation form'), - 'description' => t('The user will be taken to a confirmation form on a separate page to confirm the flag.'), - 'options' => array( - 'flag_confirmation' => '', - 'unflag_confirmation' => '', - ), - 'uses standard js' => FALSE, - 'uses standard css' => FALSE, - 'provides form' => TRUE, - ), - ); -} - /** * Implements hook_field_extra_fields(). */ From 3f7f905844aeffe59ba7862db77c3bcd520b0da6 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 17 Aug 2012 08:11:57 +0100 Subject: [PATCH 196/629] Issue #1699750 by joachim: Removed flag.inc, moved functions to module file. --- flag.inc | 78 ---------------------------------------------------- flag.module | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 80 deletions(-) delete mode 100644 flag.inc diff --git a/flag.inc b/flag.inc deleted file mode 100644 index 082272c..0000000 --- a/flag.inc +++ /dev/null @@ -1,78 +0,0 @@ -data; - } - else { - $definitions = module_invoke_all('flag_type_info'); - drupal_alter('flag_type_info', $definitions); - if (!isset($definitions['node'])) { - // We want our API to be available in hook_install, but our module is not - // enabled by then, so let's load our implementation directly: - $definitions += flag_flag_type_info(); - } - - cache_set('flag_type_info', $definitions); - } - } - - if (isset($entity_type)) { - if (isset($definitions[$entity_type])) { - return $definitions[$entity_type]; - } - } - else { - return $definitions; - } -} - -/** - * Returns all flag types defined on the system. - */ -function flag_get_types() { - $types = &drupal_static(__FUNCTION__); - if (!isset($types)) { - $types = array_keys(flag_fetch_definition()); - } - return $types; -} - -/** - * Instantiates a new flag handler. - * - * A flag handler is more commonly know as "a flag". A factory method usually - * populates this empty flag with settings loaded from the database. - * - * @param $entity_type - * The entity type to create a flag handler for. This may be FALSE if the - * entity type property could not be found in the flag configuration data. - * - * @return - * A flag handler object. This may be the special class flag_broken is there is - * a problem with the flag. - */ -function flag_create_handler($entity_type) { - $definition = flag_fetch_definition($entity_type); - if (isset($definition) && class_exists($definition['handler'])) { - $handler = new $definition['handler']; - } - else { - $handler = new flag_broken; - } - $handler->entity_type = $entity_type; - $handler->construct(); - return $handler; -} - -/** - * A shortcut function to output the link URL. - */ -function _flag_url($path, $fragment = NULL, $absolute = TRUE) { - return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); -} diff --git a/flag.module b/flag.module index a79a0ea..482bca3 100644 --- a/flag.module +++ b/flag.module @@ -10,8 +10,6 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); -include_once dirname(__FILE__) . '/flag.inc'; - /** * Implements hook_entity_info(). */ @@ -349,6 +347,83 @@ function flag_hook_info() { return $hooks; } +/** + * Returns a flag definition. + */ +function flag_fetch_definition($entity_type = NULL) { + $cache = &drupal_static(__FUNCTION__); + if (!isset($definitions)) { + if ($cache = cache_get('flag_type_info')) { + $definitions = $cache->data; + } + else { + $definitions = module_invoke_all('flag_type_info'); + drupal_alter('flag_type_info', $definitions); + if (!isset($definitions['node'])) { + // We want our API to be available in hook_install, but our module is not + // enabled by then, so let's load our implementation directly: + $definitions += flag_flag_type_info(); + } + + cache_set('flag_type_info', $definitions); + } + } + + if (isset($entity_type)) { + if (isset($definitions[$entity_type])) { + return $definitions[$entity_type]; + } + } + else { + return $definitions; + } +} + +/** + * Returns all flag types defined on the system. + */ +function flag_get_types() { + $types = &drupal_static(__FUNCTION__); + if (!isset($types)) { + $types = array_keys(flag_fetch_definition()); + } + return $types; +} + +/** + * Instantiates a new flag handler. + * + * A flag handler is more commonly know as "a flag". A factory method usually + * populates this empty flag with settings loaded from the database. + * + * @param $entity_type + * The entity type to create a flag handler for. This may be FALSE if the + * entity type property could not be found in the flag configuration data. + * + * @return + * A flag handler object. This may be the special class flag_broken is there is + * a problem with the flag. + */ +function flag_create_handler($entity_type) { + $definition = flag_fetch_definition($entity_type); + if (isset($definition) && class_exists($definition['handler'])) { + $handler = new $definition['handler']; + } + else { + $handler = new flag_broken; + } + $handler->entity_type = $entity_type; + $handler->construct(); + return $handler; +} + +/** + * A shortcut function to output the link URL. + */ +function _flag_url($path, $fragment = NULL, $absolute = TRUE) { + return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); +} + /** * Implements hook_views_api(). */ From 62d6a4f50c34641a4234d216aa3494310ebdb292 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 14 Sep 2012 07:55:35 +0100 Subject: [PATCH 197/629] Issue #1784104 by joachim: Fixed flags with no content types set not appearing on node and node type forms. --- flag.module | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 482bca3..84c7976 100644 --- a/flag.module +++ b/flag.module @@ -1880,7 +1880,8 @@ function _flag_compare_weight($flag1, $flag2) { * TRUE if the flag is enabled for this type and subtype. */ function _flag_entity_enabled($flag, $entity_type, $content_subtype = NULL) { - $return = $flag->entity_type == $entity_type && (!isset($content_subtype) || in_array($content_subtype, $flag->types)); + $return = ($flag->entity_type == $entity_type) && + (!isset($content_subtype) || !count($flag->types) || in_array($content_subtype, $flag->types)); return $return; } From a832361cb49ff263a1a355a201cbe75a657035a8 Mon Sep 17 00:00:00 2001 From: kaizerking Date: Fri, 14 Sep 2012 21:21:26 +0100 Subject: [PATCH 198/629] Issue #1782118 by kaizerking: Fixed machine name of flagging form module in test for UI message. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 84c7976..eb82ca3 100644 --- a/flag.module +++ b/flag.module @@ -307,7 +307,7 @@ function flag_help($path, $arg) { $output .= t('You will also want to pick either the "Confirmation form" or the "Form" link type for your flag, or else users won\'t have a means to enter values for the fields. (In case a form isn\'t used, the fields are assigned their default values.)', array( '@form-link-type-url' => url('admin/structure/flags/manage/' . $arg[4], array('fragment' => 'edit-link-type')), )); - if (!module_exists('flag_form')) { + if (!module_exists('flagging_form')) { $output .= ' ' . t("Note: You don't have the Flagging Form module enabled. You'll have to enable it to have the \"Form\" link-type.", array( '@enable-url' => url('admin/modules'), From fe84fd7fe9a6a802ecd0bb05dba3eefd619247dd Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 16 Sep 2012 10:12:53 +0100 Subject: [PATCH 199/629] Issue #1774226 by joachim: Fixed flag_field_attach_submit() assuming it's the only entity on a form, causing errors with field collections. --- flag.module | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/flag.module b/flag.module index eb82ca3..7bdedb5 100644 --- a/flag.module +++ b/flag.module @@ -687,10 +687,17 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la * @see flag_field_attach_form(). */ function flag_field_attach_submit($entity_type, $entity, $form, &$form_state) { - // Put the form values in the entity so flag_field_attach_save() can find - // them. We can't call flag() here as new entities have no id yet. - if (isset($form_state['values']['flag'])) { - $entity->flag = $form_state['values']['flag']; + // This is invoked for each flag_field_attach_form(), but possibly more than + // once for a particular form in the case that a form is showing multiple + // entities (field collection, inline entity form). Hence we can't simply + // assume our submitted form values are in $form_state['values']['flag']. + if (isset($form['flag'])) { + $parents = $form['flag']['#parents']; + $flag_values = drupal_array_get_nested_value($form_state['values'], $parents); + + // Put the form values in the entity so flag_field_attach_save() can find + // them. We can't call flag() here as new entities have no id yet. + $entity->flag = $flag_values; } } From ae167f22b6396eeb1dab353dfe3e4cedad8f5c63 Mon Sep 17 00:00:00 2001 From: thsutton Date: Wed, 26 Sep 2012 08:10:01 +0100 Subject: [PATCH 200/629] Issue #1795132 by thsutton: Removed needless function call in flag_permission(). --- flag.module | 1 - 1 file changed, 1 deletion(-) diff --git a/flag.module b/flag.module index 7bdedb5..41f0872 100644 --- a/flag.module +++ b/flag.module @@ -465,7 +465,6 @@ function flag_permission() { ); $flags = flag_get_flags(); - $entity_info = entity_get_info(); // Provide flag and unflag permissions for each flag. foreach ($flags as $flag_name => $flag) { $permissions += $flag->get_permissions(); From 82801ca2856b905c82d6813cec186230ec89b7c0 Mon Sep 17 00:00:00 2001 From: thsutton Date: Wed, 26 Sep 2012 08:12:03 +0100 Subject: [PATCH 201/629] Issue #1795120 by thsutton: Fixed incorrect table names in hook_schema() descriptions. --- flag.install | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.install b/flag.install index 905240a..86c94dd 100644 --- a/flag.install +++ b/flag.install @@ -152,7 +152,7 @@ function flag_schema() { 'not null' => TRUE, ), 'fid' => array( - 'description' => 'The unique flag ID this object has been flagged with, from {flags}.', + 'description' => 'The unique flag ID this object has been flagged with, from {flag}.', 'type' => 'int', 'size' => 'small', 'unsigned' => TRUE, @@ -211,7 +211,7 @@ function flag_schema() { 'description' => 'The types (usually as defined in {node_type}) that are affected by a flag.', 'fields' => array( 'fid' => array( - 'description' => 'The unqiue flag ID as defined for the flag in {flags}.', + 'description' => 'The unqiue flag ID as defined for the flag in {flag}.', 'type' => 'int', 'size' => 'small', 'unsigned' => TRUE, From 59c4f626278ac716abd94162c51e629eb11b8db7 Mon Sep 17 00:00:00 2001 From: thsutton Date: Tue, 2 Oct 2012 12:27:17 +0100 Subject: [PATCH 202/629] Issue #1800676 by thsutton: Fixed typos in comments. --- flag.module | 2 +- flag.tokens.inc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 41f0872..b96ea85 100644 --- a/flag.module +++ b/flag.module @@ -2061,7 +2061,7 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid * Optional. The name of a flag if wanting a list specific to a single flag. * * @return - * If no flag name is given, an array of flaging data, keyed by the user + * If no flag name is given, an array of flagging data, keyed by the user * ID that flagged the entity. Each flagging array is structured as * an array of flag information for each flag, keyed by the flag name. If * a flag name is specified, only the information for that flag is returned. diff --git a/flag.tokens.inc b/flag.tokens.inc index 2d7dcf0..d25967d 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -43,7 +43,7 @@ function flag_token_info() { 'type' => 'date', ); - // Flage action tokens. + // Flag action tokens. $types['flag-action'] = array( 'name' => t('Flag actions'), 'description' => t('Tokens available in response to a flag action being executed by a user.'), From f2071da3c2b5ca862a33e31ae1481ff88b7a5bf8 Mon Sep 17 00:00:00 2001 From: alextataurov Date: Wed, 3 Oct 2012 07:53:17 +0100 Subject: [PATCH 203/629] Issue #1718942 by alextataurov: Removed special handling of our definitions now they are no longer needed in our own hook_install(). --- flag.module | 5 ----- 1 file changed, 5 deletions(-) diff --git a/flag.module b/flag.module index b96ea85..5c2a196 100644 --- a/flag.module +++ b/flag.module @@ -359,11 +359,6 @@ function flag_fetch_definition($entity_type = NULL) { else { $definitions = module_invoke_all('flag_type_info'); drupal_alter('flag_type_info', $definitions); - if (!isset($definitions['node'])) { - // We want our API to be available in hook_install, but our module is not - // enabled by then, so let's load our implementation directly: - $definitions += flag_flag_type_info(); - } cache_set('flag_type_info', $definitions); } From 1c263d4ab77d1e46e823cb78b2d773a130cf7e14 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 3 Oct 2012 07:56:18 +0100 Subject: [PATCH 204/629] by joachim: Fixed misleading variable name. --- flag.flag.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flag.flag.inc b/flag.flag.inc index 09c990a..54e02a6 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -45,13 +45,13 @@ function flag_flag_type_info() { * specialized handlers for entities in hook_flag_type_info() as normal. */ function flag_flag_type_info_alter(&$definitions) { - foreach (entity_get_info() as $entity_type => $entity) { + foreach (entity_get_info() as $entity_type => $entity_info) { // Only add flag support for entities that don't yet have them, and which // are non-config entities. - if (!isset($definitions[$entity_type]) && empty($entity['configuration'])) { + if (!isset($definitions[$entity_type]) && empty($entity_info['configuration'])) { $definitions[$entity_type] = array( - 'title' => $entity['label'], - 'description' => t('@entity-type entity', array('@entity-type' => $entity['label'])), + 'title' => $entity_info['label'], + 'description' => t('@entity-type entity', array('@entity-type' => $entity_info['label'])), 'handler' => 'flag_entity', ); } From dbde8f62ec8b17ff8946721e7be03a7a40b23177 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 6 Oct 2012 08:25:39 +0100 Subject: [PATCH 205/629] Issue #1097582 by joachim: Removed ability to change 'global' setting once a flag has flagging data. --- includes/flag.admin.inc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 0dd2b4c..569b24f 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -299,6 +299,14 @@ function flag_form($form, &$form_state, $flag) { '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), '#weight' => -1, ); + // Don't allow the 'global' checkbox to be changed when flaggings exist: + // there are too many unpleasant consequences in either direction. + // @todo: Allow this, but with a confirmation form, assuming anyone actually + // needs this feature. + if (!empty($flag->fid) && flag_get_flag_counts($flag->name)) { + $form['global']['#disabled'] = TRUE; + $form['global']['#description'] .= '
' . t('This setting cannot be changed when flaggings exist for this flag.'); + } $form['messages'] = array( '#type' => 'fieldset', From 80fca36d6faed545744f9bab8e838f247773c5a6 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 9 Oct 2012 20:10:09 +0100 Subject: [PATCH 206/629] Issue #1734506 by joachim: Changed help text on flagging fields admin page to make use of 'provides form' link type property and provide help relevant to the current flag's link type. --- flag.module | 64 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/flag.module b/flag.module index 5c2a196..a107ffe 100644 --- a/flag.module +++ b/flag.module @@ -301,21 +301,61 @@ function flag_help($path, $arg) { $output = '

' . t('Select the type of flag to create. An individual flag can only affect one type of object. This cannot be changed once the flag is created.') . '

'; return $output; case FLAG_ADMIN_PATH . '/manage/%/fields': + // Get the existing link types that provide a flagging form. + $link_types = flag_get_link_types(); + $form_link_types = array(); + foreach (flag_get_link_types() as $link_type) { + if ($link_type['provides form']) { + $form_link_types[] = '' . $link_type['title'] . ''; + } + } + + // Get the flag for which we're managing fields. + $flag = menu_get_object('flag', FLAG_ADMIN_PATH_START + 1); + + // Common text. $output = '

' . t('Flags can have fields added to them. For example, a "Spam" flag could have a Reason field where a user could type in why he believes the item flagged is spam. A "Bookmarks" flag could have a Folder field into which a user could arrange her bookmarks.') . '

'; $output .= '

' . t('On this page you can add fields to flags, delete them, and otherwise manage them.') . '

'; - $output .= '

'; - $output .= t('You will also want to pick either the "Confirmation form" or the "Form" link type for your flag, or else users won\'t have a means to enter values for the fields. (In case a form isn\'t used, the fields are assigned their default values.)', array( - '@form-link-type-url' => url('admin/structure/flags/manage/' . $arg[4], array('fragment' => 'edit-link-type')), - )); - if (!module_exists('flagging_form')) { - $output .= ' ' - . t("Note: You don't have the Flagging Form module enabled. You'll have to enable it to have the \"Form\" link-type.", array( - '@enable-url' => url('admin/modules'), - '@flagging-form-url' => 'http://drupal.org/project/flagging_form', - )) - . ''; + + // Three cases: + if ($flag->link_type == 'form') { + // Case 1: the current link type is the flagging form. Don't tell the + // user anything extra, all is fine. } - $output .= '

'; + elseif ($link_types[$flag->link_type]['provides form']) { + // Case 2: the current link type shows the form for creation of the + // flagging, but it not the flagging form. Tell the user they can't edit + // existing flagging fields. + $output .= t("Field values may be edited when flaggings are created because this flag's link type shows a form for the flagging. However, to edit field values on existing flaggings, you will need to set your flag to use the Flagging form link type. This is provided by the Flagging Form module.", array( + '!flagging-form-url' => 'http://drupal.org/project/flagging_form', + )); + if (!module_exists('flagging_form')) { + $output .= ' ' + . t("You do not currently have this module enabled.") + . ''; + } + $output .= '

'; + } + else { + // Case 3: the current link type does not allow access to the flagging + // form. Tell the user they should change it. + $output .= '

' . t("To allow users to enter values for fields you will need to set your flag to use one of the following link types which allow users to access the flagging form: !link-types-list. (In case a form isn't used, the fields are assigned their default values.)", array( + '!form-link-type-url' => url('admin/structure/flags/manage/' . $flag->name, array('fragment' => 'edit-link-type')), + // The list of labels from link types. These are all defined in code + // in hook_flag_link_type_info() and therefore safe to output raw. + '!link-types-list' => implode(', ', $form_link_types), + )) . '

'; + $output .= '

' . t("Additionally, to edit field values on existing flaggings, you will need to set your flag to use the Flagging form link type. This is provided by the Flagging Form module.", array( + '!flagging-form-url' => 'http://drupal.org/project/flagging_form', + )); + if (!module_exists('flagging_form')) { + $output .= ' ' + . t("You do not currently have this module enabled.") + . ''; + } + $output .= '

'; + } + return $output; } } From 22b919efbac09be947190b66e2a670b187a84ee2 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 9 Oct 2012 20:20:42 +0100 Subject: [PATCH 207/629] Issue #404150 by q0rban: Fixed unnecessary re-adding of table to views showing the 'ops' field with the 'current user' limit on the flag relationship. --- includes/views/flag_handler_field_ops.inc | 51 +++++++++++++++-------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/includes/views/flag_handler_field_ops.inc b/includes/views/flag_handler_field_ops.inc index 7203908..58830f1 100644 --- a/includes/views/flag_handler_field_ops.inc +++ b/includes/views/flag_handler_field_ops.inc @@ -74,27 +74,44 @@ class flag_handler_field_ops extends views_handler_field { // Find out if the content is flagged. We can't just peek at some field in // our loaded table because it doesn't always reflect the user browsing the // page. So we explicitly add the flagging table to find this out. - $join = new views_join(); - $join->construct('flagging', $info['views table'], $info['join field'], 'entity_id'); - $join->extra[] = array( - 'field' => 'fid', - 'value' => $flag->fid, - 'numeric' => TRUE, - ); - if (!$flag->global) { - $join->extra[] = array( - 'field' => 'uid', - 'value' => '***CURRENT_USER***', - 'numeric' => TRUE, - ); + // If the relationship is created with 'Current User' checked, we probably + // already have the appropriate join. We just need the appropriate table + // alias for that join. We look in the relationship settings to see if + // user_scope is set to 'current' to determine this. + $relationship = $this->view->relationship[$this->options['relationship']]; + if (isset($relationship->options['user_scope']) && $relationship->options['user_scope'] == 'current') { + $table_alias = $relationship->alias; + } + // Otherwise, let's set up the alias, keeping it unique for this flag in + // case there are multiple flag relationships in a single view. + else { + $table_alias = 'flagging_current_user_' . $flag->fid; + } + // Now that we have the table alias, let's see if it's already been joined + // to. If it hasn't, we'll set up a join. + if (!isset($this->query->table_queue[$table_alias])) { + $join = new views_join(); + $join->construct('flagging', $info['views table'], $info['join field'], 'entity_id'); $join->extra[] = array( - 'field' => 'sid', - 'value' => '***FLAG_CURRENT_USER_SID***', + 'field' => 'fid', + 'value' => $flag->fid, 'numeric' => TRUE, ); + if (!$flag->global) { + $join->extra[] = array( + 'field' => 'uid', + 'value' => '***CURRENT_USER***', + 'numeric' => TRUE, + ); + $join->extra[] = array( + 'field' => 'sid', + 'value' => '***FLAG_CURRENT_USER_SID***', + 'numeric' => TRUE, + ); + } + $table_alias = $this->query->add_table($table_alias, $parent, $join); } - $flag_table = $this->query->add_table('flagging', $parent, $join); - $this->aliases['is_flagged'] = $this->query->add_field($flag_table, 'entity_id'); + $this->aliases['is_flagged'] = $this->query->add_field($table_alias, 'entity_id'); // Next, find out the content ID. We can't add_field() on this table // (flagging), because its entity_id may be NULL (in case no user has From 05f67bf51690302ddf5a3f4baf0956634b3314f9 Mon Sep 17 00:00:00 2001 From: rashfeather Date: Tue, 9 Oct 2012 20:23:40 +0100 Subject: [PATCH 208/629] Issue #1475040 by socketwench: Fixed inconsistent declaration of flag_node()::type_access_multiple(). --- includes/flag/flag_node.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index 5a87024..a6f827c 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -74,7 +74,7 @@ class flag_node extends flag_entity { unset($form['display']['show_on_entity']); } - function type_access_multiple($entity_ids, $account = NULL) { + function type_access_multiple($entity_ids, $account) { $access = array(); // If all subtypes are allowed, we have nothing to say here. From bc81820553450d29eb7c4c9bbcf47a6f897c22df Mon Sep 17 00:00:00 2001 From: naxoc Date: Tue, 9 Oct 2012 20:34:52 +0100 Subject: [PATCH 209/629] Issue #1351124 by naxoc: Fixed undefined index in flag_get_entity_flags() when the given entity has no flaggings. --- flag.module | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index a107ffe..c32fc56 100644 --- a/flag.module +++ b/flag.module @@ -2112,6 +2112,7 @@ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { ->condition('entity_id', $entity_id) ->orderBy('timestamp', 'DESC') ->execute(); + $entity_flags[$entity_type][$entity_id] = array(); foreach ($result as $flag_content) { // Build a list of flaggings for all flags by user. $entity_flags[$entity_type][$entity_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; @@ -2119,8 +2120,13 @@ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { $entity_flags[$entity_type][$entity_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; } } - - return isset($flag_name) ? $entity_flags[$entity_type][$entity_id]['flags'][$flag_name] : $entity_flags[$entity_type][$entity_id]['users']; + if (empty($entity_flags[$entity_type][$entity_id])) { + return array(); + } + if (isset($flag_name)) { + return $entity_flags[$entity_type][$entity_id]['flags'][$flag_name]; + } + return $entity_flags[$entity_type][$entity_id]['users']; } /** From 1f28040c1c53423140bf8478319ac7bc08daea49 Mon Sep 17 00:00:00 2001 From: naxoc Date: Thu, 11 Oct 2012 08:52:20 +0100 Subject: [PATCH 210/629] Issue #1351124 by naxoc: (Follow-up) Fixed documentation for flag_get_entity_flags(). --- flag.module | 1 + 1 file changed, 1 insertion(+) diff --git a/flag.module b/flag.module index c32fc56..48022e5 100644 --- a/flag.module +++ b/flag.module @@ -2100,6 +2100,7 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid * ID that flagged the entity. Each flagging array is structured as * an array of flag information for each flag, keyed by the flag name. If * a flag name is specified, only the information for that flag is returned. + * If no flags were found an empty array is returned. */ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { $entity_flags = &drupal_static(__FUNCTION__, array()); From 4372263cc431886f36a185de76180f76c020ece0 Mon Sep 17 00:00:00 2001 From: thsutton Date: Sat, 13 Oct 2012 08:30:28 +0100 Subject: [PATCH 211/629] Issue #1795130 by thsutton: Fixed name of static cache variable in flag_fetch_definition(). --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 48022e5..7e9417d 100644 --- a/flag.module +++ b/flag.module @@ -391,7 +391,7 @@ function flag_hook_info() { * Returns a flag definition. */ function flag_fetch_definition($entity_type = NULL) { - $cache = &drupal_static(__FUNCTION__); + $definitions = &drupal_static(__FUNCTION__); if (!isset($definitions)) { if ($cache = cache_get('flag_type_info')) { $definitions = $cache->data; From fcc7e0291a1dbcffa909f34234cf4176b6862b83 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 14 Oct 2012 10:49:20 +0100 Subject: [PATCH 212/629] Issue #1812276 by joachim: Fixed flagging bundle condition in EFQs. --- flag.module | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/flag.module b/flag.module index 7e9417d..0931992 100644 --- a/flag.module +++ b/flag.module @@ -64,6 +64,7 @@ function flag_entity_info() { * The entity object, or FALSE if it can't be found. */ function flagging_load($flagging_id, $reset = FALSE) { + // The flag machine name is loaded in by FlaggingController::buildQuery(). $result = entity_load('flagging', array($flagging_id), array(), $reset); return reset($result); } @@ -92,6 +93,37 @@ function flagging_load($flagging_id, $reset = FALSE) { // On the one hand this succinct version is readable and nice. On the other hand, it isn't // very "correct". +/** + * Implements hook_entity_query_alter(). + * + * Converts EntityFieldQuery instances on flaggings that have an entity + * condition on bundles (flag machine names). + * + * Based on taxonomy_entity_query_alter(). + */ +function flag_entity_query_alter($query) { + $conditions = &$query->entityConditions; + + // Alter only flagging queries with bundle conditions. + if (isset($conditions['entity_type']) && $conditions['entity_type']['value'] == 'flagging' && isset($conditions['bundle'])) { + // Convert flag machine names to flag IDs. + $flags = flag_get_flags(); + $fids = array(); + if (is_array($conditions['bundle']['value'])) { + foreach ($conditions['bundle']['value'] as $flag_name) { + $fids[] = $flags[$flag_name]->fid; + } + } + else { + $flag_name = $conditions['bundle']['value']; + $fids = $flags[$flag_name]->fid; + } + + $query->propertyCondition('fid', $fids, $conditions['bundle']['operator']); + unset($conditions['bundle']); + } +} + /** * Implements hook_menu(). */ From 54457fb2e331ac20c0843e34729dd572d4c1590d Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 19 Oct 2012 08:43:27 +0100 Subject: [PATCH 213/629] Issue #1817010 by joachim: Fixed typo in array property in FlagRulesUIClass. --- flag.rules.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.rules.inc b/flag.rules.inc index cc387b5..9fdfd7b 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -81,7 +81,7 @@ class FlagRulesUIClass extends RulesDataUI implements RulesDataDirectInputFormIn '#required' => empty($info['optional']), '#multiple' => FALSE, '#default_value' => $settings[$name], - '#emtpy' => t('There is no suiting flag available.') + '#empty' => t('There is no suiting flag available.') ); return $form; } From baa061a2428ce1bd8b704f337a9782ceda5084bc Mon Sep 17 00:00:00 2001 From: JeremyFrench Date: Thu, 1 Nov 2012 11:07:54 +0000 Subject: [PATCH 214/629] Issue #1826184 by JeremyFrench: Added class to flag linkto distinguish 'unflag denied' non-links. --- flag.module | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 0931992..ab38626 100644 --- a/flag.module +++ b/flag.module @@ -1665,8 +1665,13 @@ function template_preprocess_flag(&$variables) { $variables['flag_classes_array'] = array(); $variables['flag_classes_array'][] = 'flag'; - $variables['flag_classes_array'][] = $variables['action'] . '-action'; - $variables['flag_classes_array'][] = 'flag-link-' . $flag->link_type; + if (isset($link['href'])) { + $variables['flag_classes_array'][] = $variables['action'] . '-action'; + $variables['flag_classes_array'][] = 'flag-link-' . $flag->link_type; + } + else { + $variables['flag_classes_array'][] = $variables['action'] . '-disabled'; + } if (isset($link['attributes']['class'])) { $link['attributes']['class'] = is_string($link['attributes']['class']) ? array_filter(explode(' ', $link['attributes']['class'])) : $link['attributes']['class']; $variables['flag_classes_array'] = array_merge($variables['flag_classes_array'], $link['attributes']['class']); From 383c32f155e584ed5d5df05961d0a8fa42f6258c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 2 Nov 2012 20:23:25 +0000 Subject: [PATCH 215/629] by joachim: Changed variable name. --- flag.flag.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.flag.inc b/flag.flag.inc index 54e02a6..764a218 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -16,7 +16,7 @@ */ function flag_flag_type_info() { // Entity types we specifically cater for. - $flags = array( + $definitions = array( 'node' => array( 'title' => t('Nodes'), 'description' => t("Nodes are a Drupal site's primary content."), @@ -34,7 +34,7 @@ function flag_flag_type_info() { ), ); - return $flags; + return $definitions; } /** From 698845faf6d0f83e9529fa29f169388a896fd3db Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 2 Nov 2012 20:29:01 +0000 Subject: [PATCH 216/629] by joachim: Fixed error messages caused on broken flag handler options form; added documentation. --- includes/flag.admin.inc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 569b24f..ffdf9ed 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -514,11 +514,13 @@ function flag_form($form, &$form_state, $flag) { '#weight' => 999, ); - $flag->options_form($form); - // Add our process handler to disable access to locked properties. $form['#process'][] = 'flag_form_locked_process'; + // Allow the flag handler to make additions and changes to the form. + // Note that the flag_broken handler will completely empty the form array! + $flag->options_form($form); + return $form; } From 4e0f108ea4a8cb487c0a83ab4a7e923e86a7a197 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 4 Nov 2012 19:41:19 +0000 Subject: [PATCH 217/629] Issue #1736486 by joachim: Fixed comment flags are defined when comment module is absent. --- flag.flag.inc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/flag.flag.inc b/flag.flag.inc index 764a218..254b593 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -22,11 +22,6 @@ function flag_flag_type_info() { 'description' => t("Nodes are a Drupal site's primary content."), 'handler' => 'flag_node', ), - 'comment' => array( - 'title' => t('Comments'), - 'description' => t('Comments are responses to node content.'), - 'handler' => 'flag_comment', - ), 'user' => array( 'title' => t('Users'), 'description' => t('Users who have created accounts on your site.'), @@ -34,6 +29,14 @@ function flag_flag_type_info() { ), ); + if (module_exists('comment')) { + $definitions['comment'] = array( + 'title' => t('Comments'), + 'description' => t('Comments are responses to node content.'), + 'handler' => 'flag_comment', + ); + } + return $definitions; } From 4687cabad22a6e18e8567e710927ce6b7420fe83 Mon Sep 17 00:00:00 2001 From: naxoc Date: Thu, 15 Nov 2012 21:13:47 +0000 Subject: [PATCH 218/629] Issue #1351124 by naxoc: (Follow-up) Fixed undefined index in flag_get_entity_flags() when the given entity has no flaggings. --- flag.module | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index ab38626..b9c598b 100644 --- a/flag.module +++ b/flag.module @@ -2162,7 +2162,10 @@ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { return array(); } if (isset($flag_name)) { - return $entity_flags[$entity_type][$entity_id]['flags'][$flag_name]; + if (isset($entity_flags[$entity_type][$entity_id]['flags'][$flag_name])) { + return $entity_flags[$entity_type][$entity_id]['flags'][$flag_name]; + } + return array(); } return $entity_flags[$entity_type][$entity_id]['users']; } From b7c67647788fa779cf5cb164af076afae0899b36 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 16 Nov 2012 09:04:07 +0000 Subject: [PATCH 219/629] Issue #332956 by Amitaibu, mooffie, jherencia, avr, jastraat: Added Ctools plugins for content type and access. --- flag.module | 9 ++ .../flag_is_flagged/flag_is_flagged.inc | 96 +++++++++++++++ plugins/content_types/flag_link/flag_link.inc | 115 ++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 plugins/access/flag_is_flagged/flag_is_flagged.inc create mode 100644 plugins/content_types/flag_link/flag_link.inc diff --git a/flag.module b/flag.module index b9c598b..6c9888d 100644 --- a/flag.module +++ b/flag.module @@ -2294,3 +2294,12 @@ function flag_set_sid($uid = NULL, $create = TRUE) { function flag_get_sid($uid = NULL, $create = FALSE) { return flag_set_sid($uid, $create); } + +/** + * Implements hook_ctools_plugin_directory(). + */ +function flag_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools' && !empty($plugin)) { + return "plugins/$plugin"; + } +} diff --git a/plugins/access/flag_is_flagged/flag_is_flagged.inc b/plugins/access/flag_is_flagged/flag_is_flagged.inc new file mode 100644 index 0000000..68e1021 --- /dev/null +++ b/plugins/access/flag_is_flagged/flag_is_flagged.inc @@ -0,0 +1,96 @@ + t("Entity is flagged"), + 'description' => t('Control access by whether or not an entity is flagged.'), + 'callback' => 'flag_flag_is_flagged_access_check', + 'default' => array('flag_name' => ''), + 'settings form' => 'flag_flag_is_flagged_access_settings', + 'summary' => 'flag_flag_is_flagged_access_summary', + 'get child' => 'flag_flag_is_flagged_access_get_child', + 'get children' => 'flag_flag_is_flagged_access_get_children', +); + +/* + * Implements plugin get_child callback. + */ +function flag_flag_is_flagged_access_get_child($plugin, $parent, $child) { + $plugins = flag_flag_is_flagged_access_get_children($plugin, $parent); + return $plugins[$parent . ':' . $child]; +} + +/* + * Implements plugin get_children callback. + */ +function flag_flag_is_flagged_access_get_children($plugin, $parent) { + $plugins = array(); + $entities = entity_get_info(); + + foreach ($entities as $entity_type => $info) { + if (entity_type_supports($entity_type, 'view')) { + $plugin['title'] = t('@entity_type is flagged', array('@entity_type' => $info['label'])); + $plugin['keyword'] = $entity_type; + $plugin['name'] = $parent . ':' . $entity_type; + $plugin['required context'] = new ctools_context_required(t('Entity'), $entity_type); + $plugins[$parent . ':' . $entity_type] = $plugin; + } + } + + return $plugins; +} + +/** + * Settings form. + */ +function flag_flag_is_flagged_access_settings(&$form, &$form_state, $conf) { + $options = array(); + + $plugin = $form_state['plugin']; + $entity_type = explode(':', $plugin['name']); + $entity_type = $entity_type[1]; + + foreach (flag_get_flags($entity_type) as $flag) { + $options[$flag->name] = check_plain($flag->title); + } + + $form['settings']['flag_name'] = array( + '#title' => t('Flag name'), + '#type' => 'radios', + '#options' => $options, + '#description' => t('Include only flagged content.'), + '#default_value' => $conf['flag_name'], + ); + return $form; +} + +/** + * Check for access. + */ +function flag_flag_is_flagged_access_check($conf, $context) { + $flag = flag_get_flag($conf['flag_name']); + if (!$flag || empty($context->data)) { + return FALSE; + } + + // Get the ID of the entity. + list($id) = entity_extract_ids($flag->entity_type, $context->data); + + return $flag->is_flagged($id); +} + +/** + * Provide a summary description based upon the specified context + */ +function flag_flag_is_flagged_access_summary($conf, $context) { + $flag = flag_get_flag($conf['flag_name']); + + if ($flag) { + return t('@identifier is flagged with "@flag"', array('@flag' => check_plain($flag->title), '@identifier' => $context->identifier)); + } + else { + return t('Missing/ deleted flag "@flag"', array('@flag' => $conf['flag_name'])); + } +} diff --git a/plugins/content_types/flag_link/flag_link.inc b/plugins/content_types/flag_link/flag_link.inc new file mode 100644 index 0000000..33de132 --- /dev/null +++ b/plugins/content_types/flag_link/flag_link.inc @@ -0,0 +1,115 @@ + t('Flag link'), + 'description' => t('Add a flag link of a certain flag type for entities.'), + 'defaults' => array('flag_name' => ''), + 'content type' => 'flag_flag_link_content_type_info', +); + +/** + * Get the entity content type info. + */ +function flag_flag_link_content_type_info($entity_type) { + $types = flag_flag_link_content_type_content_types(); + if (isset($types[$entity_type])) { + return $types[$entity_type]; + } +} + +/** + * Implements hook_PLUGIN_content_type_content_types(). + */ +function flag_flag_link_content_type_content_types() { + $types = array(); + $entities = entity_get_info(); + + foreach ($entities as $entity_type => $info) { + if (entity_type_supports($entity_type, 'view')) { + $types[$entity_type] = array( + 'title' => t('Flag for @entity_type', array('@entity_type' => $info['label'])), + 'category' => t('Entity'), + 'required context' => new ctools_context_required(t('Entity'), $entity_type), + ); + } + } + + return $types; +} + +/** + * Render callback. + */ +function flag_flag_link_content_type_render($subtype, $conf, $args, $context) { + $flag = flag_get_flag($conf['flag_name']); + if (!$flag) { + return; + } + + if (empty($context->data)) { + return; + } + + // Get the ID of the entity. + list($id,,) = entity_extract_ids($flag->entity_type, $context->data); + $link = flag_create_link($flag->name, $id); + + if (!$link) { + return; + } + + $block = new stdClass(); + $block->module = 'flag'; + $block->title = t('Flag link'); + $block->delta = $flag->name; + + $block->content = $link; + return $block; +} + +/** + * Form callback. + */ +function flag_flag_link_content_type_edit_form($form, &$form_state) { + $conf = $form_state['conf']; + $entity_type = $form_state['subtype_name']; + $options = array(); + + foreach (flag_get_flags($entity_type) as $flag) { + $options[$flag->name] = $flag->title; + } + + $form['flag_name'] = array( + '#type' => 'select', + '#title' => t('Flag name'), + '#default_value' => $conf['flag_name'], + '#options' => $options, + '#description' => t('Select a flag.'), + '#required' => TRUE, + '#disabled' => !$options, + ); + + return $form; +} + +/** + * Form submit. + */ +function flag_flag_link_content_type_edit_form_submit($form, &$form_state) { + // Copy everything from our defaults. + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + $form_state['conf'][$key] = $form_state['values'][$key]; + } +} + +/** + * Returns the administrative title for a flag link. + */ +function flag_flag_link_content_type_admin_title($subtype, $conf) { + if ($flag = flag_get_flag($conf['flag_name'])) { + return t('Flag link of @flag', array('@flag' => $flag->title)); + } +} From 24cd5a27430f26a5f962a5baaaf656432792f3a1 Mon Sep 17 00:00:00 2001 From: laughnan Date: Thu, 6 Dec 2012 22:32:26 +0000 Subject: [PATCH 220/629] Issue #1784112 by laughnan: Moved _flag_entity_enabled() to a method of flag base class. --- flag.module | 20 +------------------- includes/flag/flag_flag.inc | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/flag.module b/flag.module index 6c9888d..4b33bcc 100644 --- a/flag.module +++ b/flag.module @@ -1915,7 +1915,7 @@ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = // Filter out flags based on type and subtype. if (isset($entity_type) || isset($content_subtype)) { foreach ($filtered_flags as $name => $flag) { - if (!_flag_entity_enabled($flag, $entity_type, $content_subtype)) { + if (!$flag->access_entity_enabled($entity_type, $content_subtype)) { unset($filtered_flags[$name]); } } @@ -1945,24 +1945,6 @@ function _flag_compare_weight($flag1, $flag2) { return $flag1->weight < $flag2->weight ? -1 : 1; } -/** - * Utility function: Checks whether a flag applies to a certain type, and - * possibly subtype, of entity. - * - * @param $entity_type - * The type of entity being checked, usually "node". - * @param $content_subtype - * The subtype (node type) being checked. - * - * @return - * TRUE if the flag is enabled for this type and subtype. - */ -function _flag_entity_enabled($flag, $entity_type, $content_subtype = NULL) { - $return = ($flag->entity_type == $entity_type) && - (!isset($content_subtype) || !count($flag->types) || in_array($content_subtype, $flag->types)); - return $return; -} - /** * Retrieve a list of flags defined by modules. * diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 70ede01..b9aca6c 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -579,6 +579,24 @@ class flag_flag { return NULL; } + /** + * Utility function: Checks whether a flag applies to a certain type, and + * possibly subtype, of entity. + * + * @param $entity_type + * The type of entity being checked, usually "node". + * @param $content_subtype + * The subtype (node type) being checked. + * + * @return + * TRUE if the flag is enabled for this type and subtype. + */ + function access_entity_enabled($entity_type, $content_subtype = NULL) { + $return = ($this->entity_type == $entity_type) && + (!isset($content_subtype) || !count($this->types) || in_array($content_subtype, $this->types)); + return $return; + } + /** * Returns TRUE if the flag is configured to show the flag-link using hook_link. * Derived classes are likely to implement this. From de32b0099f5e034613cc5ebec3a557ded536ee3d Mon Sep 17 00:00:00 2001 From: barraponto Date: Sun, 9 Dec 2012 09:58:42 +0000 Subject: [PATCH 221/629] Issue #1817644 by barraponto: Added flag template suggestion for link type. --- includes/flag/flag_flag.inc | 1 + theme/flag.tpl.php | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index b9aca6c..abb2d8a 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1423,6 +1423,7 @@ class flag_flag { function theme_suggestions() { $suggestions = array(); $suggestions[] = 'flag__' . $this->name; + $suggestions[] = 'flag__' . $this->link_type; $suggestions[] = 'flag'; return $suggestions; } diff --git a/theme/flag.tpl.php b/theme/flag.tpl.php index fadce0b..d086f82 100644 --- a/theme/flag.tpl.php +++ b/theme/flag.tpl.php @@ -26,6 +26,11 @@ * will be boolean TRUE. This is usually used in conjunction with immedate * JavaScript-based toggling of flags. * + * Template suggestions available, listed from the most specific template to + * the least. Drupal will use the most specific template it finds: + * - flag--name.tpl.php + * - flag--link-type.tpl.php + * * NOTE: This template spaces out the tags for clarity only. When doing some * advanced theming you may have to remove all the whitespace. */ From 45570389bc5d7ff62d9046794bc4219abf9bc219 Mon Sep 17 00:00:00 2001 From: jorrit Date: Sun, 9 Dec 2012 10:04:18 +0000 Subject: [PATCH 222/629] Issue #1804228 by Jorrit: Fixed robots.txt recommendation wrong when language negotiation is domain based. --- flag.install | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flag.install b/flag.install index 86c94dd..b22ff16 100644 --- a/flag.install +++ b/flag.install @@ -56,6 +56,9 @@ function flag_requirements($phase) { if (module_exists('session_api')) { if (file_exists('./robots.txt')) { $flag_path = url('flag') . '/'; + // We don't use url() because this may return an absolute URL when + // language negotiation is set to 'domain'. + $flag_path = parse_url($flag_path, PHP_URL_PATH); $robots_string = 'Disallow: ' . $flag_path; $contents = file_get_contents('./robots.txt'); if (strpos($contents, $robots_string) === FALSE) { From 377bc66c51dadce15b9defba4c3966e0ad92718e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 11 Dec 2012 21:55:52 +0000 Subject: [PATCH 223/629] by joachim: Fixed typo and changed single quotes to double. --- flag_bookmark/includes/flag_bookmark.views_default.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag_bookmark/includes/flag_bookmark.views_default.inc b/flag_bookmark/includes/flag_bookmark.views_default.inc index 416ec96..e656ca3 100644 --- a/flag_bookmark/includes/flag_bookmark.views_default.inc +++ b/flag_bookmark/includes/flag_bookmark.views_default.inc @@ -193,7 +193,7 @@ function flag_bookmark_views_default_views() { $view = new view; $view->name = 'flag_bookmarks_tab'; - $view->description = 'Provides a tab on all user\'s profile pages containing bookmarks for that user.'; + $view->description = "Provides a tab on all users' profile pages containing bookmarks for that user."; $view->tag = 'flag'; $view->view_php = ''; $view->base_table = 'node'; @@ -246,7 +246,7 @@ function flag_bookmark_views_default_views() { $view = new view; $view->name = 'flag_' . $flag->name; - $view->description = 'A page listing the current user\'s bookmarks at /bookmarks.'; + $view->description = "A page listing the current user's bookmarks at /bookmarks."; $view->tag = 'flag'; $view->view_php = ''; $view->base_table = 'node'; From 6223d41653788acee0ad69679dfb191e8b79fe49 Mon Sep 17 00:00:00 2001 From: fago Date: Thu, 13 Dec 2012 08:51:59 +0000 Subject: [PATCH 224/629] Issue #1304790 by fago, drewish: Fixed flagging-user sub-tokens not replaced. --- includes/flag/flag_flag.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index abb2d8a..2844df5 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -635,7 +635,7 @@ class flag_flag { function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { // Get the user. if (!isset($account)) { - $account = $GLOBALS['user']; + $account = user_load($GLOBALS['user']->uid); } if (!$account) { return FALSE; From 4a0bae5ae49c3afd00ff4b37a68eff3463a8a034 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 13 Dec 2012 08:54:10 +0000 Subject: [PATCH 225/629] by joachim: Added mising comment from previous patch. --- includes/flag/flag_flag.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 2844df5..4fe3fdd 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -635,6 +635,7 @@ class flag_flag { function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { // Get the user. if (!isset($account)) { + // Load a fresh user entity as the global user entity is not complete. $account = user_load($GLOBALS['user']->uid); } if (!$account) { From 2b91f3c5b6d85995a03d8b84b72dbcfec836a33c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 13 Dec 2012 09:03:47 +0000 Subject: [PATCH 226/629] Revert "by joachim: Added mising comment from previous patch." This reverts commit 4a0bae5ae49c3afd00ff4b37a68eff3463a8a034. --- includes/flag/flag_flag.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 4fe3fdd..2844df5 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -635,7 +635,6 @@ class flag_flag { function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { // Get the user. if (!isset($account)) { - // Load a fresh user entity as the global user entity is not complete. $account = user_load($GLOBALS['user']->uid); } if (!$account) { From 08d33c56c0b6961cc377357ecedc27d4683447e6 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 13 Dec 2012 09:03:52 +0000 Subject: [PATCH 227/629] Revert "Issue #1304790 by fago, drewish: Fixed flagging-user sub-tokens not replaced." This reverts commit 6223d41653788acee0ad69679dfb191e8b79fe49. --- includes/flag/flag_flag.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 2844df5..abb2d8a 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -635,7 +635,7 @@ class flag_flag { function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { // Get the user. if (!isset($account)) { - $account = user_load($GLOBALS['user']->uid); + $account = $GLOBALS['user']; } if (!$account) { return FALSE; From e3676d71e7947cb3b360c512aac6a61cf4441a08 Mon Sep 17 00:00:00 2001 From: laughnan Date: Fri, 14 Dec 2012 19:58:50 +0000 Subject: [PATCH 228/629] Issue #1860578 by laughnan: Changed complex expression in flag_flag::access_entity_enabled() to be more readable. --- includes/flag/flag_flag.inc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index abb2d8a..26ef707 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -592,9 +592,17 @@ class flag_flag { * TRUE if the flag is enabled for this type and subtype. */ function access_entity_enabled($entity_type, $content_subtype = NULL) { - $return = ($this->entity_type == $entity_type) && - (!isset($content_subtype) || !count($this->types) || in_array($content_subtype, $this->types)); - return $return; + $entity_type_matches = ($this->entity_type == $entity_type); + $sub_type_matches = FALSE; + if (!isset($content_subtype) || !count($this->types)) { + // Subtype automatically matches if we're not asked about it, + // or if the flag applies to all subtypes. + $sub_type_matches = TRUE; + } + else { + $sub_type_matches = in_array($content_subtype, $this->types); + } + return $entity_type_matches && $sub_type_matches; } /** From f4a7af83af30f431e021909b0f91e4607f5d7c5f Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 22 Dec 2012 08:00:22 +0000 Subject: [PATCH 229/629] by joachim: Fixed missing function documentation. --- includes/flag.admin.inc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index ffdf9ed..ba25a47 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -208,6 +208,14 @@ function theme_flag_admin_page($variables) { /** * Menu callback for adding a new flag. + * + * @param $entity_type + * The entity type for the new flag, taken from the path argument. If not + * present (i.e., '/add'), a form showing all possible flag types is shown. + * Otherwise, this shows a form for adding af flag the given type. + * + * @see flag_add_form() + * @see flag_form() */ function flag_add_page($entity_type = NULL) { if (isset($entity_type)) { From a728ea521c594ed3899f4cbb4be8ac7789ce3de7 Mon Sep 17 00:00:00 2001 From: git Date: Sat, 22 Dec 2012 08:26:15 +0000 Subject: [PATCH 230/629] Issue #1373550 by timdorr: Fixed Javascript on flag links preventing event bubbling. --- theme/flag.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/theme/flag.js b/theme/flag.js index 376ccdb..86288f0 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -50,7 +50,10 @@ Drupal.flagLink = function(context) { /** * A click handler that is attached to all elements. */ - function flagClick() { + function flagClick(event) { + // Prevent the default browser click handler + event.preventDefault(); + // 'this' won't point to the element when it's inside the ajax closures, // so we reference it using a variable. var element = this; @@ -95,7 +98,6 @@ Drupal.flagLink = function(context) { $wrapper.removeClass('flag-waiting'); } }); - return false; } $('a.flag-link-toggle:not(.flag-processed)', context).addClass('flag-processed').click(flagClick); From 008ddc63748e1a738af469e08eb3f1fd7f8baca9 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 28 Dec 2012 09:23:45 +0000 Subject: [PATCH 231/629] Issue #1868236 by joachim: Fixed missing FieldUI paths after creation of first flag. --- includes/flag.admin.inc | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index ba25a47..d034f38 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -220,6 +220,8 @@ function theme_flag_admin_page($variables) { function flag_add_page($entity_type = NULL) { if (isset($entity_type)) { $flag = flag_flag::factory_by_entity_type($entity_type); + // Mark the flag as new. + $flag->is_new = TRUE; $type_info = flag_fetch_definition($entity_type); drupal_set_title(t('Add new @type flag', array('@type' => $type_info['title']))); return drupal_get_form('flag_form', $flag); @@ -600,7 +602,8 @@ function flag_form_submit($form, &$form_state) { $flag->save(); $flag->enable(); drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); - _flag_clear_cache(); + // We clear caches more vigorously if the flag was new. + _flag_clear_cache(!empty($flag->is_new)); // Save permissions. // This needs to be done after the flag cache has been cleared, so that @@ -678,7 +681,7 @@ function flag_delete_confirm_submit($form, &$form_state) { if ($form_state['values']['confirm']) { $flag->delete(); $flag->disable(); - _flag_clear_cache(); + _flag_clear_cache(TRUE); } drupal_set_message(t('Flag @name has been deleted.', array('@name' => $flag->get_title()))); $form_state['redirect'] = FLAG_ADMIN_PATH; @@ -716,14 +719,25 @@ function flag_check_link_types($element) { /** * Clears various caches when a flag is modified. + * + * @param $clear_entity_info + * Whether to also clear the entity info cache. This is needed when adding or + * deleting a flag, as this changes the bundles on the flagging entity. In + * particular, when no flags exist yet, no Field admin UI paths exist and these + * need to be created. */ -function _flag_clear_cache() { - if (module_exists('views')) { - views_invalidate_cache(); - } +function _flag_clear_cache($clear_entity_info = FALSE) { // Reset our flags cache, thereby making the following code aware of the // modifications. drupal_static_reset('flag_get_flags'); + + if ($clear_entity_info) { + entity_info_cache_clear(); + } + + if (module_exists('views')) { + views_invalidate_cache(); + } // The title of a flag may appear in the menu (indirectly, via our "default // views"), so we need to clear the menu cache. This call also clears the // page cache, which is desirable too because the flag labels may have From 1b9d9ff868fea578271c2361b3721ce1a90278c8 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 28 Dec 2012 09:26:43 +0000 Subject: [PATCH 232/629] by joachim: Changed query to be more legible. --- includes/flag/flag_flag.inc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 26ef707..4016a26 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1046,8 +1046,12 @@ class flag_flag { $sid = flag_get_sid($uid); } return db_select('flagging', 'fc')->fields('fc', array('flagging_id')) - ->condition('fid', $this->fid)->condition('uid', $uid)->condition('sid', $sid) - ->countQuery()->execute()->fetchField(); + ->condition('fid', $this->fid) + ->condition('uid', $uid) + ->condition('sid', $sid) + ->countQuery() + ->execute() + ->fetchField(); } /** From 637a4139fb7bc9c5d5536e3cc51bcdbb93d86210 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 28 Dec 2012 21:19:48 +0000 Subject: [PATCH 233/629] Issue #1875854 by joachim: Removed #after_build for radio button descriptions; not needed on D7. --- includes/flag.admin.inc | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index d034f38..d84d530 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -475,12 +475,22 @@ function flag_form($form, &$form_state, $flag) { '#type' => 'radios', '#title' => t('Link type'), '#options' => _flag_link_type_options(), - '#option_descriptions' => _flag_link_type_descriptions(), '#flag_link_fields' => _flag_link_type_fields(), - '#after_build' => array('flag_expand_link_option', 'flag_check_link_types'), + '#after_build' => array('flag_check_link_types'), '#default_value' => $flag->link_type, '#weight' => 2, + '#attached' => array( + 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), + ), + '#attributes' => array( + 'class' => array('flag-link-options'), + ), ); + // Add the descriptions to each ratio button element. These attach to the + // elements when FormAPI expands them. + foreach (_flag_link_type_descriptions() as $key => $description) { + $form['display']['link_type'][$key]['#description'] = $description; + } $form['display']['link_options_intro'] = array( '#markup' => '', @@ -687,25 +697,6 @@ function flag_delete_confirm_submit($form, &$form_state) { $form_state['redirect'] = FLAG_ADMIN_PATH; } -/** - * FormAPI after_build function to add descriptions to radio buttons. - */ -function flag_expand_link_option($element) { - $element['#attached'] = array( - 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), - ); - - foreach (element_children($element) as $key) { - // Add a description to the link option. - if (isset($element['#option_descriptions'][$key])) { - $element[$key]['#description'] = $element['#option_descriptions'][$key]; - } - } - $element['#attributes']['class'] = array('flag-link-options'); - - return $element; -} - /** * FormAPI after_build function to check that the link type exists. */ From 14ee66339760448b1f845f9cc1f7e0c16987089f Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 30 Dec 2012 20:59:06 +0000 Subject: [PATCH 234/629] Issue #1367268 by joachim: Fixed whitespace around flag name not trimmed on submission. --- includes/flag.admin.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index d84d530..e3cfd4d 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -580,6 +580,7 @@ function flag_form_locked_process($element, &$form_state, $form) { * Add/Edit flag form validate. */ function flag_form_validate($form, &$form_state) { + $form_state['values']['title'] = trim($form_state['values']['title']); $form_values = $form_state['values']; if ($form_values['link_type'] == 'confirm') { @@ -607,6 +608,8 @@ function flag_form_validate($form, &$form_state) { */ function flag_form_submit($form, &$form_state) { $flag = $form['#flag']; + + $form_state['values']['title'] = trim($form_state['values']['title']); $flag->form_input($form_state['values']); $flag->save(); From 0980ba2c3d35c912d0fe0b73df5ce4d2fee221c2 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 31 Dec 2012 16:33:25 +0000 Subject: [PATCH 235/629] by joachim: Changed notice about taxonomy entity view now fix for Drupal core bug #1067120 is released. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 4b33bcc..372bc24 100644 --- a/flag.module +++ b/flag.module @@ -927,7 +927,7 @@ function flag_contextual_links_view_alter(&$element, $items) { * * Handles the 'show_on_entity' flag option. * - * Note this is broken for taxonomy terms. @see http://drupal.org/node/1067120 + * Note this is broken for taxonomy terms for version of Drupal core < 7.17. */ function flag_entity_view($entity, $type, $view_mode, $langcode) { $links = flag_link($type, $entity, $view_mode == 'teaser'); From 024c5c25534ee1a58b3647d21c9c8591839db402 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 30 Dec 2012 21:38:12 +0000 Subject: [PATCH 236/629] Issue #1784382 by joachim: Fixed entities unable to show edit form checkbox showing the option in flag admin form. --- includes/flag/flag_entity.inc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index cd6f172..f706028 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -55,6 +55,14 @@ class flag_entity extends flag_flag { '#title' => t('Display checkbox on entity edit form'), '#default_value' => $this->show_on_form, ); + // We use FieldAPI to put the flag checkbox on the entity form, so therefore + // require the entity to be fielable. Since this is a potential DX + // headscratcher for a developer wondering where this option has gone, + // we disable it and explain why. + if (empty($entity_info['fieldable'])) { + $form['display']['show_on_form']['#disabled'] = TRUE; + $form['display']['show_on_form']['#description'] = t('This is only possible on entities which are fieldable.'); + } $form['display']['show_contextual_link'] = array( '#type' => 'checkbox', '#title' => t('Display in contextual links'), From 29aa3d678230c8bac46fdaafff8c06e1df86bae8 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 30 Dec 2012 21:03:55 +0000 Subject: [PATCH 237/629] Issue #1793744 by joachim: Moved flag_link() to follow flag_entity_view(); added docs now it is no longer a hook implementation. --- flag.module | 90 +++++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/flag.module b/flag.module index 372bc24..e5cee50 100644 --- a/flag.module +++ b/flag.module @@ -557,47 +557,6 @@ function flag_form_user_admin_permissions_alter(&$form, &$form_state, $form_id) } } -/** - * Implements hook_link(). - * - * This hook does not exist in Drupal 7, it is called from flag_entity_view(). - */ -function flag_link($type, $object = NULL, $teaser = FALSE) { - if (!isset($object) || !flag_fetch_definition($type)) { - return; - } - global $user; - - // Get all possible flags for this entity type. - $flags = flag_get_flags($type); - - foreach ($flags as $flag) { - $entity_id = $flag->get_entity_id($object); - - if (!$flag->uses_hook_link($teaser)) { - // Flag is not configured to show its link here. - continue; - } - if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { - // User has no permission to use this flag or flag does not apply to this - // entity. The link is not skipped if the user has "flag" access but - // not "unflag" access (this way the unflag denied message is shown). - continue; - } - - // The flag links are actually fully rendered theme functions. - // The HTML attribute is set to TRUE to allow whatever the themer desires. - $links['flag-' . $flag->name] = array( - 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), - 'html' => TRUE, - ); - } - - if (isset($links)) { - return $links; - } -} - /** * Implements hook_flag_link(). */ @@ -940,6 +899,55 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { } } +/** + * Creates an array of links for all the flags of given entity. + * + * @param $type + * The entity type. + * @param $entity + * The entity + * @param $teaser + * Boolean indicating whether the current view mode is 'teaser'. + * + * @return + * An array of link data, suitable for passing to theme_links(). + */ +function flag_link($type, $entity = NULL, $teaser = FALSE) { + if (!isset($entity) || !flag_fetch_definition($type)) { + return; + } + global $user; + + // Get all possible flags for this entity type. + $flags = flag_get_flags($type); + + foreach ($flags as $flag) { + $entity_id = $flag->get_entity_id($entity); + + if (!$flag->uses_hook_link($teaser)) { + // Flag is not configured to show its link here. + continue; + } + if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { + // User has no permission to use this flag or flag does not apply to this + // entity. The link is not skipped if the user has "flag" access but + // not "unflag" access (this way the unflag denied message is shown). + continue; + } + + // The flag links are actually fully rendered theme functions. + // The HTML attribute is set to TRUE to allow whatever the themer desires. + $links['flag-' . $flag->name] = array( + 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), + 'html' => TRUE, + ); + } + + if (isset($links)) { + return $links; + } +} + /** * Implements hook_node_insert(). */ From 92891acc7cd51837c0d34470fedf872409963ebd Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 1 Jan 2013 16:42:28 +0000 Subject: [PATCH 238/629] Issue #1877448 by joachim: Changed update system to have clearer class names and allow API point versions. --- includes/flag.export.inc | 61 +++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/includes/flag.export.inc b/includes/flag.export.inc index e19f38a..1501407 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -240,34 +240,67 @@ function flag_update_page($flag) { * The flag object passed by reference. */ function flag_update_export(&$flag) { - // Set the API version to 1 by default. + // Set the API version to 1 by default: version 1 did not explicitly define + // the API version. if (empty($flag->api_version)) { $flag->api_version = 1; } - // Loop through the classes until the API version is up to date. - while ($flag->api_version != FLAG_API_VERSION) { - // Get the class for the update. - $update_class = 'FlagUpdate_' . $flag->api_version; + // Get all our update classes. + // This is not terribly graceful, but the alternative is declaring our classes + // explicitly, or registering them with the Drupal autoloader and then running + // a database query, which seems a waste of space given we only ever need + // these here. + $classes = get_declared_classes(); + $update_handlers = array(); + foreach ($classes as $class) { + // Any class whose name is of the form 'FlagUpdate_foo' is one of ours, we + // assume. Should this prove problematic, we can add use of reflection here. + if (substr($class, 0, 11) == 'FlagUpdate_') { + // @todo: change this to work with the static class when we drop support + // for PHP 5.2: see commit d5b517. + $update_handler = new $class; + // Cast to string, as decimals as array keys seem to be rounded down to + // ints, WTF PHP? + $version = (string) $update_handler->old_api_version; + + $update_handlers[$version] = $update_handler; + } + } + // Sort the classes by old version number. + uksort($update_handlers, 'version_compare'); + + // Work through each update handler. + foreach ($update_handlers as $old_api_version => $update_handler) { + // Skip update classes that are older than our current flag. + if (version_compare($old_api_version, $flag->api_version, '<')) { + continue; + } // Run the update and change the API version on the flag. - // @todo: change this to work with the static class when we drop support for - // PHP 5.2: see commit d5b517. - $update_handler = new $update_class; $update_handler->update($flag); $flag->api_version = $update_handler->new_api_version; } } /** - * Flag update class for API 1 flags. + * Flag update class for API 1 flags -> API 2. + * + * The class name after the prefix is immaterial, though we follow the Drupal + * system update convention whereby the number here is what we update to. */ -class FlagUpdate_1 { +class FlagUpdate_2 { + /** - * The API version this class updates a flag to. + * The API version this class updates a flag from. * * @todo: Change this to a class constant when we drop support for PHP 5.2. */ + public $old_api_version = 1; + + /** + * The API version this class updates a flag to. + */ public $new_api_version = 2; /** @@ -284,9 +317,11 @@ class FlagUpdate_1 { } /** - * Flag update class for API 2 flags. + * Flag update class for API 2 flags -> API 3. */ -class FlagUpdate_2 { +class FlagUpdate_3 { + + public $old_api_version = 2; public $new_api_version = 3; static function update(&$flag) { From bc4d080d0bc467a845a69e48bfe74268b0c5e50d Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 1 Jan 2013 16:49:05 +0000 Subject: [PATCH 239/629] Issue #1877378 by joachim: Fixed incorrect documentation in flag_flag()::theme(). --- includes/flag/flag_flag.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 4016a26..d69a008 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1392,7 +1392,7 @@ class flag_flag { * Renders a flag/unflag link. This is a wrapper around theme('flag') that, * in Drupal 6, easily channels the call to the right template file. * - * For parameters docmentation, see theme_flag(). + * For parameters documentation, see flag.tpl.php. */ function theme($action, $entity_id, $after_flagging = FALSE) { static $js_added = array(); From 2876edae2f4fa275627c7732a71fbbd333cfdfe0 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 2 Jan 2013 11:04:57 +0000 Subject: [PATCH 240/629] Issue #1717672 by joachim: Added tests for basic access to flagging and unflagging. --- tests/flag.test | 141 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 5 deletions(-) diff --git a/tests/flag.test b/tests/flag.test index 7b21e4d..5302b7c 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -5,7 +5,7 @@ * Tests for the Flag module. */ -class FlagTestCase extends DrupalWebTestCase { +class FlagAdminTestCase extends DrupalWebTestCase { var $_flag = FALSE; /** @@ -13,7 +13,7 @@ class FlagTestCase extends DrupalWebTestCase { */ public static function getInfo() { return array( - 'name' => t('Flag tests'), + 'name' => t('Flag admin tests'), 'description' => t('Add, edit and delete flags.'), 'group' => t('Flag'), ); @@ -145,12 +145,143 @@ class FlagTestCase extends DrupalWebTestCase { $this->assertFalse(flag_get_flag($flag->name), t('Flag successfully deleted.')); } +} + +class FlagAccessTestCase extends DrupalWebTestCase { + /** - * Test that only allowed users have access to flags. + * Implements getInfo(). */ - function testFlagAccess() { + public static function getInfo() { + return array( + 'name' => t('Flag access tests'), + 'description' => t('Access to flag and unflag entities.'), + 'group' => t('Flag'), + ); + } + + /** + * Implements setUp(). + */ + function setUp() { + parent::setUp('flag'); + // Create a test flag on article nodes. + $flag_data = array( + 'entity_type' => 'node', + 'name' => 'test_flag', + 'title' => 'Test Flag', + 'global' => 0, + 'types' => array( + 0 => 'article', + ), + 'flag_short' => 'Flag this item', + 'flag_long' => '', + 'flag_message' => '', + 'unflag_short' => 'Unflag this item', + 'unflag_long' => '', + 'unflag_message' => '', + 'unflag_denied_text' => 'You may not unflag this item', + // Use the normal link type as it involves no intermediary page loads. + 'link_type' => 'normal', + 'weight' => 0, + 'show_on_form' => 0, + 'access_author' => '', + 'show_contextual_link' => 0, + 'show_on_page' => 1, + 'show_on_teaser' => 1, + 'i18n' => 0, + 'api_version' => 3, + ); + $flag = flag_flag::factory_by_array($flag_data); + $flag->save(); + // Reset our cache so our permissions show up. + drupal_static_reset('flag_get_flags'); + + // Reset permissions so that permissions for this flag are available. + $this->checkPermissions(array(), TRUE); + + // Create an article node that various users will try to flag. + $title = $this->randomName(8); + $node = array( + 'title' => $title, + 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), + 'uid' => 1, + 'type' => 'article', + 'is_new' => TRUE, + ); + $node = node_submit((object) $node); + node_save($node); + $this->nid = $node->nid; } -} + /** + * Test that a user without flag access can't see the flag. + */ + function testFlagAccessNone() { + // Create test user who can't flag at all. + $no_flag_user = $this->drupalCreateUser(array()); + $this->drupalLogin($no_flag_user); + + // Clear the user access cache so our changes to permissions are noticed. + drupal_static_reset('user_access'); + drupal_static_reset('user_role_permissions'); + + // Look at our node. + $this->drupalGet('node/' . $this->nid); + $this->assertNoLink('Flag this item', 0, 'The flag link does not appear on the page'); + } + + /** + * Test that a user with only flag access can flag but not unflag. + */ + function testFlagAccessFlagOnly() { + // Create test user who can flag but not unflag. + $flag_user = $this->drupalCreateUser(array('flag test_flag',)); + $this->drupalLogin($flag_user); + + // Clear the user access cache so our changes to permissions are noticed. + drupal_static_reset('user_access'); + drupal_static_reset('user_role_permissions'); + + // Look at our node. + $this->drupalGet('node/' . $this->nid); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); + + // Click the link to flag the node. + $this->clickLink(t('Flag this item')); + + $this->assertText('You may not unflag this item', 0, 'The unflag denied text appears on the page after flagging.'); + } + + /** + * Test that a user with flag access can flag and unflag. + */ + function testFlagAccessFlagUnflag() { + // Create test user who can flag and unflag. + $flag_unflag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); + $this->drupalLogin($flag_unflag_user); + + // Clear the user access cache so our changes to permissions are noticed. + drupal_static_reset('user_access'); + drupal_static_reset('user_role_permissions'); + + // Look at our node. + $this->drupalGet('node/' . $this->nid); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); + + // Click the link to flag the node. + $this->clickLink(t('Flag this item')); + + $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); + + // Click the link to unflag the node. + $this->clickLink(t('Unflag this item')); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); + } + +} From 3b0997a139b453ed3c1385f3c94065c18b1d0f6d Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 2 Jan 2013 20:43:07 +0000 Subject: [PATCH 241/629] Issue #1878296 by joachim: Added tests for the confirm form link type. --- tests/flag.test | 119 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/tests/flag.test b/tests/flag.test index 5302b7c..d3d2375 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -285,3 +285,122 @@ class FlagAccessTestCase extends DrupalWebTestCase { } } + +class FlagLinkTypeConfirmTestCase extends DrupalWebTestCase { + + /** + * Implements getInfo(). + */ + public static function getInfo() { + return array( + 'name' => t('Flag confirm link tests'), + 'description' => t('Flag confirm form link type.'), + 'group' => t('Flag'), + ); + } + + /** + * Implements setUp(). + */ + function setUp() { + parent::setUp('flag'); + + // Create a test flag on article nodes. + // Keep the original data so we can compare strings. + $this->flag_data = array( + 'entity_type' => 'node', + 'name' => 'test_flag', + 'title' => 'Test Flag', + 'global' => 0, + 'types' => array( + 0 => 'article', + ), + 'flag_short' => 'Flag this item', + 'flag_long' => '', + 'flag_message' => 'You have flagged this item.', + 'unflag_short' => 'Unflag this item', + 'unflag_long' => '', + 'unflag_message' => 'You have unflagged this item', + 'unflag_denied_text' => 'You may not unflag this item', + 'link_type' => 'confirm', + 'flag_confirmation' => 'Are you sure you want to flag this item?', + 'unflag_confirmation' => 'Are you sure you want to unflag this item?', + 'weight' => 0, + 'show_on_form' => 0, + 'access_author' => '', + 'show_contextual_link' => 0, + 'show_on_page' => 1, + 'show_on_teaser' => 1, + 'i18n' => 0, + 'api_version' => 3, + ); + $flag = flag_flag::factory_by_array($this->flag_data); + $flag->save(); + // Reset our cache so our permissions show up. + drupal_static_reset('flag_get_flags'); + + // Reset permissions so that permissions for this flag are available. + $this->checkPermissions(array(), TRUE); + + // Create test user who can flag and unflag. + $flag_unflag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); + $this->drupalLogin($flag_unflag_user); + + // Create an article node to flag and unflag. + $title = $this->randomName(8); + $node = array( + 'title' => $title, + 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), + 'uid' => 1, + 'type' => 'article', + 'is_new' => TRUE, + ); + $node = node_submit((object) $node); + node_save($node); + $this->nid = $node->nid; + } + + /** + * Test that a user sees the flag confirm form. + */ + function testFlag() { + // Look at our node. + $this->drupalGet('node/' . $this->nid); + + $this->assertLink($this->flag_data['flag_short'], 0, 'The flag link appears on the page'); + + // Click the link to flag the node. + $this->clickLink($this->flag_data['flag_short']); + + $this->assertUrl('flag/confirm/flag/test_flag/' . $this->nid, array( + 'query' => array( + 'destination' => 'node/' . $this->nid, + ), + ), 'On confirm flagging form page.'); + + $this->assertText($this->flag_data['flag_confirmation'], 'The flag confirmation text appears as the confirmation page title.'); + + // Click the button to confirm the flagging. + $this->drupalPost(NULL, array(), $this->flag_data['flag_short']); + + $this->assertText($this->flag_data['flag_message'], 'The flag message appears once the item has been flagged.'); + $this->assertLink($this->flag_data['unflag_short'], 0, 'The unflag link appears once the item has been flagged.'); + + // Click the link to unflag the node. + $this->clickLink($this->flag_data['unflag_short']); + + $this->assertUrl('flag/confirm/unflag/test_flag/' . $this->nid, array( + 'query' => array( + 'destination' => 'node/' . $this->nid, + ), + ), t('On confirm unflagging form page.')); + + $this->assertText($this->flag_data['unflag_confirmation'], 'The unflag confirmation text appears as the confirmation page title.'); + + // Click the button to confirm the flagging. + $this->drupalPost(NULL, array(), $this->flag_data['unflag_short']); + + $this->assertText($this->flag_data['unflag_message'], 'The unflag message appears once the item has been flagged.'); + } + +} From a276a3d91a55f75fb98a244eeb09bbf46f81f15a Mon Sep 17 00:00:00 2001 From: csdco Date: Wed, 2 Jan 2013 20:47:01 +0000 Subject: [PATCH 242/629] Issue #1877290 by csdco: Fixed flag_init() not using module_load_include(). --- flag.module | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/flag.module b/flag.module index e5cee50..4484a05 100644 --- a/flag.module +++ b/flag.module @@ -396,8 +396,7 @@ function flag_help($path, $arg) { * Implements hook_init(). */ function flag_init() { - $path = drupal_get_path('module', 'flag'); - include_once $path . '/includes/flag.actions.inc'; + module_load_include('inc', 'flag', 'includes/flag.actions'); } /** From c6bb71b6adf7f907b10441dcf0548f914646fb27 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 2 Jan 2013 22:22:17 +0000 Subject: [PATCH 243/629] Issue #887360 by joachim: Changed forms to standardize the way $flag is passed to submit handlers. --- includes/flag.admin.inc | 4 ++-- includes/flag.pages.inc | 9 ++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index e3cfd4d..1e09e4b 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -679,7 +679,7 @@ function theme_flag_form_roles($variables) { * Delete flag page. */ function flag_delete_confirm($form, &$form_state, $flag) { - $form['fid'] = array('#type' => 'value', '#value' => $flag->fid); + $form['#flag'] = $flag; return confirm_form($form, t('Are you sure you want to delete %title?', array('%title' => $flag->get_title())), @@ -690,7 +690,7 @@ function flag_delete_confirm($form, &$form_state, $flag) { } function flag_delete_confirm_submit($form, &$form_state) { - $flag = flag_get_flag(NULL, $form_state['values']['fid']); + $flag = $form['#flag']; if ($form_state['values']['confirm']) { $flag->delete(); $flag->disable(); diff --git a/includes/flag.pages.inc b/includes/flag.pages.inc index d7334e0..e30d928 100644 --- a/includes/flag.pages.inc +++ b/includes/flag.pages.inc @@ -80,14 +80,11 @@ function flag_page($action, $flag, $entity_id) { * @see flag_confirm_submit() */ function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { + $form['#flag'] = $flag; $form['action'] = array( '#type' => 'value', '#value' => $action, ); - $form['flag_name'] = array( - '#type' => 'value', - '#value' => $flag->name, - ); $form['entity_id'] = array( '#type' => 'value', '#value' => $entity_id, @@ -117,12 +114,10 @@ function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { * @see flag_confirm() */ function flag_confirm_submit(&$form, &$form_state) { + $flag = $form['#flag']; $action = $form_state['values']['action']; - $flag_name = $form_state['values']['flag_name']; $entity_id = $form_state['values']['entity_id']; - $flag = flag_get_flag($flag_name); - if ($action == 'flag') { // If the action 'flag', further build up the new entity from form values. $flagging = $form['#flagging']; From e7975e6b86d4fa226c5e89ceb717a20dec723009 Mon Sep 17 00:00:00 2001 From: pebosi Date: Fri, 4 Jan 2013 12:51:03 +0000 Subject: [PATCH 244/629] Issue #1734550 by pebosi: Removed unused form property '#flag_link_fields' and helper function. --- flag.module | 12 ------------ includes/flag.admin.inc | 1 - 2 files changed, 13 deletions(-) diff --git a/flag.module b/flag.module index 4484a05..9b621d6 100644 --- a/flag.module +++ b/flag.module @@ -1733,18 +1733,6 @@ function _flag_link_type_descriptions() { return $options; } -/** - * Return an array of flag link fields that are dependent on a link type. - */ -function _flag_link_type_fields() { - $options = array(); - $types = flag_get_link_types(); - foreach ($types as $type_name => $type) { - $options[$type_name] = array_keys($type['options']); - } - return $options; -} - // --------------------------------------------------------------------------- // Non-Views public API diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 1e09e4b..d5026fa 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -475,7 +475,6 @@ function flag_form($form, &$form_state, $flag) { '#type' => 'radios', '#title' => t('Link type'), '#options' => _flag_link_type_options(), - '#flag_link_fields' => _flag_link_type_fields(), '#after_build' => array('flag_check_link_types'), '#default_value' => $flag->link_type, '#weight' => 2, From 274652dfea72338ad9a8cb83ea1a5432477da995 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 7 Jan 2013 10:00:54 +0000 Subject: [PATCH 245/629] Issue #1792584 by joachim: Fixed flag links displayed twice on user profile. --- flag.module | 2 +- includes/flag.admin.inc | 4 +++- includes/flag/flag_entity.inc | 3 +++ includes/flag/flag_user.inc | 19 ++++++++----------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/flag.module b/flag.module index 9b621d6..3d618f8 100644 --- a/flag.module +++ b/flag.module @@ -1176,7 +1176,7 @@ function flag_user_view($account, $view_mode) { // User has no permission to use this flag. continue; } - if (!$flag->uses_hook_link(array())) { + if (!$flag->show_on_profile) { // Flag not set to appear on profile. continue; } diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index d5026fa..4297d2a 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -477,7 +477,9 @@ function flag_form($form, &$form_state, $flag) { '#options' => _flag_link_type_options(), '#after_build' => array('flag_check_link_types'), '#default_value' => $flag->link_type, - '#weight' => 2, + // Give this a high weight so additions by the flag classes for entity- + // specific options go above. + '#weight' => 18, '#attached' => array( 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), ), diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index f706028..389becb 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -49,11 +49,13 @@ class flag_entity extends flag_flag { '#type' => 'checkbox', '#title' => t('Display link on entity'), '#default_value' => isset($this->show_on_entity) ? $this->show_on_entity : TRUE, + '#weight' => 0, ); $form['display']['show_on_form'] = array( '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), '#default_value' => $this->show_on_form, + '#weight' => 5, ); // We use FieldAPI to put the flag checkbox on the entity form, so therefore // require the entity to be fielable. Since this is a potential DX @@ -69,6 +71,7 @@ class flag_entity extends flag_flag { '#default_value' => $this->show_contextual_link, '#description' => t('Note that not all entity types support contextual links.'), '#access' => module_exists('contextual'), + '#weight' => 10, ); } diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc index 156ff96..17d7ab3 100644 --- a/includes/flag/flag_user.inc +++ b/includes/flag/flag_user.inc @@ -11,8 +11,9 @@ class flag_user extends flag_entity { function options() { $options = parent::options(); - // Use own display settings in the meanwhile. - unset($options['show_on_entity']); + // We supersede, but do not supplant, the regular entity display with an + // option that's formatted in the style of user profiles. + $options['show_on_entity'] = FALSE; $options += array( 'show_on_profile' => TRUE, 'access_uid' => '', @@ -40,10 +41,13 @@ class flag_user extends flag_entity { $form['display']['show_on_profile'] = array( '#type' => 'checkbox', '#title' => t('Display link on user profile page'), + '#description' => t('Show the link formatted as a user profile element.'), '#default_value' => $this->show_on_profile, + // Put this above 'show on entity'. + '#weight' => -1, ); - - unset($form['display']['show_on_entity']); + // Explain how 'show on entity' is different. + $form['display']['show_on_entity']['#description'] = t('Show the link in the same format as on other entities.'); } function form_input($form_values) { @@ -76,13 +80,6 @@ class flag_user extends flag_entity { return $access; } - function uses_hook_link($teaser) { - if ($this->show_on_profile) { - return TRUE; - } - return FALSE; - } - function get_flag_action($entity_id) { $flag_action = parent::get_flag_action($entity_id); $user = $this->fetch_entity($entity_id); From d7847fa2af5fe8e3f15a2340e7144213570bdd31 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 7 Jan 2013 16:54:47 +0000 Subject: [PATCH 246/629] Issue #1882006 by joachim: Fixed flag defaults not respected on node add form if creating user doesn't have access. --- flag.module | 12 ++-- tests/flag.test | 143 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 142 insertions(+), 13 deletions(-) diff --git a/flag.module b/flag.module index 3d618f8..7b52cf6 100644 --- a/flag.module +++ b/flag.module @@ -764,7 +764,7 @@ function flag_form_alter(&$form, &$form_state, $form_id) { if (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] . '_node_form')) { global $user; $nid = !empty($form['nid']['#value']) ? $form['nid']['#value'] : NULL; - $flags = flag_get_flags('node', $form['type']['#value'], $user); + $flags = flag_get_flags('node', $form['type']['#value']); // Filter out flags which need to be included on the node form. $flags_in_form = 0; @@ -786,6 +786,8 @@ function flag_form_alter(&$form, &$form_state, $form_id) { // Global flags have their value set even if the user doesn't have access // to it, similar to the way "published" and "promote" keep the default // values even if the user doesn't have "administer nodes" permission. + // Furthermore, a global flag is set to its default value on new nodes + // even if the user creating the node doesn't have access to the flag. $access = $flag->access($nid, $flag_status ? 'unflag' : 'flag', $user); if (!$access && !$flag->global) { continue; @@ -965,8 +967,6 @@ function flag_node_update($node) { * Shared saving routine between flag_node_insert() and flag_node_update(). */ function flag_node_save($node) { - global $user; - // Response to the flag checkboxes added to the form in flag_form_alter(). $remembered = FALSE; if (isset($node->flag)) { @@ -980,7 +980,11 @@ function flag_node_save($node) { // modification: $remembered = TRUE; } - flag($state ? 'flag' : 'unflag', $name, $node->nid, $user); + + $action = $state ? 'flag' : 'unflag'; + // Pass TRUE for $skip_permission_check so that flags that have been + // passed through as hidden form values are saved. + $flag->flag($action, $node->nid, NULL, TRUE); } } } diff --git a/tests/flag.test b/tests/flag.test index d3d2375..d7902ad 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -147,7 +147,138 @@ class FlagAdminTestCase extends DrupalWebTestCase { } -class FlagAccessTestCase extends DrupalWebTestCase { +/** + * Base class for our tests with common methods. + */ +abstract class FlagAccessTestCaseBase extends DrupalWebTestCase { + + /** + * Helper to create a flag from an array of data and clear caches etc. + * + * @param $flag_data + * An array of flag data. + * + * @return + * The flag object. + */ + function createFlag($flag_data) { + $flag = flag_flag::factory_by_array($flag_data); + $flag->save(); + // Reset our cache so our permissions show up. + drupal_static_reset('flag_get_flags'); + + // Reset permissions so that permissions for this flag are available. + $this->checkPermissions(array(), TRUE); + + return $flag; + } + +} + +/** + * Access to flags using the entity forms. + * + * @todo: complete this test class. + */ +class FlagAccessFormTestCase extends FlagAccessTestCaseBase { + + /** + * Implements getInfo(). + */ + public static function getInfo() { + return array( + 'name' => t('Flag access: entity forms'), + 'description' => t('Access to flag and unflag entities via entity forms.'), + 'group' => t('Flag'), + ); + } + + /** + * Implements setUp(). + */ + function setUp() { + parent::setUp('flag'); + } + + /** + * Test scenarios with no access to a global flag. + */ + function testFlagAccessGlobalNone() { + // Create a global flag on article nodes. + $flag_data = array( + 'entity_type' => 'node', + 'name' => 'global_flag', + 'title' => 'Global Flag', + 'global' => 1, + 'types' => array( + 0 => 'article', + ), + 'flag_short' => 'Flag this item', + 'flag_long' => '', + 'flag_message' => '', + 'unflag_short' => 'Unflag this item', + 'unflag_long' => '', + 'unflag_message' => '', + 'unflag_denied_text' => 'You may not unflag this item', + 'link_type' => 'normal', + 'weight' => 0, + // Show the flag on the form. + 'show_on_form' => 1, + 'access_author' => '', + 'show_contextual_link' => 0, + 'show_on_page' => 1, + 'show_on_teaser' => 1, + 'i18n' => 0, + 'api_version' => 3, + ); + $flag = $this->createFlag($flag_data); + + // Create test user who can't us this flag, but can create nodes. + $no_flag_user = $this->drupalCreateUser(array('create article content')); + $this->drupalLogin($no_flag_user); + + // Clear the user access cache so our changes to permissions are noticed. + drupal_static_reset('user_access'); + drupal_static_reset('user_role_permissions'); + + $this->drupalGet('node/add/article'); + + // Check that the flag form element cannot be seen + $this->assertNoText('Flag this item', t('Flag form element was not found.')); + + // Have the user create a node. + $edit = array( + 'title' => 'node 1', + ); + $this->drupalPost('node/add/article', $edit, t('Save')); + + $node = $this->drupalGetNodeByTitle($edit["title"]); + + // Check the new node has not been flagged. + $this->assertFalse($flag->is_flagged($node->nid), t('New node is not flagged.')); + + // Now set the variable so that the flag is set by default on new nodes. + variable_set('flag_' . $flag->name . '_default_' . 'article', 1); + + // Create another new node. + $edit = array( + 'title' => 'node 2', + ); + $this->drupalPost('node/add/article', $edit, t('Save')); + + $node = $this->drupalGetNodeByTitle($edit["title"]); + + // Check the new node has been flagged, despite the user not having access + // to the flag. + $this->assertTrue($flag->is_flagged($node->nid), t('New node is flagged.')); + } + +} + +/** + * Access to flags using the basic flag link. + */ +class FlagAccessLinkTestCase extends FlagAccessTestCaseBase { /** * Implements getInfo(). @@ -155,7 +286,7 @@ class FlagAccessTestCase extends DrupalWebTestCase { public static function getInfo() { return array( 'name' => t('Flag access tests'), - 'description' => t('Access to flag and unflag entities.'), + 'description' => t('Access to flag and unflag entities using the basic link.'), 'group' => t('Flag'), ); } @@ -193,13 +324,7 @@ class FlagAccessTestCase extends DrupalWebTestCase { 'i18n' => 0, 'api_version' => 3, ); - $flag = flag_flag::factory_by_array($flag_data); - $flag->save(); - // Reset our cache so our permissions show up. - drupal_static_reset('flag_get_flags'); - - // Reset permissions so that permissions for this flag are available. - $this->checkPermissions(array(), TRUE); + $flag = $this->createFlag($flag_data); // Create an article node that various users will try to flag. $title = $this->randomName(8); From 652cc90c50d34ebea4c99a5a483d5749e73f82a2 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 7 Jan 2013 17:21:52 +0000 Subject: [PATCH 247/629] by joachim: Changed flag test base class to be parent of all our test classes. --- tests/flag.test | 62 ++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/tests/flag.test b/tests/flag.test index d7902ad..7332571 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -5,7 +5,35 @@ * Tests for the Flag module. */ -class FlagAdminTestCase extends DrupalWebTestCase { +/** + * Base class for our tests with common methods. + */ +abstract class FlagTestCaseBase extends DrupalWebTestCase { + + /** + * Helper to create a flag from an array of data and clear caches etc. + * + * @param $flag_data + * An array of flag data. + * + * @return + * The flag object. + */ + function createFlag($flag_data) { + $flag = flag_flag::factory_by_array($flag_data); + $flag->save(); + // Reset our cache so our permissions show up. + drupal_static_reset('flag_get_flags'); + + // Reset permissions so that permissions for this flag are available. + $this->checkPermissions(array(), TRUE); + + return $flag; + } + +} + +class FlagAdminTestCase extends FlagTestCaseBase { var $_flag = FALSE; /** @@ -147,40 +175,12 @@ class FlagAdminTestCase extends DrupalWebTestCase { } -/** - * Base class for our tests with common methods. - */ -abstract class FlagAccessTestCaseBase extends DrupalWebTestCase { - - /** - * Helper to create a flag from an array of data and clear caches etc. - * - * @param $flag_data - * An array of flag data. - * - * @return - * The flag object. - */ - function createFlag($flag_data) { - $flag = flag_flag::factory_by_array($flag_data); - $flag->save(); - // Reset our cache so our permissions show up. - drupal_static_reset('flag_get_flags'); - - // Reset permissions so that permissions for this flag are available. - $this->checkPermissions(array(), TRUE); - - return $flag; - } - -} - /** * Access to flags using the entity forms. * * @todo: complete this test class. */ -class FlagAccessFormTestCase extends FlagAccessTestCaseBase { +class FlagAccessFormTestCase extends FlagTestCaseBase { /** * Implements getInfo(). @@ -278,7 +278,7 @@ class FlagAccessFormTestCase extends FlagAccessTestCaseBase { /** * Access to flags using the basic flag link. */ -class FlagAccessLinkTestCase extends FlagAccessTestCaseBase { +class FlagAccessLinkTestCase extends FlagTestCaseBase { /** * Implements getInfo(). From 015582c429101902b1d64987848021a244454a5c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Tue, 8 Jan 2013 08:57:09 +0000 Subject: [PATCH 248/629] Issue #1881964 by joachim: Fixed missing documentation for type_access() and type_access_multiple() return value. --- includes/flag/flag_flag.inc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index d69a008..6ec66d8 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -551,6 +551,10 @@ class flag_flag { * Implements access() implemented by each child class. * * @abstract + * + * @return + * FALSE if access should be denied, or NULL if there is no restriction to + * be made. This should NOT return TRUE. */ function type_access($entity_id, $action, $account) { return NULL; @@ -560,6 +564,12 @@ class flag_flag { * Implements access_multiple() implemented by each child class. * * @abstract + * + * @return + * An array keyed by entity ids, whose values represent the access to the + * corresponding entity. The access value may be FALSE if access should be + * denied, or NULL (or not set) if there is no restriction to be made. It + * should NOT be TRUE. */ function type_access_multiple($entity_ids, $account) { return array(); From 9c4ce57d2e5393bc32d0dc041afb8895b0379272 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 11 Jan 2013 14:25:09 +0000 Subject: [PATCH 249/629] by joachim: Removed unneeded cache clearings from tests. --- tests/flag.test | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/tests/flag.test b/tests/flag.test index 7332571..8da07c9 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -237,10 +237,6 @@ class FlagAccessFormTestCase extends FlagTestCaseBase { $no_flag_user = $this->drupalCreateUser(array('create article content')); $this->drupalLogin($no_flag_user); - // Clear the user access cache so our changes to permissions are noticed. - drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); - $this->drupalGet('node/add/article'); // Check that the flag form element cannot be seen @@ -348,10 +344,6 @@ class FlagAccessLinkTestCase extends FlagTestCaseBase { $no_flag_user = $this->drupalCreateUser(array()); $this->drupalLogin($no_flag_user); - // Clear the user access cache so our changes to permissions are noticed. - drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); - // Look at our node. $this->drupalGet('node/' . $this->nid); @@ -366,10 +358,6 @@ class FlagAccessLinkTestCase extends FlagTestCaseBase { $flag_user = $this->drupalCreateUser(array('flag test_flag',)); $this->drupalLogin($flag_user); - // Clear the user access cache so our changes to permissions are noticed. - drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); - // Look at our node. $this->drupalGet('node/' . $this->nid); @@ -389,10 +377,6 @@ class FlagAccessLinkTestCase extends FlagTestCaseBase { $flag_unflag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); $this->drupalLogin($flag_unflag_user); - // Clear the user access cache so our changes to permissions are noticed. - drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); - // Look at our node. $this->drupalGet('node/' . $this->nid); From bc8b53545886357f091bba6fb00bb00eb2f3ba80 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 11 Jan 2013 20:28:50 +0000 Subject: [PATCH 250/629] by joachim: Changed layout of big theme arrays to be more readable. --- flag.module | 23 +++++++++++++++++++---- includes/flag/flag_flag.inc | 14 ++++++++++++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/flag.module b/flag.module index 7b52cf6..32cebd9 100644 --- a/flag.module +++ b/flag.module @@ -1582,13 +1582,21 @@ function flag_theme() { return array( 'flag' => array( - 'variables' => array('flag' => NULL, 'action' => NULL, 'entity_id' => NULL, 'after_flagging' => FALSE), + 'variables' => array( + 'flag' => NULL, + 'action' => NULL, + 'entity_id' => NULL, + 'after_flagging' => FALSE, + ), 'template' => 'flag', 'pattern' => 'flag__', 'path' => $path, ), 'flag_tokens_browser' => array( - 'variables' => array('types' => array('all'), 'global_types' => TRUE), + 'variables' => array( + 'types' => array('all'), + 'global_types' => TRUE, + ), 'file' => 'flag.tokens.inc', ), 'flag_admin_listing' => array( @@ -1596,11 +1604,18 @@ function flag_theme() { 'file' => 'includes/flag.admin.inc', ), 'flag_admin_listing_disabled' => array( - 'variables' => array('flags' => NULL, 'default_flags' => NULL), + 'variables' => array( + 'flags' => NULL, + 'default_flags' => NULL, + ), 'file' => 'includes/flag.admin.inc', ), 'flag_admin_page' => array( - 'variables' => array('flags' => NULL, 'default_flags' => NULL, 'flag_admin_listing' => NULL), + 'variables' => array( + 'flags' => NULL, + 'default_flags' => NULL, + 'flag_admin_listing' => NULL, + ), 'file' => 'includes/flag.admin.inc', ), 'flag_form_roles' => array( diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 6ec66d8..8d39e4d 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1431,12 +1431,22 @@ class flag_flag { } if (!isset($js_added[$this->name . '_' . $entity_id])) { $js_added[$this->name . '_' . $entity_id] = TRUE; - $js_template = theme($this->theme_suggestions(), array('flag' => $this, 'action' => $js_action, 'entity_id' => $entity_id, 'after_flagging' => $after_flagging)); + $js_template = theme($this->theme_suggestions(), array( + 'flag' => $this, + 'action' => $js_action, + 'entity_id' => $entity_id, + 'after_flagging' => $after_flagging, + )); drupal_add_js(array('flag' => array('templates' => array($this->name . '_' . $entity_id => $js_template))), 'setting'); } } - return theme($this->theme_suggestions(), array('flag' => $this, 'action' => $action, 'entity_id' => $entity_id, 'after_flagging' => $after_flagging)); + return theme($this->theme_suggestions(), array( + 'flag' => $this, + 'action' => $action, + 'entity_id' => $entity_id, + 'after_flagging' => $after_flagging, + )); } /** From 64b7ae4c7bcba8f104a07d0d6a784be5a3763ed2 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 11 Jan 2013 20:29:28 +0000 Subject: [PATCH 251/629] by joachim: Removed obsolete comment. --- includes/flag/flag_flag.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 8d39e4d..c8b7838 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1399,8 +1399,8 @@ class flag_flag { } /** - * Renders a flag/unflag link. This is a wrapper around theme('flag') that, - * in Drupal 6, easily channels the call to the right template file. + * Renders a flag/unflag link. This is a wrapper around theme('flag') that + * channels the call to the right template file. * * For parameters documentation, see flag.tpl.php. */ From 73e25c73cea5ccdb2575db3b64f1b643e8d9da1d Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 11 Jan 2013 20:30:51 +0000 Subject: [PATCH 252/629] by joachim: Removed obsolete details in README. --- theme/README.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/theme/README.txt b/theme/README.txt index d369781..3acb393 100644 --- a/theme/README.txt +++ b/theme/README.txt @@ -17,7 +17,7 @@ In order to customize flag theming: - Edit that copy to your liking. -Template variants[3] +Template variants ----------------- In addition, the theme layer will first look for the template 'flag--.tpl.php' before it turns to 'flag.tpl.php'. This too @@ -32,6 +32,3 @@ Footnotes file. This step is needed if you create or rename template files. This step *isn't* needed if you merely modify the contents of a file. Instructions on how to clear you theme registry are at http://drupal.org/node/173880#theme-registry - -[3] For template variants to work correctly you must use Drupal 6.3 or above (or -apply the patch from http://drupal.org/node/241570). From 6bac6cc385213b8d2acc4f683b769e033ef1929a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 11 Jan 2013 20:32:12 +0000 Subject: [PATCH 253/629] by joachim: Fixed missing detail about link type template suggestion in README. --- theme/README.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/theme/README.txt b/theme/README.txt index 3acb393..ea98c51 100644 --- a/theme/README.txt +++ b/theme/README.txt @@ -19,9 +19,11 @@ In order to customize flag theming: Template variants ----------------- -In addition, the theme layer will first look for the template -'flag--.tpl.php' before it turns to 'flag.tpl.php'. This too -you should place in your theme's folder.[2][1] +The theme layer will first look for the following templates in this order: + - flag--.tpl.php + - flag--.tpl.php + - flag.tpl.php +These should also be placed in your theme's folder.[2][1] Footnotes From 93cf7f9fc31bf84a63dc8cac8a42a8e1e03fdc45 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 11 Jan 2013 20:36:31 +0000 Subject: [PATCH 254/629] by joachim: Removed obsolete Views 2 compability methods. --- .../flag_plugin_argument_validate_flaggability.inc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/includes/views/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc index b36379c..c8f6e30 100644 --- a/includes/views/flag_plugin_argument_validate_flaggability.inc +++ b/includes/views/flag_plugin_argument_validate_flaggability.inc @@ -83,18 +83,6 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v } } - // This function seems useless, but in the Drupal 6 branch it allows for - // compatibility between Views 3 and Views 2. - function _get_option($option, $default) { - return $this->options[$option]; - } - - // This function seems useless, but in the Drupal 6 branch it allows for - // compatibility between Views 3 and Views 2. - function _option_name($option) { - return $option; - } - /** * Migrate existing Views 2 options to Views 3. */ From e6057ff99d451d2fb731a402700180af28c23f07 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 12 Jan 2013 08:09:06 +0000 Subject: [PATCH 255/629] Issue #1886244 by joachim: Changed parameters of _insert_flagging() to match other private CRUD methods. --- includes/flag/flag_flag.inc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index c8b7838..0bda839 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -753,16 +753,22 @@ class flag_flag { $this->_flag_anonymous($entity_id); } if (!$flagged) { + // The entity is unflagged. By definition there is no flagging entity, + // but we may have been passed one in to save. if (!isset($flagging)) { // Construct a new flagging object if we don't have one. $flagging = $this->new_flagging($entity_id, $uid, $sid); } + // Save the flagging entity (just our table). $flagging_id = $this->_flag($entity_id, $uid, $sid); + // The _flag() method is a plain DB record writer, so it's a bit + // antiquated. We have to explicitly get our new ID out. + $flagging->flagging_id = $flagging_id; $this->_increase_count($entity_id); // We're writing out a flagging entity even when we aren't passed one // (e.g., when flagging via JavaScript toggle links); in this case // Field API will assign the fields their default values. - $this->_insert_flagging($flagging, $entity_id, $flagging_id); + $this->_insert_flagging($flagging); module_invoke_all('flag_flag', $this, $entity_id, $account, $flagging); // Invoke Rules event. if (module_exists('rules')) { @@ -802,8 +808,7 @@ class flag_flag { * operation is also accompanied by some bookkeeping (calling hooks, updating * counters) or access control. These tasks are handled by the flag() method. */ - private function _insert_flagging($flagging, $entity_id, $flagging_id) { - $flagging->flagging_id = $flagging_id; + private function _insert_flagging($flagging) { field_attach_presave('flagging', $flagging); field_attach_insert('flagging', $flagging); } From 79bb3d039d86b56e4b6a72f99a080afdf0a29bde Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 12 Jan 2013 08:15:19 +0000 Subject: [PATCH 256/629] Issue #1776238 by jyee, joachim: Added a flagging_save() API function, and ability to save flaggings with EntityMetadataWrapper. --- flag.module | 46 ++++++++++++- tests/flag.test | 174 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 32cebd9..85927b6 100644 --- a/flag.module +++ b/flag.module @@ -30,6 +30,9 @@ function flag_entity_info() { 'bundle' => 'name', ), 'bundles' => array(), + // The following tells EntityAPI how to save flaggings, thus allowing use + // of Entity metadata wrappers (if present). + 'save callback' => 'flagging_save', ), ); @@ -69,7 +72,48 @@ function flagging_load($flagging_id, $reset = FALSE) { return reset($result); } -// @todo: Implement flagging_save(). It's not required but other modules may expect it. +/** + * Saves a flagging entity. + * + * For a new flagging, throws an exception is the flag action is not allowed for + * the given combination of flag, entity, and user. + * + * @param $flagging + * The flagging entity. This may have either flag_name or the flag fid set, + * and may also omit the uid property to use the current user. + * + * @throws Exception + */ +function flagging_save($flagging) { + // Get the flag, either way. + if (isset($flagging->flag_name)) { + $flag = flag_get_flag($flagging->flag_name); + } + else { + $flag = flag_get_flag(NULL, $flagging->fid); + } + + if (!$flag) { + throw new Exception('Flag not found for flagging entity.'); + } + + // Fill in properties that may be omitted. + $flagging->fid = $flag->fid; + $flagging->flag_name = $flag->name; + + if (!empty($flagging->uid)) { + $account = user_load($flagging->uid); + } + else { + $account = NULL; + } + + $result = $flag->flag('flag', $flagging->entity_id, $account, FALSE, $flagging); + + if (!$result) { + throw new Exception('Flag action not allowed for given flagging entity properties.'); + } +} // @todo: Implement flagging_view(). Not extremely useful. I already have it. diff --git a/tests/flag.test b/tests/flag.test index 8da07c9..31c0f4a 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -33,6 +33,180 @@ abstract class FlagTestCaseBase extends DrupalWebTestCase { } +class FlagFlaggingCRUDTestCase extends FlagTestCaseBase { + + /** + * Implements getInfo(). + */ + public static function getInfo() { + return array( + 'name' => t('Flagging CRUD'), + 'description' => t('Basic CRUD operations on flagging entities.'), + 'group' => t('Flag'), + ); + } + + /** + * Implements setUp(). + */ + function setUp() { + parent::setUp('flag'); + + $flag_data = array( + 'entity_type' => 'node', + 'name' => 'test_flag', + 'title' => 'Test Flag', + 'global' => 0, + 'types' => array( + 0 => 'article', + ), + 'flag_short' => 'Flag this item', + 'flag_long' => '', + 'flag_message' => '', + 'unflag_short' => 'Unflag this item', + 'unflag_long' => '', + 'unflag_message' => '', + 'unflag_denied_text' => 'You may not unflag this item', + 'link_type' => 'normal', + 'weight' => 0, + 'show_on_form' => 0, + 'access_author' => '', + 'show_contextual_link' => 0, + 'show_on_page' => 1, + 'show_on_teaser' => 1, + 'i18n' => 0, + 'api_version' => 3, + ); + $this->flag = $this->createFlag($flag_data); + + // Create test user who can flag and unflag. + $this->flag_unflag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); + $this->drupalLogin($this->flag_unflag_user); + } + + /** + * Test creation of a flagging entity with flagging_save(). + */ + function testFlaggingCreate() { + // Create an article node that we try to create a flagging entity for. + $title = $this->randomName(8); + $node = array( + 'title' => $title, + 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), + 'uid' => 1, + 'type' => 'article', + 'is_new' => TRUE, + ); + $node = node_submit((object) $node); + node_save($node); + + // Create a flagging entity and save it. + $flagging = array( + 'fid' => $this->flag->fid, + 'entity_type' => 'node', + 'entity_id' => $node->nid, + 'uid' => $this->flag_unflag_user->uid, + ); + + $flagging = (object) $flagging; + flagging_save($flagging); + + // Test flagging has a flagging_id + $this->assertTrue(!empty($flagging->flagging_id), 'The flagging entity has an entity id.'); + + // Test the database record exists. + $result = db_query("SELECT * FROM {flagging} WHERE fid = :fid AND entity_id = :nid AND uid = :uid", array( + ':fid' => $this->flag->fid, + ':nid' => $node->nid, + ':uid' => $this->flag_unflag_user->uid, + )); + $records = $result->fetchAll(); + $this->assertTrue(count($records), 'The flagging record exists in the database.'); + + // Test node is flagged. + // The current user is not the same as the user logged into the internal + // browser, so we have to pass the UID param explicitly. + $this->assertTrue($this->flag->is_flagged($node->nid, $this->flag_unflag_user->uid), 'The node has been flagged by creating the flagging.'); + } + + /** + * Test throwing of exceptions with flagging_save(). + */ + function testFlaggingCreateException() { + // Create an article node that we try to create a flagging entity for. + $title = $this->randomName(8); + $node = array( + 'title' => $title, + 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), + 'uid' => 1, + 'type' => 'article', + 'is_new' => TRUE, + ); + $node = node_submit((object) $node); + node_save($node); + + // Create test user who can't use this flag. + $no_flag_user = $this->drupalCreateUser(array()); + + // Create a flagging entity with that tries to perform an flagging action + // that is not permitted. + $flagging = array( + 'fid' => $this->flag->fid, + 'entity_type' => 'node', + 'entity_id' => $node->nid, + 'uid' => $no_flag_user->uid, + ); + + $flagging = (object) $flagging; + try { + flagging_save($flagging); + $this->fail(t('Expected exception has not been thrown.')); + } + catch (Exception $e) { + $this->pass(t('Expected exception has been thrown.')); + } + } + + /** + * Test creation of a flagging entity with flagging_save(). + */ + function testFlaggingUpdate() { + // Create an article node that we try to create a flagging entity for. + $title = $this->randomName(8); + $node = array( + 'title' => $title, + 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), + 'uid' => 1, + 'type' => 'article', + 'is_new' => TRUE, + ); + $node = node_submit((object) $node); + node_save($node); + + // Flag the node as the user. + $flag = flag_get_flag('test_flag'); + $flag->flag('flag', $node->nid, $this->flag_unflag_user); + + // Get the flagging record back from the database. + $result = db_query("SELECT * FROM {flagging} WHERE fid = :fid AND entity_id = :nid AND uid = :uid", array( + ':fid' => $this->flag->fid, + ':nid' => $node->nid, + ':uid' => $this->flag_unflag_user->uid, + )); + $record = $result->fetchObject(); + + // Load the flagging entity we just created. + $flagging = flagging_load($record->flagging_id); + + // Save it, as if we were updating field values. + flagging_save($flagging); + + // This should have no effect: the node should still be flagged. + $this->assertTrue($this->flag->is_flagged($node->nid, $this->flag_unflag_user->uid), 'The node is still flagged after updating the flagging.'); + } + +} + class FlagAdminTestCase extends FlagTestCaseBase { var $_flag = FALSE; From c12c48f2959295c508f936bdb012b77378ffcd18 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 08:52:46 +0000 Subject: [PATCH 257/629] Issue #1315850 by mh86, joachim, madmatter23: Added support for Entity API metadata properties. --- flag.info.inc | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ flag.module | 40 ++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 flag.info.inc diff --git a/flag.info.inc b/flag.info.inc new file mode 100644 index 0000000..1870c5a --- /dev/null +++ b/flag.info.inc @@ -0,0 +1,91 @@ +flag_FLAGNAME, boolean. + * - per-user flags: + * - entity->flag_FLAGNAME_users, list of users. + * - user->flag_FLAGNAME_flagged, list of user's flagged entities. + */ +function flag_entity_property_info_alter(&$info) { + foreach (flag_get_flags() as $flag) { + if ($flag->global) { + // Global flags. + // Boolean property on entity type. + // This can go on either the entity as a whole, or on bundles, depending + // on whether the flag is limited by bundle. + $property_definition = array( + 'label' => t('Whether the entity is flagged with flag @flag', array( + '@flag' => $flag->name, + )), + 'description' => t('Whether the entity is flagged with flag @flag.', array( + '@flag' => $flag->name, + )), + 'type' => 'boolean', + 'getter callback' => 'flag_properties_get_flagging_boolean', + 'computed' => TRUE, + 'flag_name' => $flag->name, + ); + if (count($flag->types)) { + // Bundle specific property. + foreach ($flag->types as $type) { + $info[$flag->entity_type]['bundles'][$type]['properties']['flag_' . $flag->name] = $property_definition; + } + } + else { + // Generic property, applies for all bundles. + $info[$flag->entity_type]['properties']['flag_' . $flag->name] = $property_definition; + } + } + else { + // Per-user flags. + // User property: list of flagged entities by the user. + $info['user']['properties']['flag_' . $flag->name . '_flagged'] = array( + 'label' => t('Flagged @entity-type with flag @flag', array( + '@entity-type' => $flag->entity_type, + '@flag' => $flag->name, + )), + 'description' => t('Returns a list of entities a user flagged with flag @flag.', array( + '@flag' => $flag->name, + )), + 'type' => 'list<' . $flag->entity_type . '>', + 'getter callback' => 'flag_properties_get_flagged_entities', + 'computed' => TRUE, + 'flag_name' => $flag->name, + 'flag_entity_type' => $flag->entity_type, + ); + // Entity property: list of users who have flagged this entity. + // This can go on either the entity as a whole, or on bundles, depending + // on whether the flag is limited by bundle. + $property_definition = array( + 'label' => t('Users who flagged the entity with flag @flag', array( + '@flag' => $flag->name, + )), + 'description' => t('Returns a list of users who flagged an entity with flag @flag.', array( + '@flag' => $flag->name, + )), + 'type' => 'list', + 'getter callback' => 'flag_properties_get_flagging_users', + 'computed' => TRUE, + 'flag_name' => $flag->name, + ); + if (count($flag->types)) { + // Bundle specific property. + foreach ($flag->types as $type) { + $info[$flag->entity_type]['bundles'][$type]['properties']['flag_' . $flag->name . '_user'] = $property_definition; + } + } + else { + // Generic property, applies for all bundles. + $info[$flag->entity_type]['properties']['flag_' . $flag->name . '_user'] = $property_definition; + } + } + } +} diff --git a/flag.module b/flag.module index 85927b6..adedfbf 100644 --- a/flag.module +++ b/flag.module @@ -2343,3 +2343,43 @@ function flag_ctools_plugin_directory($module, $plugin) { return "plugins/$plugin"; } } + +// --------------------------------------------------------------------------- +// Entity Metadata callbacks + +/** + * Getter callback that returns whether the given entity is flagged. + */ +function flag_properties_get_flagging_boolean($entity, array $options, $name, $entity_type, $property_info) { + list($entity_id,) = entity_extract_ids($entity_type, $entity); + + $flagging_data = flag_get_user_flags($entity_type, $entity_id); + return isset($flagging_data[$property_info['flag_name']]); +} + +/** + * Getter callback that returns entities the given user flagged. + */ +function flag_properties_get_flagged_entities($entity, array $options, $name, $entity_type, $property_info) { + // Need the entity type the flag applies to. + $flag_entity_type = $property_info['flag_entity_type']; + + $flagging_data = flag_get_user_flags($flag_entity_type, NULL, $entity->uid); + + $flag_name = $property_info['flag_name']; + if (isset($flagging_data[$flag_name])) { + return array_keys($flagging_data[$flag_name]); + } + return array(); +} + +/** + * Getter callback that returns users who flagged the given entity. + */ +function flag_properties_get_flagging_users($entity, array $options, $name, $entity_type, $property_info) { + list($entity_id,) = entity_extract_ids($entity_type, $entity); + + $flagging_data = flag_get_entity_flags($entity_type, $entity_id, $property_info['flag_name']); + + return array_keys($flagging_data); +} From 73bedb241edf9a29cd30eb5238216d05595b609b Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 09:16:21 +0000 Subject: [PATCH 258/629] by joachim: Moved flag_trim_flag() and flag_reset_flag() to public API section of module file. --- flag.module | 122 ++++++++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/flag.module b/flag.module index adedfbf..7df4251 100644 --- a/flag.module +++ b/flag.module @@ -1472,67 +1472,6 @@ function flag_flag_access_multiple($flag, $entity_ids, $account) { return $access; } -/** - * Trim a flag to a certain size. - * - * @param $fid - * The flag object. - * @param $account - * The user object on behalf the trimming will occur. - * @param $cutoff_size - * The number of flaggings allowed. Any flaggings beyond that will be trimmed. - */ -function flag_trim_flag($flag, $account, $cutoff_size) { - $result = db_select('flagging', 'fc') - ->fields('fc') - ->condition('fid', $flag->fid) - ->condition(db_or()->condition('uid', $account->uid)->condition('uid', 0)) - ->orderBy('timestamp', 'DESC') - ->execute(); - $i = 1; - foreach ($result as $row) { - if ($i++ > $cutoff_size) { - flag('unflag', $flag->name, $row->entity_id, $account); - } - } -} - -/** - * Remove all flagged entities from a flag. - * - * @param $flag - * The flag object. - * @param $entity_id - * Optional. The entity ID on which all flaggings will be removed. If left - * empty, this will remove all of this flag's entities. - */ -function flag_reset_flag($flag, $entity_id = NULL) { - $query = db_select('flagging', 'fc') - ->fields('fc') - ->condition('fid', $flag->fid); - - if ($entity_id) { - $query->condition('entity_id', $entity_id); - } - - $result = $query->execute()->fetchAllAssoc('flagging_id', PDO::FETCH_ASSOC); - $rows = array(); - foreach ($result as $row) { - $rows[] = $row; - } - module_invoke_all('flag_reset', $flag, $entity_id, $rows); - - $query = db_delete('flagging')->condition('fid' , $flag->fid); - // Update the flag_counts table. - $count_query = db_delete('flag_counts')->condition('fid', $flag->fid); - if ($entity_id) { - $query->condition('entity_id', $entity_id); - $count_query->condition('entity_id', $entity_id); - } - $count_query->execute(); - return $query->execute(); -} - /** * Implements hook_node_operations(). * @@ -2237,6 +2176,67 @@ function flag_create_link($flag_name, $entity_id) { return $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id); } +/** + * Trim a flag to a certain size. + * + * @param $fid + * The flag object. + * @param $account + * The user object on behalf the trimming will occur. + * @param $cutoff_size + * The number of flaggings allowed. Any flaggings beyond that will be trimmed. + */ +function flag_trim_flag($flag, $account, $cutoff_size) { + $result = db_select('flagging', 'fc') + ->fields('fc') + ->condition('fid', $flag->fid) + ->condition(db_or()->condition('uid', $account->uid)->condition('uid', 0)) + ->orderBy('timestamp', 'DESC') + ->execute(); + $i = 1; + foreach ($result as $row) { + if ($i++ > $cutoff_size) { + flag('unflag', $flag->name, $row->entity_id, $account); + } + } +} + +/** + * Remove all flagged entities from a flag. + * + * @param $flag + * The flag object. + * @param $entity_id + * Optional. The entity ID on which all flaggings will be removed. If left + * empty, this will remove all of this flag's entities. + */ +function flag_reset_flag($flag, $entity_id = NULL) { + $query = db_select('flagging', 'fc') + ->fields('fc') + ->condition('fid', $flag->fid); + + if ($entity_id) { + $query->condition('entity_id', $entity_id); + } + + $result = $query->execute()->fetchAllAssoc('flagging_id', PDO::FETCH_ASSOC); + $rows = array(); + foreach ($result as $row) { + $rows[] = $row; + } + module_invoke_all('flag_reset', $flag, $entity_id, $rows); + + $query = db_delete('flagging')->condition('fid' , $flag->fid); + // Update the flag_counts table. + $count_query = db_delete('flag_counts')->condition('fid', $flag->fid); + if ($entity_id) { + $query->condition('entity_id', $entity_id); + $count_query->condition('entity_id', $entity_id); + } + $count_query->execute(); + return $query->execute(); +} + /** * Return an array of link types provided by modules. * From 0f8d23587e47cd38204d70e28eea5768f58aa31a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 09:19:23 +0000 Subject: [PATCH 259/629] by joachim: Moved hook implementations so contrib integration functions are together. --- flag.module | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/flag.module b/flag.module index 7df4251..b21b9e7 100644 --- a/flag.module +++ b/flag.module @@ -534,30 +534,6 @@ function _flag_url($path, $fragment = NULL, $absolute = TRUE) { return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); } -/** - * Implements hook_views_api(). - */ -function flag_views_api() { - return array( - 'api' => 3.0, - 'path' => drupal_get_path('module', 'flag') . '/includes/views', - ); -} - -/** - * Implements hook_features_api(). - */ -function flag_features_api() { - return array( - 'flag' => array( - 'name' => t('Flag'), - 'feature_source' => TRUE, - 'default_hook' => 'flag_default_flags', - 'file' => drupal_get_path('module', 'flag') . '/includes/flag.features.inc', - ), - ); -} - /** * Implements hook_permission(). */ @@ -2335,6 +2311,33 @@ function flag_get_sid($uid = NULL, $create = FALSE) { return flag_set_sid($uid, $create); } +// --------------------------------------------------------------------------- +// Contrib integration hooks + +/** + * Implements hook_views_api(). + */ +function flag_views_api() { + return array( + 'api' => 3.0, + 'path' => drupal_get_path('module', 'flag') . '/includes/views', + ); +} + +/** + * Implements hook_features_api(). + */ +function flag_features_api() { + return array( + 'flag' => array( + 'name' => t('Flag'), + 'feature_source' => TRUE, + 'default_hook' => 'flag_default_flags', + 'file' => drupal_get_path('module', 'flag') . '/includes/flag.features.inc', + ), + ); +} + /** * Implements hook_ctools_plugin_directory(). */ From 302e01e41e5f2cb358195d653d436a64a4dc2d21 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 09:29:14 +0000 Subject: [PATCH 260/629] by joachim: Moved hook_schema() to be at the top of the .install file. --- flag.install | 168 +++++++++++++++++++++++++-------------------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/flag.install b/flag.install index b22ff16..83c93c8 100644 --- a/flag.install +++ b/flag.install @@ -5,90 +5,6 @@ * Flag module install/schema/update hooks. */ -/** - * Implements hook_install(). - */ -function flag_install() { -} - -/** - * Implements hook_uninstall(). - */ -function flag_uninstall() { - $result = db_select('variable', 'v') - ->fields('v', array('name')) - ->condition('name', 'flag_%', 'LIKE') - ->execute(); - foreach ($result as $row) { - variable_del($row->name); - } - - drupal_set_message(t('Flag has been uninstalled.')); -} - -/** - * Implements hook_requirements(). - * - * Prevent installing this module if the "Flag content" module is installed as well. - */ -function flag_requirements($phase) { - $requirements = array(); - $t = get_t(); - if ($phase == 'install') { - if (!defined('MAINTENANCE_MODE') && _flag_flag_content_installed()) { - $requirements['flag_content_clash'] = array( - 'title' => $t('Flag'), - 'severity' => REQUIREMENT_ERROR, - 'description' => _flag_flag_content_message(), - ); - } - } - - if ($phase == 'runtime') { - if (module_exists('translation') && !module_exists('translation_helpers')) { - $requirements['flag_translation'] = array( - 'title' => $t('Flag'), - 'severity' => REQUIREMENT_ERROR, - 'description' => $t('To have the flag module work with translations, you need to install and enable the Translation helpers module.'), - 'value' => $t('Translation helpers module not found.'), - ); - } - if (module_exists('session_api')) { - if (file_exists('./robots.txt')) { - $flag_path = url('flag') . '/'; - // We don't use url() because this may return an absolute URL when - // language negotiation is set to 'domain'. - $flag_path = parse_url($flag_path, PHP_URL_PATH); - $robots_string = 'Disallow: ' . $flag_path; - $contents = file_get_contents('./robots.txt'); - if (strpos($contents, $robots_string) === FALSE) { - $requirements['flag_robots'] = array( - 'title' => $t('Flag robots.txt problem'), - 'severity' => REQUIREMENT_WARNING, - 'description' => $t('Flag module may currently be used with anonymous users, however the robots.txt file does not exclude the "@flag-path" path, which may cause search engines to randomly flag and unflag content when they index the site. It is highly recommended to add "@robots-string" to your robots.txt file (located in the root of your Drupal installation).', array('@flag-path' => $flag_path, '@robots-string' => $robots_string)), - 'value' => $t('Search engines flagging content'), - ); - } - } - } - } - return $requirements; -} - -/** - * Returns TRUE if the "Flag content" module, which we aren't compatible with, - * is installed. - */ -function _flag_flag_content_installed() { - $version = @drupal_get_installed_schema_version('flag_content', TRUE); - return (isset($version) && $version != SCHEMA_UNINSTALLED); -} - -function _flag_flag_content_message() { - $t = get_t(); - return $t("You are trying to install the Flag module. However, you have the \"Flag content\" module installed, and these two modules aren't compatible (because they happen to use a database table by the same name). To install the Flag module, you'll first have to disable and then uninstall the \"Flag content\" module.", array('@uninstall-url' => url('admin/modules/uninstall'))); -} - /** * Implements hook_schema(). */ @@ -288,6 +204,90 @@ function flag_schema() { return $schema; } +/** + * Implements hook_install(). + */ +function flag_install() { +} + +/** + * Implements hook_uninstall(). + */ +function flag_uninstall() { + $result = db_select('variable', 'v') + ->fields('v', array('name')) + ->condition('name', 'flag_%', 'LIKE') + ->execute(); + foreach ($result as $row) { + variable_del($row->name); + } + + drupal_set_message(t('Flag has been uninstalled.')); +} + +/** + * Implements hook_requirements(). + * + * Prevent installing this module if the "Flag content" module is installed as well. + */ +function flag_requirements($phase) { + $requirements = array(); + $t = get_t(); + if ($phase == 'install') { + if (!defined('MAINTENANCE_MODE') && _flag_flag_content_installed()) { + $requirements['flag_content_clash'] = array( + 'title' => $t('Flag'), + 'severity' => REQUIREMENT_ERROR, + 'description' => _flag_flag_content_message(), + ); + } + } + + if ($phase == 'runtime') { + if (module_exists('translation') && !module_exists('translation_helpers')) { + $requirements['flag_translation'] = array( + 'title' => $t('Flag'), + 'severity' => REQUIREMENT_ERROR, + 'description' => $t('To have the flag module work with translations, you need to install and enable the Translation helpers module.'), + 'value' => $t('Translation helpers module not found.'), + ); + } + if (module_exists('session_api')) { + if (file_exists('./robots.txt')) { + $flag_path = url('flag') . '/'; + // We don't use url() because this may return an absolute URL when + // language negotiation is set to 'domain'. + $flag_path = parse_url($flag_path, PHP_URL_PATH); + $robots_string = 'Disallow: ' . $flag_path; + $contents = file_get_contents('./robots.txt'); + if (strpos($contents, $robots_string) === FALSE) { + $requirements['flag_robots'] = array( + 'title' => $t('Flag robots.txt problem'), + 'severity' => REQUIREMENT_WARNING, + 'description' => $t('Flag module may currently be used with anonymous users, however the robots.txt file does not exclude the "@flag-path" path, which may cause search engines to randomly flag and unflag content when they index the site. It is highly recommended to add "@robots-string" to your robots.txt file (located in the root of your Drupal installation).', array('@flag-path' => $flag_path, '@robots-string' => $robots_string)), + 'value' => $t('Search engines flagging content'), + ); + } + } + } + } + return $requirements; +} + +/** + * Returns TRUE if the "Flag content" module, which we aren't compatible with, + * is installed. + */ +function _flag_flag_content_installed() { + $version = @drupal_get_installed_schema_version('flag_content', TRUE); + return (isset($version) && $version != SCHEMA_UNINSTALLED); +} + +function _flag_flag_content_message() { + $t = get_t(); + return $t("You are trying to install the Flag module. However, you have the \"Flag content\" module installed, and these two modules aren't compatible (because they happen to use a database table by the same name). To install the Flag module, you'll first have to disable and then uninstall the \"Flag content\" module.", array('@uninstall-url' => url('admin/modules/uninstall'))); +} + function flag_update_last_removed() { return 6004; } From f86911fabc37e7b88b9ad833adb2abe0a995a4a3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 09:41:27 +0000 Subject: [PATCH 261/629] by joachim: Moved functions for Drupal core operations lower down in module code. --- flag.module | 149 +++++++++++++++++++++++++++------------------------- 1 file changed, 76 insertions(+), 73 deletions(-) diff --git a/flag.module b/flag.module index b21b9e7..d1aa0a6 100644 --- a/flag.module +++ b/flag.module @@ -1448,79 +1448,6 @@ function flag_flag_access_multiple($flag, $entity_ids, $account) { return $access; } -/** - * Implements hook_node_operations(). - * - * Add additional options on the admin/build/node page. - */ -function flag_node_operations() { - global $user; - - $flags = flag_get_flags('node', NULL, $user); - $operations = array(); - - foreach ($flags as $flag) { - $operations['flag_' . $flag->name] = array( - 'label' => $flag->get_label('flag_short'), - 'callback' => 'flag_nodes', - 'callback arguments' => array('flag', $flag->name), - 'behavior' => array(), - ); - $operations['unflag_' . $flag->name] = array( - 'label' => $flag->get_label('unflag_short'), - 'callback' => 'flag_nodes', - 'callback arguments' => array('unflag', $flag->name), - 'behavior' => array(), - ); - } - return $operations; -} - -/** - * Callback function for hook_node_operations(). - */ -function flag_nodes($nodes, $action, $flag_name) { - $performed = FALSE; - foreach ($nodes as $nid) { - $performed |= flag($action, $flag_name, $nid); - } - if ($performed) { - drupal_set_message(t('The update has been performed.')); - } -} - -/** - * Implements hook_user_operations(). - */ -function flag_user_operations() { - global $user; - - $flags = flag_get_flags('user', NULL, $user); - $operations = array(); - - foreach ($flags as $flag) { - $operations['flag_' . $flag->name] = array( - 'label' => $flag->get_label('flag_short'), - 'callback' => 'flag_users', - 'callback arguments' => array('flag', $flag->name), - ); - $operations['unflag_' . $flag->name] = array( - 'label' => $flag->get_label('unflag_short'), - 'callback' => 'flag_users', - 'callback arguments' => array('unflag', $flag->name), - ); - } - return $operations; -} -/** - * Callback function for hook_user_operations(). - */ -function flag_users($users, $action, $flag_name) { - foreach ($users as $uid) { - flag($action, $flag_name, $uid); - } -} - /** * Implements hook_mail(). */ @@ -2311,6 +2238,82 @@ function flag_get_sid($uid = NULL, $create = FALSE) { return flag_set_sid($uid, $create); } +// --------------------------------------------------------------------------- +// Drupal Core operations + +/** + * Implements hook_node_operations(). + * + * Add additional options on the admin/build/node page. + */ +function flag_node_operations() { + global $user; + + $flags = flag_get_flags('node', NULL, $user); + $operations = array(); + + foreach ($flags as $flag) { + $operations['flag_' . $flag->name] = array( + 'label' => $flag->get_label('flag_short'), + 'callback' => 'flag_nodes', + 'callback arguments' => array('flag', $flag->name), + 'behavior' => array(), + ); + $operations['unflag_' . $flag->name] = array( + 'label' => $flag->get_label('unflag_short'), + 'callback' => 'flag_nodes', + 'callback arguments' => array('unflag', $flag->name), + 'behavior' => array(), + ); + } + return $operations; +} + +/** + * Callback function for hook_node_operations(). + */ +function flag_nodes($nodes, $action, $flag_name) { + $performed = FALSE; + foreach ($nodes as $nid) { + $performed |= flag($action, $flag_name, $nid); + } + if ($performed) { + drupal_set_message(t('The update has been performed.')); + } +} + +/** + * Implements hook_user_operations(). + */ +function flag_user_operations() { + global $user; + + $flags = flag_get_flags('user', NULL, $user); + $operations = array(); + + foreach ($flags as $flag) { + $operations['flag_' . $flag->name] = array( + 'label' => $flag->get_label('flag_short'), + 'callback' => 'flag_users', + 'callback arguments' => array('flag', $flag->name), + ); + $operations['unflag_' . $flag->name] = array( + 'label' => $flag->get_label('unflag_short'), + 'callback' => 'flag_users', + 'callback arguments' => array('unflag', $flag->name), + ); + } + return $operations; +} +/** + * Callback function for hook_user_operations(). + */ +function flag_users($users, $action, $flag_name) { + foreach ($users as $uid) { + flag($action, $flag_name, $uid); + } +} + // --------------------------------------------------------------------------- // Contrib integration hooks From d0e0be061576abea0db110c8db84ecb9af7c87b2 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 10:35:30 +0000 Subject: [PATCH 262/629] by joachim: Added API docs for hook_flag_export_alter(). --- flag.api.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/flag.api.php b/flag.api.php index 4c4e962..da2fb7e 100644 --- a/flag.api.php +++ b/flag.api.php @@ -279,3 +279,15 @@ function hook_flag_reset($flag, $entity_id, $rows) { function hook_flag_javascript_info_alter() { } + +/** + * Alter a flag object that is being prepared for exporting. + * + * @param $flag + * The flag object. + * + * @see flag_export_flags() + */ +function hook_flag_export_alter($flag) { + +} From 53dcec662e00547b1e623ada6f2d8d676cba1f3e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 10:55:52 +0000 Subject: [PATCH 263/629] by joachim: Changed single-line arrays in calls to theme() to multi-line. --- includes/flag.admin.inc | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 4297d2a..76a0180 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -12,7 +12,11 @@ function flag_admin_page() { $flags = flag_get_flags(); $default_flags = flag_get_default_flags(TRUE); $flag_admin_listing = drupal_get_form('flag_admin_listing', $flags); - return theme('flag_admin_page', array('flags' => $flags, 'default_flags' => $default_flags, 'flag_admin_listing' => $flag_admin_listing)); + return theme('flag_admin_page', array( + 'flags' => $flags, + 'default_flags' => $default_flags, + 'flag_admin_listing' => $flag_admin_listing, + )); } /** @@ -113,7 +117,11 @@ function theme_flag_admin_listing($variables) { $header[] = t('Weight'); } $header = array_merge($header, array(t('Flag type'), t('Roles'), t('Entity bundles'), t('Global?'), t('Operations'))); - $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'flag-admin-listing-table'))); + $output .= theme('table', array( + 'header' => $header, + 'rows' => $rows, + 'attributes' => array('id' => 'flag-admin-listing-table'), + )); $output .= drupal_render_children($form); return $output; @@ -372,11 +380,14 @@ function flag_form($form, &$form_state, $flag) { '#type' => 'fieldset', '#description' => '

' . t('The above six texts may contain any of the tokens listed below. For example, "Flag link text" could be entered as:') . '

' . - theme('item_list', array('items' => array( - t('Add <em>[node:title]</em> to your favorites'), - t('Add this [node:type] to your favorites'), - t('Vote for this proposal ([node:flag-vote-count] people have already done so)'), - ), 'attributes' => array('class' => 'token-examples'))) . + theme('item_list', array( + 'items' => array( + t('Add <em>[node:title]</em> to your favorites'), + t('Add this [node:type] to your favorites'), + t('Vote for this proposal ([node:flag-vote-count] people have already done so)'), + ), + 'attributes' => array('class' => 'token-examples'), + )) . '

' . t('These tokens will be replaced with the appropriate fields from the node (or user, or comment).') . '

' . theme('flag_tokens_browser', array('types' => $flag->get_labels_token_types())), '#collapsible' => TRUE, @@ -673,7 +684,14 @@ function theme_flag_form_roles($variables) { $rows[] = $row; } - return theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('class' => array('flag-admin-table'), 'id' => 'flag-roles'))); + return theme('table', array( + 'header' => $header, + 'rows' => $rows, + 'attributes' => array( + 'class' => array('flag-admin-table'), + 'id' => 'flag-roles', + ), + )); } /** From 54e03f17f7459b1bd7e4863ffb2db9e6c2f26cbf Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 15:21:09 +0000 Subject: [PATCH 264/629] Issue #1730164 by joachim: Changed flag admin form link options to use Form API states rather than JavaScript. --- includes/flag.admin.inc | 42 ++++++++++++++++++++++++++++++++++++++++- theme/flag-admin.js | 27 -------------------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 76a0180..4ab59d6 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -480,6 +480,7 @@ function flag_form($form, &$form_state, $flag) { '#description' => t('Flags are usually controlled through links that allow users to toggle their behavior. You can choose how users interact with flags by changing options here. It is legitimate to have none of the following checkboxes ticked, if, for some reason, you wish to place the the links on the page yourself.', array('@placement-url' => 'http://drupal.org/node/295383')), '#tree' => FALSE, '#weight' => 20, + '#after_build' => array('flag_link_type_options_states'), ); $form['display']['link_type'] = array( @@ -505,7 +506,10 @@ function flag_form($form, &$form_state, $flag) { } $form['display']['link_options_intro'] = array( - '#markup' => '', + // This is a hack to allow a markup element to use FormAPI states. + // @see http://www.bywombats.com/blog/06-25-2011/using-containers-states-enabled-markup-form-elements + '#type' => 'container', + '#children' => '', '#weight' => 20, ); @@ -556,6 +560,42 @@ function flag_form($form, &$form_state, $flag) { return $form; } +/** + * FormAPI after_build function set states on link type options fieldsets. + * + * We do this in an after build so we handle further link types fieldsets from + * other modules that provide link types. + * + * This expects a link type's fieldset to be $form['display'][link_options_TYPE] + * so that can be matched up with the radio button value. + */ +function flag_link_type_options_states($element) { + $intro_element_values_array = array(); + foreach (element_children($element) as $key) { + if (isset($element[$key]['#type']) && $element[$key]['#type'] == 'fieldset' && substr($key, 0, 12) == 'link_options') { + // Trim the radio value from the fieldset key. This assumed the fieldset + // key is 'link_options_TYPE'. + $radio_value = substr($key, 13); + $element[$key]['#states'] = array( + 'visible' => array( + ':input[name="link_type"]' => array('value' => $radio_value), + ), + ); + // Gather up the radio values for the format we need for a multiple + // value state. + $intro_element_values_array[] = array('value' => $radio_value); + } + } + + $element['link_options_intro']['#states'] = array( + 'visible' => array( + ':input[name="link_type"]' => $intro_element_values_array, + ), + ); + + return $element; +} + /** * Form process handler for locking flag properties. * diff --git a/theme/flag-admin.js b/theme/flag-admin.js index 7867149..5e028ea 100644 --- a/theme/flag-admin.js +++ b/theme/flag-admin.js @@ -40,33 +40,6 @@ Drupal.behaviors.flagRoles.attach = function(context) { } }; - -/** - * Behavior to make link options dependent on the link radio button. - */ -Drupal.behaviors.flagLinkOptions = {}; -Drupal.behaviors.flagLinkOptions.attach = function(context) { - $('.flag-link-options input.form-radio', context).change(function() { - // Reveal only the fieldset whose ID is link-options-LINKTYPE, - // where LINKTYPE is the value of the selected radio button. - var radioButton = this; - var $relevant = $('fieldset#link-options-' + radioButton.value); - var $irrelevant = $('fieldset[id^=link-options-]').not($relevant); - - $relevant.show(); - $irrelevant.hide(); - - if ($relevant.size()) { - $('#link-options-intro').show(); - } - else { - $('#link-options-intro').hide(); - } - }) - // Hide the link options by default if needed. - .filter(':checked').trigger('change'); -}; - /** * Vertical tabs integration. */ From cb31cf8708ddb71d67e8c0b26ed900bef51c97e3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 14 Jan 2013 15:17:29 +0000 Subject: [PATCH 265/629] Issue #1888330 by joachim: Removed check for flag property on node during node preview. --- flag.module | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/flag.module b/flag.module index d1aa0a6..c6a924a 100644 --- a/flag.module +++ b/flag.module @@ -794,13 +794,8 @@ function flag_form_alter(&$form, &$form_state, $form_id) { continue; } - if (isset($form['#node']->flag[$flag->name])) { - $flag_status = $form['#node']->flag[$flag->name]; - } - else { - $flag_status_default = variable_get('flag_' . $flag->name . '_default_' . $form['type']['#value'], 0); - $flag_status = $nid ? $flag->is_flagged($nid) : $flag_status_default; - } + $flag_status_default = variable_get('flag_' . $flag->name . '_default_' . $form['type']['#value'], 0); + $flag_status = $nid ? $flag->is_flagged($nid) : $flag_status_default; // If the flag is not global and the user doesn't have access, skip it. // Global flags have their value set even if the user doesn't have access From cf03d863a72c124a0504bc8aaaa63dc3f19b25ae Mon Sep 17 00:00:00 2001 From: chrisjlee Date: Wed, 16 Jan 2013 15:39:16 +0000 Subject: [PATCH 266/629] Issue #1888068 by chrisjlee: Remove empty hook_install() implementations. --- flag.install | 6 ------ flag_actions.install | 6 ------ flag_bookmark/flag_bookmark.install | 7 ------- 3 files changed, 19 deletions(-) diff --git a/flag.install b/flag.install index 83c93c8..7d31897 100644 --- a/flag.install +++ b/flag.install @@ -204,12 +204,6 @@ function flag_schema() { return $schema; } -/** - * Implements hook_install(). - */ -function flag_install() { -} - /** * Implements hook_uninstall(). */ diff --git a/flag_actions.install b/flag_actions.install index 5124393..a41286d 100644 --- a/flag_actions.install +++ b/flag_actions.install @@ -5,12 +5,6 @@ * Flag actions install file. */ -/** - * Implements hook_install(). - */ -function flag_actions_install() { -} - /** * Implements hook_uninstall(). */ diff --git a/flag_bookmark/flag_bookmark.install b/flag_bookmark/flag_bookmark.install index b67910c..bce09f2 100644 --- a/flag_bookmark/flag_bookmark.install +++ b/flag_bookmark/flag_bookmark.install @@ -5,13 +5,6 @@ * The Flag Bookmark module install hooks. */ -/** - * Implements hook_install(). - */ -function flag_bookmark_install() { - // Everything is handled by hook_enable(). -} - /** * Implements hook_enable(). * From 665294926540140cfccefe5523af7e14e4e2d8f4 Mon Sep 17 00:00:00 2001 From: vomiand Date: Wed, 16 Jan 2013 15:49:30 +0000 Subject: [PATCH 267/629] Issue #1888058 by vomiand: Removed check for flag_content module hook_requirements(). --- flag.install | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/flag.install b/flag.install index 7d31897..6b6c973 100644 --- a/flag.install +++ b/flag.install @@ -221,21 +221,10 @@ function flag_uninstall() { /** * Implements hook_requirements(). - * - * Prevent installing this module if the "Flag content" module is installed as well. */ function flag_requirements($phase) { $requirements = array(); $t = get_t(); - if ($phase == 'install') { - if (!defined('MAINTENANCE_MODE') && _flag_flag_content_installed()) { - $requirements['flag_content_clash'] = array( - 'title' => $t('Flag'), - 'severity' => REQUIREMENT_ERROR, - 'description' => _flag_flag_content_message(), - ); - } - } if ($phase == 'runtime') { if (module_exists('translation') && !module_exists('translation_helpers')) { @@ -268,20 +257,6 @@ function flag_requirements($phase) { return $requirements; } -/** - * Returns TRUE if the "Flag content" module, which we aren't compatible with, - * is installed. - */ -function _flag_flag_content_installed() { - $version = @drupal_get_installed_schema_version('flag_content', TRUE); - return (isset($version) && $version != SCHEMA_UNINSTALLED); -} - -function _flag_flag_content_message() { - $t = get_t(); - return $t("You are trying to install the Flag module. However, you have the \"Flag content\" module installed, and these two modules aren't compatible (because they happen to use a database table by the same name). To install the Flag module, you'll first have to disable and then uninstall the \"Flag content\" module.", array('@uninstall-url' => url('admin/modules/uninstall'))); -} - function flag_update_last_removed() { return 6004; } From 303c07a76af8643ff8d4e91a30b77ab245c6cec6 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 16 Jan 2013 15:55:51 +0000 Subject: [PATCH 268/629] Issue #891722 by mooffie, joachim: Removed [node:type] hack for token replacement where there is no real node available. --- flag.module | 21 ++++++++++++++++++--- includes/flag/flag_node.inc | 19 ++++++------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/flag.module b/flag.module index c6a924a..a3c6fdb 100644 --- a/flag.module +++ b/flag.module @@ -622,10 +622,18 @@ function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { $flags = flag_get_flags('node', $form['#node_type']->type, $user); foreach ($flags as $flag) { if ($flag->show_on_form) { + // To be able to process node tokens in flag labels, we create a fake + // node and store it in the flag's cache for replace_tokens() to find, + // with a fake ID. + $flag->remember_entity('fake', (object) array( + 'nid' => NULL, + 'type' => $form['#node_type']->type, + 'title' => '', + )); $var = 'flag_' . $flag->name . '_default'; $form['workflow']['flag'][$var] = array( '#type' => 'checkbox', - '#title' => $flag->get_label('flag_short', $form['#node_type']->type), + '#title' => $flag->get_label('flag_short', 'fake'), '#default_value' => variable_get($var . '_' . $form['#node_type']->type, 0), '#return_value' => 1, ); @@ -808,11 +816,18 @@ function flag_form_alter(&$form, &$form_state, $form_id) { continue; } + if (!$nid) { + // To be able to process node tokens for a node which hasn't yet been + // saved (e.g., on node/add/article), we "save" it to the flag's cache + // under a pseudo ID. + $flag->remember_entity('new', $form['#node']); + } + // Add the flag checkbox if displaying on the form. $form['flag'][$flag->name] = array( '#type' => 'checkbox', - '#title' => $flag->get_label('flag_short', $nid ? $nid : $form['type']['#value']), - '#description' => $flag->get_label('flag_long', $nid ? $nid : $form['type']['#value']), + '#title' => $flag->get_label('flag_short', $nid ? $nid : 'new'), + '#description' => $flag->get_label('flag_long', $nid ? $nid : 'new'), '#default_value' => $flag_status, '#return_value' => 1, '#attributes' => array('title' => $flag->get_title()), // Used by our drupalSetSummary(). diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index a6f827c..db9141c 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -132,20 +132,13 @@ class flag_node extends flag_entity { return parent::get_flagging_record($entity_id, $uid, $sid); } + /** + * This is overridden for no other purpose than to document that $entity_id + * can be one of the following fake IDs in certain contexts: + * - 'new': On a new node form. + * - 'fake': On the node type admin form. + */ function replace_tokens($label, $contexts, $options, $entity_id) { - if (is_numeric($entity_id) && ($node = $this->fetch_entity($entity_id))) { - $contexts['node'] = $node; - } - // Nodes accept the node-type as a $entity_id in the case that a new node - // is being created and a full node object does not yet exist. - elseif (!empty($entity_id) && ($type = node_type_get_type($entity_id))) { - $entity_id = NULL; - $contexts['node'] = (object) array( - 'nid' => NULL, - 'type' => $type->type, - 'title' => '', - ); - } return parent::replace_tokens($label, $contexts, $options, $entity_id); } } From 3c90443c971bbb1c988d239f193a02a5e5350951 Mon Sep 17 00:00:00 2001 From: alexweber Date: Wed, 16 Jan 2013 21:31:34 +0000 Subject: [PATCH 269/629] Issue #1890520 by alexweber: Removed unused global in flag_link(). --- flag.module | 1 - 1 file changed, 1 deletion(-) diff --git a/flag.module b/flag.module index a3c6fdb..262b8ea 100644 --- a/flag.module +++ b/flag.module @@ -947,7 +947,6 @@ function flag_link($type, $entity = NULL, $teaser = FALSE) { if (!isset($entity) || !flag_fetch_definition($type)) { return; } - global $user; // Get all possible flags for this entity type. $flags = flag_get_flags($type); From 669b5225b71719659d9ecbc81e675ac58ad43a10 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 17 Jan 2013 13:53:13 +0000 Subject: [PATCH 270/629] Issue #1890856 by joachim: Fixed calls to Views 2 compatibility methods (removed by 93cf7f9) in Views flaggability plugin. --- ..._plugin_argument_validate_flaggability.inc | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/includes/views/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc index c8f6e30..f653412 100644 --- a/includes/views/flag_plugin_argument_validate_flaggability.inc +++ b/includes/views/flag_plugin_argument_validate_flaggability.inc @@ -33,35 +33,35 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v } $options = $this->flags_options(); - $form[$this->_option_name('flag_name')] = array( + $form['flag_name'] = array( '#type' => 'radios', '#title' => t('Flag'), '#options' => $options, - '#default_value' => $this->_get_option('flag_name', '*relationship*'), + '#default_value' => $this->options['flag_name'], '#description' => t('Select the flag to validate against.'), ); if (!$options) { - $form[$this->_option_name('flag_name')]['#description'] = '

' . t('No %type flags exist. You must first create a %type flag before being able to use one.', array('%type' => $this->flag_type, '@create-url' => FLAG_ADMIN_PATH)) . '

'; + $form['flag_name']['#description'] = '

' . t('No %type flags exist. You must first create a %type flag before being able to use one.', array('%type' => $this->flag_type, '@create-url' => FLAG_ADMIN_PATH)) . '

'; } - $form[$this->_option_name('flag_test')] = array( + $form['flag_test'] = array( '#type' => 'select', '#title' => t('Validate the @type only if', array('@type' => $this->flag_type)), '#options' => $this->tests_options(), - '#default_value' => $this->_get_option('flag_test', 'flaggable'), + '#default_value' => $this->options['flag_test'], ); // This validator supports the "multiple IDs" syntax. It may not be // extremely useful, but similar validators do support this and it's a good // thing to be compatible. - $form[$this->_option_name('flag_id_type')] = array( + $form['flag_id_type'] = array( '#type' => 'select', '#title' => t('Argument type'), '#options' => array( 'id' => t('ID'), 'ids' => t('IDs separated by , or +'), ), - '#default_value' => $this->_get_option('flag_id_type', 'id'), + '#default_value' => $this->options['flag_id_type'], ); } @@ -125,7 +125,7 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v } function get_flag() { - $flag_name = $this->_get_option('flag_name', '*relationship*'); + $flag_name = $this->options['flag_name']; if ($flag_name == '*relationship*') { // Pick the first flag mentioned in the relationships. @@ -149,8 +149,8 @@ class flag_plugin_argument_validate_flaggability extends views_plugin_argument_v * carry out is determined by 'flag_test'. */ function validate_argument($argument) { - $flag_test = $this->_get_option('flag_test', 'flaggable'); - $id_type = $this->_get_option('flag_id_type', 'id'); + $flag_test = $this->options['flag_test']; + $id_type = $this->options['flag_id_type']; $flag = $this->get_flag(); if (!$flag) { From 44ed7fe7f2e8fc30bc8a66fe386214f2ec32617a Mon Sep 17 00:00:00 2001 From: alexweber Date: Sun, 20 Jan 2013 11:28:07 +0000 Subject: [PATCH 271/629] Issue #1887738 by alexweber: Changed _flag_url() to a class method. --- flag.module | 7 ------- includes/flag/flag_comment.inc | 2 +- includes/flag/flag_entity.inc | 2 +- includes/flag/flag_flag.inc | 7 +++++++ includes/flag/flag_user.inc | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/flag.module b/flag.module index 262b8ea..290b196 100644 --- a/flag.module +++ b/flag.module @@ -527,13 +527,6 @@ function flag_create_handler($entity_type) { return $handler; } -/** - * A shortcut function to output the link URL. - */ -function _flag_url($path, $fragment = NULL, $absolute = TRUE) { - return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); -} - /** * Implements hook_permission(). */ diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 4930d77..19158fd 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -102,7 +102,7 @@ class flag_comment extends flag_entity { $flag_action = parent::get_flag_action($entity_id); $comment = $this->fetch_entity($entity_id); $flag_action->content_title = $comment->subject; - $flag_action->content_url = _flag_url("comment/$comment->cid", "comment-$comment->cid"); + $flag_action->content_url = $this->_flag_url("comment/$comment->cid", "comment-$comment->cid"); return $flag_action; } diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 389becb..0f3c457 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -174,7 +174,7 @@ class flag_entity extends flag_flag { $flag_action = parent::get_flag_action($entity_id); $entity = $this->fetch_entity($entity_id); $flag_action->content_title = entity_label($this->entity_type, $entity); - $flag_action->content_url = _flag_url($this->entity_type . '/' . $this->get_entity_id($entity)); + $flag_action->content_url = $this->_flag_url($this->entity_type . '/' . $this->get_entity_id($entity)); return $flag_action; } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 0bda839..51f2a7d 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1464,6 +1464,13 @@ class flag_flag { $suggestions[] = 'flag'; return $suggestions; } + + /** + * A shortcut function to output the link URL. + */ + function _flag_url($path, $fragment = NULL, $absolute = TRUE) { + return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); + } } /** diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc index 17d7ab3..b438d13 100644 --- a/includes/flag/flag_user.inc +++ b/includes/flag/flag_user.inc @@ -84,7 +84,7 @@ class flag_user extends flag_entity { $flag_action = parent::get_flag_action($entity_id); $user = $this->fetch_entity($entity_id); $flag_action->content_title = $user->name; - $flag_action->content_url = _flag_url('user/' . $user->uid); + $flag_action->content_url = $this->_flag_url('user/' . $user->uid); return $flag_action; } From af881f536599f4e5764edd122aa35385649c4782 Mon Sep 17 00:00:00 2001 From: alexweber Date: Sun, 20 Jan 2013 11:30:06 +0000 Subject: [PATCH 272/629] Issue #1862404 by alexweber: Fixed mention of node_type in flag_schema() field comments. --- flag.install | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.install b/flag.install index 6b6c973..d68671c 100644 --- a/flag.install +++ b/flag.install @@ -127,7 +127,7 @@ function flag_schema() { ); $schema['flag_types'] = array( - 'description' => 'The types (usually as defined in {node_type}) that are affected by a flag.', + 'description' => 'The entity bundles that are affected by a flag.', 'fields' => array( 'fid' => array( 'description' => 'The unqiue flag ID as defined for the flag in {flag}.', @@ -138,7 +138,7 @@ function flag_schema() { 'default' => 0, ), 'type' => array( - 'description' => 'The types (usually from {node_type}) that can be flagged by this fid.', + 'description' => 'The entity bundles that can be flagged by this fid.', 'type' => 'varchar', 'length' => '128', 'not null' => TRUE, From 24e01fc82f08bd547260ea8e911bc0ef02ff0275 Mon Sep 17 00:00:00 2001 From: alexweber Date: Sun, 20 Jan 2013 11:32:02 +0000 Subject: [PATCH 273/629] Issue #1888036 by alexweber: Removed flag_get_entity_id(). --- flag.module | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/flag.module b/flag.module index 290b196..ed35c51 100644 --- a/flag.module +++ b/flag.module @@ -1908,20 +1908,6 @@ function flag_get_flag_flagging_data($flag_name) { return $result->fetchAllAssoc('flagging_id'); } -/** - * Get entity ID from a flag content ID. - * - * @param $flagging_id - * The flag content ID for which to look up the entity ID. - */ -function flag_get_entity_id($flagging_id) { - return db_select('flagging', 'fc') - ->fields('fc', array('entity_id')) - ->condition('flagging_id', $flagging_id) - ->execute() - ->fetchField(); -} - /** * Find what a user has flagged, either a single node or on the entire site. * From 06948cba4aeda866894ac963376707c71b9d1816 Mon Sep 17 00:00:00 2001 From: alexweber Date: Mon, 21 Jan 2013 09:56:09 +0000 Subject: [PATCH 274/629] Issue #1886560 by alexweber: Removed reset parameter in flag_get_user_flags() in favour of drupal_static_reset(). --- flag.module | 11 +---------- includes/flag/flag_flag.inc | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/flag.module b/flag.module index ed35c51..141140b 100644 --- a/flag.module +++ b/flag.module @@ -1923,8 +1923,6 @@ function flag_get_flag_flagging_data($flag_name) { * Optional. The user SID (provided by Session API) whose flags we're * checking. If none given, the current user will be used. The SID is 0 for * logged in users. - * @param $reset - * Reset the internal cache and execute the SQL query another time. * * @return $flags * If returning a single item's flags (that is, when $entity_id isn't NULL), @@ -1935,16 +1933,9 @@ function flag_get_flag_flagging_data($flag_name) { * [flag_name] => [entity_id] => Object from above. * */ -function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid = NULL, $reset = FALSE) { +function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid = NULL) { $flagged_content = &drupal_static(__FUNCTION__); - if ($reset) { - $flagged_content = array(); - if (!isset($entity_type)) { - return; - } - } - $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid; $sid = !isset($sid) ? flag_get_sid($uid) : $sid; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 51f2a7d..fc62da4 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -677,7 +677,7 @@ class flag_flag { // Clear various caches; We don't want code running after us to report // wrong counts or false flaggings. flag_get_counts(NULL, NULL, TRUE); - flag_get_user_flags(NULL, NULL, NULL, NULL, TRUE); + drupal_static_reset('flag_get_user_flags'); drupal_static_reset('flag_get_entity_flags'); // Find out which user id to use. From 3413948f6f8377c16adc3a1c78c4b8c8463359d2 Mon Sep 17 00:00:00 2001 From: alexweber Date: Mon, 21 Jan 2013 19:18:26 +0000 Subject: [PATCH 275/629] Issue #1894030 by alexweber: Removed reset parameter in flag_get_counts() in favour of drupal_static_reset(). --- flag.module | 11 +---------- includes/flag/flag_flag.inc | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/flag.module b/flag.module index 141140b..22d1051 100644 --- a/flag.module +++ b/flag.module @@ -1650,22 +1650,13 @@ function _flag_link_type_descriptions() { * The entity type (usually 'node'). * @param $entity_id * The entity ID (usually the node ID). - * @param $reset - * Reset the internal cache and execute the SQL query another time. * * @return $flags * An array of the structure [name] => [number of flags]. */ -function flag_get_counts($entity_type, $entity_id, $reset = FALSE) { +function flag_get_counts($entity_type, $entity_id) { $counts = &drupal_static(__FUNCTION__); - if ($reset) { - $counts = array(); - if (!isset($entity_type)) { - return; - } - } - if (!isset($counts[$entity_type][$entity_id])) { $counts[$entity_type][$entity_id] = array(); $query = db_select('flag', 'f'); diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index fc62da4..462af15 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -676,7 +676,7 @@ class flag_flag { // Clear various caches; We don't want code running after us to report // wrong counts or false flaggings. - flag_get_counts(NULL, NULL, TRUE); + drupal_static_reset('flag_get_counts'); drupal_static_reset('flag_get_user_flags'); drupal_static_reset('flag_get_entity_flags'); From 7fb7e11ce3c5be13b3460ff1abea6242553816c7 Mon Sep 17 00:00:00 2001 From: alexweber Date: Mon, 21 Jan 2013 20:04:48 +0000 Subject: [PATCH 276/629] Issue #1862710 by alexweber: Fixed PHP notice for entities without a base table. --- includes/flag/flag_entity.inc | 5 +++++ includes/views/flag.views.inc | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 0f3c457..c30efa5 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -192,6 +192,11 @@ class flag_entity extends flag_flag { */ function get_views_info() { $entity_info = entity_get_info($this->entity_type); + + if (!isset($entity_info['base table'])) { + return NULL; + } + return array( 'views table' => $entity_info['base table'], 'join field' => $entity_info['entity keys']['id'], diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc index 7d0cb01..4d3c216 100644 --- a/includes/views/flag.views.inc +++ b/includes/views/flag.views.inc @@ -170,6 +170,10 @@ function flag_views_data_alter(&$data) { $flag = flag_flag::factory_by_entity_type($flag_type); $info = $flag->get_views_info(); + if (!isset($info)) { + continue; + } + if (!empty($info['join field'])) { // Add the flag relationship. $data[$info['views table']]['flag_content_rel'] = array( From fb040bcc5df3798f3552908944a54007e4e189b1 Mon Sep 17 00:00:00 2001 From: alexweber Date: Tue, 22 Jan 2013 11:13:45 +0000 Subject: [PATCH 277/629] Issue #1888074 by alexweber: Removed unused implementation of hook_mail(). --- flag.module | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/flag.module b/flag.module index 22d1051..23f9272 100644 --- a/flag.module +++ b/flag.module @@ -1450,18 +1450,6 @@ function flag_flag_access_multiple($flag, $entity_ids, $account) { return $access; } -/** - * Implements hook_mail(). - */ -function flag_mail($key, &$message, $params) { - switch ($key) { - case 'over_threshold': - $message['subject'] = $params['subject']; - $message['body'] = $params['body']; - break; - } -} - /** * Implements hook_theme(). */ From 76ae02f204c9f32f0aee897c83765a8822e6a0b2 Mon Sep 17 00:00:00 2001 From: alexweber Date: Sat, 26 Jan 2013 20:18:20 +0000 Subject: [PATCH 278/629] Issue #1864246 by alexweber: Removed old Views Bookmark logic in updateLink(). --- theme/flag.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/theme/flag.js b/theme/flag.js index 86288f0..c8442e7 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -33,11 +33,6 @@ Drupal.flagLink = function(context) { // Find the wrapper of the old link. var $wrapper = $(element).parents('.flag-wrapper:first'); - if ($wrapper.length == 0) { - // If no ancestor wrapper was found, or if the 'flag-wrapper' class is - // attached to the element itself, then take the element itself. - $wrapper = $(element); - } // Replace the old link with the new one. $wrapper.after($newLink).remove(); Drupal.attachBehaviors($newLink.get(0)); From b38338fb84b05d535a323266c632a6c2c0ad83e4 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 30 Jan 2013 22:21:27 +0000 Subject: [PATCH 279/629] Issue #952114 by mooffie, acrollet, snufkin: Added hook_flag_validate(). --- flag.api.php | 36 +++++++++++++++++++++ flag.module | 28 ++++++++++++++--- includes/flag.pages.inc | 63 ++++++++++++++++++++----------------- includes/flag/flag_flag.inc | 31 ++++++++++++++++-- theme/flag.css | 8 +++++ theme/flag.js | 20 ++++-------- theme/flag.tpl.php | 4 ++- 7 files changed, 141 insertions(+), 49 deletions(-) diff --git a/flag.api.php b/flag.api.php index da2fb7e..64b205f 100644 --- a/flag.api.php +++ b/flag.api.php @@ -120,6 +120,42 @@ function hook_flag_unflag($flag, $entity_id, $account, $flagging) { } +/** + * Perform custom validation on a flag before flagging/unflagging. + * + * @param $action + * The action about to be carried out. Either 'flag' or 'unflag'. + * @param $flag + * The flag object. + * @param $entity_id + * The id of the entity the user is trying to flag or unflag. + * @param $account + * The user account performing the action. + * @param $flagging + * The flagging entity. + * + * @return + * Optional array: textual error with the error-name as the key. + * If the error name is 'access-denied' and javascript is disabled, + * drupal_access_denied will be called and a 403 will be returned. + * If validation is successful, do not return a value. + */ +function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permission_check, $flagging) { + // We're only operating on the "test" flag, and users may always unflag. + if ($flag->name == 'test' && $action == 'flag') { + // Get all flags set by the current user. + $flags = flag_get_user_flags('node', NULL, $account->uid, $sid = NULL, $reset = FALSE); + // Check if this user has any flags of this type set. + if (isset($flags['test'])) { + $count = count($flags[$flag->name]); + if ($count >= 2) { + // Users may flag only 2 nodes with this flag. + return(array('access-denied' => t('You may only flag 2 nodes with the test flag.'))); + } + } + } +} + /** * Allow modules to allow or deny access to flagging. * diff --git a/flag.module b/flag.module index 23f9272..6a8debc 100644 --- a/flag.module +++ b/flag.module @@ -1463,6 +1463,7 @@ function flag_theme() { 'action' => NULL, 'entity_id' => NULL, 'after_flagging' => FALSE, + 'errors' => array(), ), 'template' => 'flag', 'pattern' => 'flag__', @@ -1510,6 +1511,7 @@ function flag_theme() { * - $action * - $entity_id * - $after_flagging + * - $errors * * See 'flag.tpl.php' for their documentation. */ @@ -1521,6 +1523,7 @@ function template_preprocess_flag(&$variables) { $flag =& $variables['flag']; $action = $variables['action']; $entity_id = $variables['entity_id']; + $errors = join('
', $variables['errors']); $flag_css_name = str_replace('_', '-', $flag->name); // Generate the link URL. @@ -1563,7 +1566,6 @@ function template_preprocess_flag(&$variables) { $variables['flag_wrapper_classes_array'][] = 'flag-wrapper'; $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name; $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name . '-' . $entity_id; - $variables['flag_wrapper_classes'] = implode(' ', $variables['flag_wrapper_classes_array']); $variables['flag_classes_array'] = array(); $variables['flag_classes_array'][] = 'flag'; @@ -1578,12 +1580,30 @@ function template_preprocess_flag(&$variables) { $link['attributes']['class'] = is_string($link['attributes']['class']) ? array_filter(explode(' ', $link['attributes']['class'])) : $link['attributes']['class']; $variables['flag_classes_array'] = array_merge($variables['flag_classes_array'], $link['attributes']['class']); } + $variables['message_classes_array'] = array(); if ($variables['after_flagging']) { - $inverse_action = ($action == 'flag' ? 'unflag' : 'flag'); - $variables['message_text'] = $flag->get_label($inverse_action . '_message', $entity_id); - $variables['flag_classes_array'][] = $variables['status']; + $variables['message_classes_array'][] = 'flag-message'; + if ($errors) { + $variables['message_classes_array'][] = 'flag-failure-message'; + $variables['message_text'] = $errors; + } + else { + $inverse_action = ($action == 'flag' ? 'unflag' : 'flag'); + $variables['message_classes_array'][] = 'flag-success-message'; + $variables['message_classes_array'][] = 'flag-' . $variables['status'] . '-message'; + $variables['message_text'] = $flag->get_label($inverse_action . '_message', $entity_id); + $variables['flag_classes_array'][] = $variables['status']; + // By default we make our JS code remove, after a few seconds, only success messages. + $variables['message_classes_array'][] = 'flag-auto-remove'; + } } + else { + $variables['message_text'] = ''; + } + + $variables['flag_wrapper_classes'] = implode(' ', $variables['flag_wrapper_classes_array']); $variables['flag_classes'] = implode(' ', $variables['flag_classes_array']); + $variables['message_classes'] = join(' ', $variables['message_classes_array']); // Backward compatibility: The following section preserves some deprecated // variables either to make old flag.tpl.php files continue to work, or to diff --git a/includes/flag.pages.inc b/includes/flag.pages.inc index e30d928..695c2bd 100644 --- a/includes/flag.pages.inc +++ b/includes/flag.pages.inc @@ -23,47 +23,48 @@ function flag_page($action, $flag, $entity_id) { // Specifically $_GET to avoid getting the $_COOKIE variable by the same key. $has_js = isset($_GET['has_js']); - // Check the flag token, then perform the flagging. + // Check the flag token, and then javascript status. if (!flag_check_token($token, $entity_id)) { - $error = t('Bad token. You seem to have followed an invalid link.'); + $flag->errors['token'] = t('Bad token. You seem to have followed an invalid link.'); } elseif ($user->uid == 0 && !$has_js) { - $error = t('You must have JavaScript and cookies enabled in your browser to flag content.'); - } - else { - $result = $flag->flag($action, $entity_id); - if (!$result) { - $error = t('You are not allowed to flag, or unflag, this content.'); - } + $flag->errors['javascript'] = t('You must have JavaScript and cookies enabled in your browser to flag content.'); } - // If an error was received, set a message and exit. - if (isset($error)) { - if ($js) { - drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); - print drupal_json_encode(array( - 'status' => FALSE, - 'errorMessage' => $error, - )); - drupal_exit(); - } - else { - drupal_set_message($error); - drupal_access_denied(); - return; - } + // If no errors have been detected thus far, perform the flagging. + // Further errors may still be detected during validation and prevent + // the operation from succeeding. + if (!$flag->errors) { + $flag->flag($action, $entity_id); } // If successful, return data according to the request type. if ($js) { drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); $flag->link_type = 'toggle'; + // Any errors that have been set will be output below + // the flag link with javascript. print drupal_json_encode(flag_build_javascript_info($flag, $entity_id)); drupal_exit(); } else { - drupal_set_message($flag->get_label($action . '_message', $entity_id)); - drupal_goto(); + $errors = $flag->get_errors(); + if ($errors) { + // If an error was received, set a message and exit. + foreach ($errors as $error) { + drupal_set_message($error, 'error'); + } + if (isset($errors['access-denied'])) { + drupal_access_denied(); + } + else { + drupal_goto(); + } + } + else { + drupal_set_message($flag->get_label($action . '_message', $entity_id)); + drupal_goto(); + } } } @@ -130,7 +131,11 @@ function flag_confirm_submit(&$form, &$form_state) { } if (!$result) { - drupal_set_message(t('You are not allowed to flag, or unflag, this content.')); + if ($errors = $flag->get_errors()) { + foreach ($errors as $error) { + drupal_set_message($error, 'error'); + } + } } else { drupal_set_message($flag->get_label($action . '_message', $entity_id)); @@ -141,10 +146,12 @@ function flag_confirm_submit(&$form, &$form_state) { * Builds the JavaScript structure describing the flagging operation. */ function flag_build_javascript_info($flag, $entity_id) { + $errors = $flag->get_errors(); $info = array( 'status' => TRUE, - 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, TRUE), + 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, TRUE, $errors), // Further information for the benefit of custom JavaScript event handlers: + 'flagSuccess' => !$errors, 'contentId' => $entity_id, 'entityType' => $flag->entity_type, 'flagName' => $flag->name, diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 462af15..edf1c0d 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -93,6 +93,18 @@ class flag_flag { 'unflag' => array(), ); + /** + * An associative array containing textual errors that may be created during validation. + * + * The array keys should reflect the type of error being set. At this time, + * the only "special" behavior related to the array keys is that + * drupal_access_denied() is called when the key is 'access-denied' and + * javascript is disabled. + * + * @var array + */ + var $errors = array(); + /** * Creates a flag from a database row. Returns it. * @@ -651,7 +663,7 @@ class flag_flag { * applicable to the item, etc.), TRUE otherwise. */ function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { - // Get the user. + // Get the user. if (!isset($account)) { $account = $GLOBALS['user']; } @@ -662,6 +674,7 @@ class flag_flag { // Check access and applicability. if (!$skip_permission_check) { if (!$this->access($entity_id, $action, $account)) { + $this->errors['access-denied'] = t('You are not allowed to flag, or unflag, this content.'); // User has no permission to flag/unflag this object. return FALSE; } @@ -670,10 +683,15 @@ class flag_flag { // We are skipping permission checks. However, at a minimum we must make // sure the flag applies to this entity type: if (!$this->applies_to_entity_id($entity_id)) { + $this->errors['entity-type'] = t('This flag does not apply to this entity type.'); return FALSE; } } + if (($this->errors = module_invoke_all('flag_validate', $action, $this, $entity_id, $account, $skip_permission_check, $flagging))) { + return FALSE; + } + // Clear various caches; We don't want code running after us to report // wrong counts or false flaggings. drupal_static_reset('flag_get_counts'); @@ -691,6 +709,7 @@ class flag_flag { $sid = flag_get_sid($uid, TRUE); // Anonymous users must always have a session id. if ($sid == 0 && $account->uid == 0) { + $this->errors['session'] = t('Internal error: You are anonymous but you have no session ID.'); return FALSE; } } @@ -1161,6 +1180,13 @@ class flag_flag { return $flag_action; } + /** + * Returns an array of errors set during validation. + */ + function get_errors() { + return $this->errors; + } + /** * @addtogroup actions * @{ @@ -1409,7 +1435,7 @@ class flag_flag { * * For parameters documentation, see flag.tpl.php. */ - function theme($action, $entity_id, $after_flagging = FALSE) { + function theme($action, $entity_id, $after_flagging = FALSE, $errors = array()) { static $js_added = array(); global $user; @@ -1451,6 +1477,7 @@ class flag_flag { 'action' => $action, 'entity_id' => $entity_id, 'after_flagging' => $after_flagging, + 'errors' => $errors, )); } diff --git a/theme/flag.css b/theme/flag.css index 610b4b0..f43eb1b 100644 --- a/theme/flag.css +++ b/theme/flag.css @@ -9,6 +9,14 @@ font-size: .8em; } +.flag-message.flag-failure-message { + border: 1px solid ; + border-color: #ed5; + color: #840; + background-color: #fffce5; + padding: 2px; +} + .flag-wrapper { position: relative; } diff --git a/theme/flag.js b/theme/flag.js index c8442e7..1b3bb38 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -38,7 +38,7 @@ Drupal.flagLink = function(context) { Drupal.attachBehaviors($newLink.get(0)); $('.flag-message', $newLink).fadeIn(); - setTimeout(function(){ $('.flag-message', $newLink).fadeOut() }, 3000); + setTimeout(function(){ $('.flag-message.flag-auto-remove', $newLink).fadeOut() }, 3000); return $newLink.get(0); } @@ -73,20 +73,12 @@ Drupal.flagLink = function(context) { data: { js: true }, dataType: 'json', success: function (data) { - if (data.status) { - // Success. - data.link = $wrapper.get(0); - $.event.trigger('flagGlobalBeforeLinkUpdate', [data]); - if (!data.preventDefault) { // A handler may cancel updating the link. - data.link = updateLink(element, data.newLink); - } - $.event.trigger('flagGlobalAfterLinkUpdate', [data]); - } - else { - // Failure. - alert(data.errorMessage); - $wrapper.removeClass('flag-waiting'); + data.link = $wrapper.get(0); + $.event.trigger('flagGlobalBeforeLinkUpdate', [data]); + if (!data.preventDefault) { // A handler may cancel updating the link. + data.link = updateLink(element, data.newLink); } + $.event.trigger('flagGlobalAfterLinkUpdate', [data]); }, error: function (xmlhttp) { alert('An HTTP error '+ xmlhttp.status +' occurred.\n'+ element.href); diff --git a/theme/flag.tpl.php b/theme/flag.tpl.php index d086f82..df6bfdc 100644 --- a/theme/flag.tpl.php +++ b/theme/flag.tpl.php @@ -21,6 +21,8 @@ * - $link_title: The title attribute for the link. * * - $message_text: The long message to show after a flag action has been carried out. + * - $message_classes: A space-separated list of CSS classes that should be applied to + * the message. * - $after_flagging: This template is called for the link both before and after being * flagged. If displaying to the user immediately after flagging, this value * will be boolean TRUE. This is usually used in conjunction with immedate @@ -42,7 +44,7 @@ - + From 5be70f8c74a6890fbc66015a476d2e3775239a38 Mon Sep 17 00:00:00 2001 From: alexweber Date: Thu, 7 Feb 2013 20:52:17 +0000 Subject: [PATCH 280/629] Issue #1905750 by alexweber: Added implementations of hook_flag_type_info() on behalf of non-required core modules. --- flag.flag.inc | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/flag.flag.inc b/flag.flag.inc index 254b593..de98ad5 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -8,14 +8,17 @@ /** * Implements hook_flag_type_info(). * - * Defines the flag types this module implements. + * We define flag types for those Core entities we specifically cater for whose + * modules are required by Drupal core. Other core entities we cater for have + * their flag type defined in implementations of this hook on behalf of their + * providing modules, so that the entity's module is correctly picked up as a + * dependency. * * @return * An "array of arrays", keyed by object type. The 'handler' slot * should point to the PHP class implementing this flag. */ function flag_flag_type_info() { - // Entity types we specifically cater for. $definitions = array( 'node' => array( 'title' => t('Nodes'), @@ -29,13 +32,31 @@ function flag_flag_type_info() { ), ); - if (module_exists('comment')) { - $definitions['comment'] = array( - 'title' => t('Comments'), - 'description' => t('Comments are responses to node content.'), - 'handler' => 'flag_comment', - ); - } + return $definitions; +} + +/** + * Implement hook_flag_type_info() on behalf of the core Comment module. + */ +function comment_flag_type_info() { + $definitions['comment'] = array( + 'title' => t('Comments'), + 'description' => t('Comments are responses to node content.'), + 'handler' => 'flag_comment', + ); + + return $definitions; +} + +/** + * Implement hook_flag_type_info() on behalf of the core Taxonomy module. + */ +function taxonomy_flag_type_info() { + $definitions['taxonomy_term'] = array( + 'title' => t('Taxonomy Terms'), + 'description' => t('Taxonomy terms are used to categorize content.'), + 'handler' => 'flag_entity', + ); return $definitions; } From b2e1289fec2b0ad88429acad081c22b9aae23ca9 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 8 Feb 2013 16:34:13 +0000 Subject: [PATCH 281/629] Revert "Issue #1905750 by alexweber: Added implementations of hook_flag_type_info() on behalf of non-required core modules." This reverts commit 5be70f8c74a6890fbc66015a476d2e3775239a38. --- flag.flag.inc | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/flag.flag.inc b/flag.flag.inc index de98ad5..254b593 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -8,17 +8,14 @@ /** * Implements hook_flag_type_info(). * - * We define flag types for those Core entities we specifically cater for whose - * modules are required by Drupal core. Other core entities we cater for have - * their flag type defined in implementations of this hook on behalf of their - * providing modules, so that the entity's module is correctly picked up as a - * dependency. + * Defines the flag types this module implements. * * @return * An "array of arrays", keyed by object type. The 'handler' slot * should point to the PHP class implementing this flag. */ function flag_flag_type_info() { + // Entity types we specifically cater for. $definitions = array( 'node' => array( 'title' => t('Nodes'), @@ -32,31 +29,13 @@ function flag_flag_type_info() { ), ); - return $definitions; -} - -/** - * Implement hook_flag_type_info() on behalf of the core Comment module. - */ -function comment_flag_type_info() { - $definitions['comment'] = array( - 'title' => t('Comments'), - 'description' => t('Comments are responses to node content.'), - 'handler' => 'flag_comment', - ); - - return $definitions; -} - -/** - * Implement hook_flag_type_info() on behalf of the core Taxonomy module. - */ -function taxonomy_flag_type_info() { - $definitions['taxonomy_term'] = array( - 'title' => t('Taxonomy Terms'), - 'description' => t('Taxonomy terms are used to categorize content.'), - 'handler' => 'flag_entity', - ); + if (module_exists('comment')) { + $definitions['comment'] = array( + 'title' => t('Comments'), + 'description' => t('Comments are responses to node content.'), + 'handler' => 'flag_comment', + ); + } return $definitions; } From 2c308c0311ed428109361385235a1f43a966dd5e Mon Sep 17 00:00:00 2001 From: alexweber Date: Fri, 8 Feb 2013 20:09:13 +0000 Subject: [PATCH 282/629] Issue #1905750 by alexweber: Added module property to hook_flag_type_info(), and explicitly defined taxonomy term flag type, so that non-required core modules correctly declare dependencies. --- flag.api.php | 3 +++ flag.flag.inc | 10 ++++++++++ includes/flag.features.inc | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/flag.api.php b/flag.api.php index 64b205f..9feb8f8 100644 --- a/flag.api.php +++ b/flag.api.php @@ -25,6 +25,8 @@ * - 'description': A longer description shown in the UI when creating a new * flag. * - 'handler': The name of the class implementing this flag type. + * - 'module': (optional) The name of the module that should be registered as a + * dependency for this flag type. * * @see flag_fetch_definition() */ @@ -34,6 +36,7 @@ function hook_flag_type_info() { 'title' => t('Nodes'), 'description' => t("Nodes are a Drupal site's primary content."), 'handler' => 'flag_node', + 'module' => 'node', ), ); } diff --git a/flag.flag.inc b/flag.flag.inc index 254b593..c7ff2ec 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -34,6 +34,16 @@ function flag_flag_type_info() { 'title' => t('Comments'), 'description' => t('Comments are responses to node content.'), 'handler' => 'flag_comment', + 'module' => 'comment', + ); + } + + if (module_exists('taxonomy')) { + $definitions['taxonomy_term'] = array( + 'title' => t('Taxonomy Terms'), + 'description' => t('Taxonomy terms are used to categorize content.'), + 'handler' => 'flag_entity', + 'module' => 'taxonomy', ); } diff --git a/includes/flag.features.inc b/includes/flag.features.inc index 23ad242..a3a1064 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -85,7 +85,7 @@ function flag_features_providing_module() { $hook = 'flag_type_info'; foreach (module_implements($hook) as $module) { foreach (module_invoke($module, $hook) as $key => $value) { - $modules[$key] = $module; + $modules[$key] = isset($value['module']) ? $value['module'] : $module; } } return $modules; From 4137641df0a7069f5e221c23c0c35127d621262b Mon Sep 17 00:00:00 2001 From: alexweber Date: Fri, 8 Feb 2013 20:17:51 +0000 Subject: [PATCH 283/629] Issue #1905766 by alexweber: Removed declaration of flag type for taxonomy vocabularies. --- flag.flag.inc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/flag.flag.inc b/flag.flag.inc index c7ff2ec..242ab77 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -62,6 +62,13 @@ function flag_flag_type_info_alter(&$definitions) { // Only add flag support for entities that don't yet have them, and which // are non-config entities. if (!isset($definitions[$entity_type]) && empty($entity_info['configuration'])) { + // We deliberately exclude taxonomy vocabularies from the list of + // supported entity types because they aren't fieldable or directly + // viewable, which makes them impossible to flag. + if ($entity_type === 'taxonomy_vocabulary') { + continue; + } + $definitions[$entity_type] = array( 'title' => $entity_info['label'], 'description' => t('@entity-type entity', array('@entity-type' => $entity_info['label'])), From 3fe0a348391c541d71b68c1b151866f399436d5a Mon Sep 17 00:00:00 2001 From: steveoliver Date: Mon, 11 Feb 2013 21:03:58 +0000 Subject: [PATCH 284/629] Issue #1912208 by steveoliver: Fixed hook_flag_access() missing a mention of hook_flag_access_multiple(). --- flag.api.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/flag.api.php b/flag.api.php index 9feb8f8..1069eb9 100644 --- a/flag.api.php +++ b/flag.api.php @@ -160,7 +160,10 @@ function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permissi } /** - * Allow modules to allow or deny access to flagging. + * Allow modules to allow or deny access to flagging for a single entity. + * + * Called when displaying a single entity view or edit page. For flag access + * checks from within Views, implement hook_flag_access_multiple(). * * @param $flag * The flag object. @@ -175,6 +178,7 @@ function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permissi * Boolean TRUE if the user is allowed to flag/unflag the given entity. * FALSE otherwise. * + * @see hook_flag_access_multiple() * @see flag_flag:access() */ function hook_flag_access($flag, $entity_id, $action, $account) { @@ -182,7 +186,10 @@ function hook_flag_access($flag, $entity_id, $action, $account) { } /** - * Allow modules to allow or deny access to flagging. + * Allow modules to allow or deny access to flagging for multiple entities. + * + * Called when preparing a View or list of multiple flaggable entities. + * For flag access checks for individual entities, see hook_flag_access(). * * @param $flag * The flag object. From 61f80040f017407c6a96d70ba2b14848d9ed19d8 Mon Sep 17 00:00:00 2001 From: alexweber Date: Sat, 16 Feb 2013 20:28:00 +0000 Subject: [PATCH 285/629] Issue #1905004 by alexweber: Fixed flag export to Features not finding module that provides the entity as a dependency. --- includes/flag.features.inc | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/includes/flag.features.inc b/includes/flag.features.inc index a3a1064..4017421 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -17,10 +17,28 @@ function flag_features_export($data, &$export, $module_name = '') { // Ensure the modules that provide the flag are included as dependencies. $modules = flag_features_providing_module(); foreach ($data as $key => $flag) { - // Get the module that provided the flag definition. + $module = ''; if ($flag = flag_load($flag, TRUE)) { - $module = $modules[$flag->entity_type]; - $export['dependencies'][$module] = $module; + // Try to get the module that provides the entity this flag is on. + // First pass: check whether there's a module that implements + // hook_flag_type_info() for this entity. + if (array_key_exists($flag->entity_type, $modules)) { + $module = $modules[$flag->entity_type]; + } + else { + // Second pass: check whether this entity is defined using Entity API + // and therefore has an extra 'module' property in its information. + if ($entity_info = entity_get_info($flag->entity_type)) { + if (isset($entity_info['module'])) { + $module = $entity_info['module']; + } + } + } + + if (!empty($module)) { + $export['dependencies'][$module] = $module; + } + $export['features']['flag'][$flag->name] = $flag->name; } } From 5206b67146f2b429f96a0912819c31adafc491b4 Mon Sep 17 00:00:00 2001 From: hefox Date: Sun, 17 Feb 2013 09:44:51 +0000 Subject: [PATCH 286/629] Issue #1896854 by hefox: Changed flag_flag_access() to use flag->fetch_content() cache. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 6a8debc..a1b45ea 100644 --- a/flag.module +++ b/flag.module @@ -1353,7 +1353,7 @@ function flag_flag_access($flag, $entity_id, $action, $account) { if ($flag->entity_type == 'node') { // For non-existent nodes (such as on the node add form), assume that the // current user is creating the content. - if (empty($entity_id) || !($node = node_load($entity_id))) { + if (empty($entity_id) || !($node = $flag->fetch_entity($entity_id))) { return $flag->access_author == 'others' ? FALSE : NULL; } From a38302c74000dcb82db89281708c1359fc3ed408 Mon Sep 17 00:00:00 2001 From: donatasp Date: Tue, 19 Feb 2013 23:12:24 +0000 Subject: [PATCH 287/629] Issue #1921106 by donatasp: Fixed use of drupal_access_denied() causing 'cannot modify header information' errors. --- includes/flag.pages.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.pages.inc b/includes/flag.pages.inc index 695c2bd..ce4bd5c 100644 --- a/includes/flag.pages.inc +++ b/includes/flag.pages.inc @@ -55,7 +55,7 @@ function flag_page($action, $flag, $entity_id) { drupal_set_message($error, 'error'); } if (isset($errors['access-denied'])) { - drupal_access_denied(); + return MENU_ACCESS_DENIED; } else { drupal_goto(); From f1e5c90fc41d7e6f48d382abf12083b18f99162e Mon Sep 17 00:00:00 2001 From: alexweber Date: Thu, 9 May 2013 07:11:43 +0100 Subject: [PATCH 288/629] Issue #1871426 by alexweber, chrisjlee: Added ability to set display of flag links on specific view modes. --- flag.install | 33 ++++++++++++++++++++++ flag.module | 12 ++++---- flag_bookmark/flag_bookmark.install | 6 ++-- includes/flag.export.inc | 24 ++++++++++++++++ includes/flag/flag_comment.inc | 15 ---------- includes/flag/flag_entity.inc | 35 +++++++++++++++-------- includes/flag/flag_flag.inc | 2 +- includes/flag/flag_node.inc | 24 ---------------- includes/flag/flag_user.inc | 5 ---- tests/flag.test | 44 ++++++++++++++++++++--------- 10 files changed, 122 insertions(+), 78 deletions(-) diff --git a/flag.install b/flag.install index d68671c..7a4cb9f 100644 --- a/flag.install +++ b/flag.install @@ -652,3 +652,36 @@ function flag_update_7305() { '!url' => 'http://drupal.org/node/1724256', )); } + +/** + * Convert flag view modes settings. + */ +function flag_update_7306() { + foreach (flag_get_flags() as $flag) { + // Update show_on_teaser property to use new view mode settings. + if (!empty($flag->show_on_teaser)) { + $flag->show_in_links['teaser'] = TRUE; + unset($flag->show_on_teaser); + } + + // Update show_on_page property to use new view mode settings. + if (!empty($flag->show_on_page)) { + $flag->show_in_links['full'] = TRUE; + unset($flag->show_on_page); + } + + // Update show_on_comment and show_on_entity properties to use new view + // mode settings. Since the old logic was to show on all view modes, do that. + if (!empty($flag->show_on_entity) || !empty($flag->show_on_comment)) { + if ($entity_info = entity_get_info($flag->entity_type)) { + foreach ($entity_info['view modes'] as $view_mode => $value) { + $flag->show_in_links[$view_mode] = TRUE; + } + } + + unset($flag->show_on_entity, $flag->show_on_comment); + } + + $flag->save(); + } +} diff --git a/flag.module b/flag.module index a1b45ea..dbaabda 100644 --- a/flag.module +++ b/flag.module @@ -908,12 +908,12 @@ function flag_contextual_links_view_alter(&$element, $items) { /** * Implements hook_entity_view(). * - * Handles the 'show_on_entity' flag option. + * Handles the 'show_in_links' flag option. * * Note this is broken for taxonomy terms for version of Drupal core < 7.17. */ function flag_entity_view($entity, $type, $view_mode, $langcode) { - $links = flag_link($type, $entity, $view_mode == 'teaser'); + $links = flag_link($type, $entity, $view_mode); if (isset($links)) { $entity->content['links']['flag'] = array( '#theme' => 'links', @@ -930,13 +930,13 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { * The entity type. * @param $entity * The entity - * @param $teaser - * Boolean indicating whether the current view mode is 'teaser'. + * @param $view_mode + * String indicating the current view mode. * * @return * An array of link data, suitable for passing to theme_links(). */ -function flag_link($type, $entity = NULL, $teaser = FALSE) { +function flag_link($type, $entity = NULL, $view_mode) { if (!isset($entity) || !flag_fetch_definition($type)) { return; } @@ -947,7 +947,7 @@ function flag_link($type, $entity = NULL, $teaser = FALSE) { foreach ($flags as $flag) { $entity_id = $flag->get_entity_id($entity); - if (!$flag->uses_hook_link($teaser)) { + if (!$flag->uses_hook_link($view_mode)) { // Flag is not configured to show its link here. continue; } diff --git a/flag_bookmark/flag_bookmark.install b/flag_bookmark/flag_bookmark.install index bce09f2..284784a 100644 --- a/flag_bookmark/flag_bookmark.install +++ b/flag_bookmark/flag_bookmark.install @@ -23,8 +23,10 @@ function flag_bookmark_enable() { $configuration = array( 'name' => 'bookmarks', 'global' => 0, - 'show_on_page' => 1, - 'show_on_teaser' => 1, + 'show_in_links' => array( + 'full' => 1, + 'teaser' => 1, + ), 'show_on_form' => 1, // The following UI labels aren't wrapped in t() because they are written // to the DB in English. They are passed to t() later, thus allowing for diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 1501407..5053c67 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -340,5 +340,29 @@ class FlagUpdate_3 { if (isset($flag->roles)) { $flag->import_roles = $flag->roles; } + + // Update show_on_teaser property to use new view mode settings. + if (!empty($flag->show_on_teaser)) { + $flag->show_in_links['teaser'] = TRUE; + unset($flag->show_on_teaser); + } + + // Update show_on_page property to use new view mode settings. + if (!empty($flag->show_on_page)) { + $flag->show_in_links['full'] = TRUE; + unset($flag->show_on_page); + } + + // Update show_on_comment and show_on_entity properties to use new view + // mode settings. Since the old logic was to show on all view modes, do that. + if (!empty($flag->show_on_entity) || !empty($flag->show_on_comment)) { + if ($entity_info = entity_get_info($flag->entity_type)) { + foreach ($entity_info['view modes'] as $view_mode => $value) { + $flag->show_in_links[$view_mode] = TRUE; + } + } + + unset($flag->show_on_entity, $flag->show_on_comment); + } } } diff --git a/includes/flag/flag_comment.inc b/includes/flag/flag_comment.inc index 19158fd..58b15fc 100644 --- a/includes/flag/flag_comment.inc +++ b/includes/flag/flag_comment.inc @@ -11,11 +11,8 @@ class flag_comment extends flag_entity { function options() { $options = parent::options(); - // Use own display settings in the meanwhile. - unset($options['show_on_entity']); $options += array( 'access_author' => '', - 'show_on_comment' => TRUE, ); return $options; } @@ -39,14 +36,6 @@ class flag_comment extends flag_entity { '#default_value' => $this->access_author, '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), ); - - $form['display']['show_on_comment'] = array( - '#type' => 'checkbox', - '#title' => t('Display link under comment'), - '#default_value' => $this->show_on_comment, - ); - - unset($form['display']['show_on_entity']); } function type_access_multiple($entity_ids, $account) { @@ -80,10 +69,6 @@ class flag_comment extends flag_entity { return $comment->cid; } - function uses_hook_link($teaser) { - return $this->show_on_comment; - } - function get_labels_token_types() { return array_merge(array('comment', 'node'), parent::get_labels_token_types()); } diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index c30efa5..2b0e89f 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -16,8 +16,10 @@ class flag_entity extends flag_flag { $options = parent::options(); $options += array( // Output the flag in the entity links. + // This is empty for now and will get overriden for different + // entities. // @see hook_entity_view(). - 'show_on_entity' => TRUE, + 'show_in_links' => array(), // Add a checkbox for the flag in the entity form. // @see hook_field_attach_form(). 'show_on_form' => FALSE, @@ -43,20 +45,30 @@ class flag_entity extends flag_flag { '#description' => t('Select the bundles that this flag may be used on. Leave blank to allow on all bundles for the entity type.'), '#default_value' => $this->types, ); - // Handlers may want to unset this option if they provide their own more - // specific ways to show links. - $form['display']['show_on_entity'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on entity'), - '#default_value' => isset($this->show_on_entity) ? $this->show_on_entity : TRUE, - '#weight' => 0, + + // Add checkboxes to show flag link on each entity view mode. + $options = array(); + $defaults = array(); + foreach ($entity_info['view modes'] as $name => $view_mode) { + $options[$name] = t('Display on @name view mode', array('@name' => $view_mode['label'])); + $defaults[$name] = !empty($this->show_in_links[$name]) ? $name : 0; + } + + $form['display']['show_in_links'] = array( + '#type' => 'checkboxes', + '#title' => t('Display in entity links'), + '#description' => t('Show the flag link with the other links on the entity.'), + '#options' => $options, + '#default_value' => $defaults, ); + $form['display']['show_on_form'] = array( '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), '#default_value' => $this->show_on_form, '#weight' => 5, ); + // We use FieldAPI to put the flag checkbox on the entity form, so therefore // require the entity to be fielable. Since this is a potential DX // headscratcher for a developer wondering where this option has gone, @@ -141,9 +153,10 @@ class flag_entity extends flag_flag { /** * Returns TRUE if the link should be displayed. */ - function uses_hook_link($teaser) { - if ($this->show_on_entity) { - return TRUE; + function uses_hook_link($view_mode) { + // Check for settings for the given view mode. + if (isset($this->show_in_links[$view_mode])) { + return (bool) $this->show_in_links[$view_mode]; } return FALSE; } diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index edf1c0d..7541fad 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -631,7 +631,7 @@ class flag_flag { * Returns TRUE if the flag is configured to show the flag-link using hook_link. * Derived classes are likely to implement this. */ - function uses_hook_link($teaser) { + function uses_hook_link($view_mode) { return FALSE; } diff --git a/includes/flag/flag_node.inc b/includes/flag/flag_node.inc index db9141c..1f087b8 100644 --- a/includes/flag/flag_node.inc +++ b/includes/flag/flag_node.inc @@ -12,11 +12,7 @@ class flag_node extends flag_entity { function options() { $options = parent::options(); // Use own display settings in the meanwhile. - unset($options['show_on_entity']); $options += array( - 'show_on_page' => TRUE, - 'show_on_teaser' => TRUE, - 'show_on_form' => FALSE, 'i18n' => 0, ); return $options; @@ -54,24 +50,11 @@ class flag_node extends flag_entity { '#weight' => 5, ); - $form['display']['show_on_teaser'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on node teaser'), - '#default_value' => $this->show_on_teaser, - ); - - $form['display']['show_on_page'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on node page'), - '#default_value' => $this->show_on_page, - ); // Override the UI texts for nodes. $form['display']['show_on_form'] = array( '#title' => t('Display checkbox on node edit form'), '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form
for each content type.', array('@content-types-url' => url('admin/structure/types'))), ) + $form['display']['show_on_form']; - - unset($form['display']['show_on_entity']); } function type_access_multiple($entity_ids, $account) { @@ -113,13 +96,6 @@ class flag_node extends flag_entity { return $entity_id; } - function uses_hook_link($teaser) { - if ($teaser && $this->show_on_teaser || !$teaser && $this->show_on_page) { - return TRUE; - } - return FALSE; - } - function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { $entity_id = $this->get_translation_id($entity_id); return parent::flag($action, $entity_id, $account, $skip_permission_check, $flagging); diff --git a/includes/flag/flag_user.inc b/includes/flag/flag_user.inc index b438d13..72dc201 100644 --- a/includes/flag/flag_user.inc +++ b/includes/flag/flag_user.inc @@ -11,9 +11,6 @@ class flag_user extends flag_entity { function options() { $options = parent::options(); - // We supersede, but do not supplant, the regular entity display with an - // option that's formatted in the style of user profiles. - $options['show_on_entity'] = FALSE; $options += array( 'show_on_profile' => TRUE, 'access_uid' => '', @@ -46,8 +43,6 @@ class flag_user extends flag_entity { // Put this above 'show on entity'. '#weight' => -1, ); - // Explain how 'show on entity' is different. - $form['display']['show_on_entity']['#description'] = t('Show the link in the same format as on other entities.'); } function form_input($form_values) { diff --git a/tests/flag.test b/tests/flag.test index 31c0f4a..4f99ed0 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -72,8 +72,10 @@ class FlagFlaggingCRUDTestCase extends FlagTestCaseBase { 'show_on_form' => 0, 'access_author' => '', 'show_contextual_link' => 0, - 'show_on_page' => 1, - 'show_on_teaser' => 1, + 'show_in_links' => array( + 'full' => 1, + 'teaser' => 1, + ), 'i18n' => 0, 'api_version' => 3, ); @@ -250,15 +252,19 @@ class FlagAdminTestCase extends FlagTestCaseBase { 'roles[unflag][2]' => TRUE, 'types[article]' => FALSE, 'types[page]' => TRUE, - 'show_on_teaser' => FALSE, - 'show_on_page' => FALSE, + 'show_in_links[full]' => FALSE, + 'show_in_links[teaser]' => FALSE, + 'show_in_links[rss]' => FALSE, + 'show_in_links[search_index]' => FALSE, + 'show_in_links[search_result]' => FALSE, 'show_on_form' => FALSE, 'link_type' => 'toggle', ); $saved = $edit; $saved['roles'] = array('flag' => array(2), 'unflag' => array(2)); $saved['types'] = array('page'); - unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); + $saved['show_in_links'] = array('full' => 0, 'teaser' => 0, 'rss' => 0, 'search_index' => 0, 'search_result' => 0); + unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]'], $saved['show_in_links[full]'], $saved['show_in_links[teaser]'], $saved['show_in_links[rss]'], $saved['show_in_links[search_index]'], $saved['show_in_links[search_result]']); $this->drupalPost(FLAG_ADMIN_PATH . '/add/node', $edit, t('Save flag')); @@ -300,15 +306,19 @@ class FlagAdminTestCase extends FlagTestCaseBase { 'roles[unflag][2]' => TRUE, 'types[article]' => TRUE, 'types[page]' => FALSE, - 'show_on_teaser' => TRUE, - 'show_on_page' => TRUE, + 'show_in_links[full]' => TRUE, + 'show_in_links[teaser]' => TRUE, + 'show_in_links[rss]' => FALSE, + 'show_in_links[search_index]' => FALSE, + 'show_in_links[search_result]' => FALSE, 'show_on_form' => TRUE, 'link_type' => 'normal', ); $saved = $edit; $saved['roles'] = array('flag' => array(2), 'unflag' => array(2)); $saved['types'] = array('article'); - unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]']); + $saved['show_in_links'] = array('full' => TRUE, 'teaser' => TRUE, 'rss' => 0, 'search_index' => 0, 'search_result' => 0); + unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]'], $saved['show_in_links[full]'], $saved['show_in_links[teaser]'], $saved['show_in_links[rss]'], $saved['show_in_links[search_index]'], $saved['show_in_links[search_result]']); $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name, $edit, t('Save flag')); @@ -400,8 +410,10 @@ class FlagAccessFormTestCase extends FlagTestCaseBase { 'show_on_form' => 1, 'access_author' => '', 'show_contextual_link' => 0, - 'show_on_page' => 1, - 'show_on_teaser' => 1, + 'show_in_links' => array( + 'full' => 1, + 'teaser' => 1, + ), 'i18n' => 0, 'api_version' => 3, ); @@ -489,8 +501,10 @@ class FlagAccessLinkTestCase extends FlagTestCaseBase { 'show_on_form' => 0, 'access_author' => '', 'show_contextual_link' => 0, - 'show_on_page' => 1, - 'show_on_teaser' => 1, + 'show_in_links' => array( + 'full' => 1, + 'teaser' => 1, + ), 'i18n' => 0, 'api_version' => 3, ); @@ -612,8 +626,10 @@ class FlagLinkTypeConfirmTestCase extends DrupalWebTestCase { 'show_on_form' => 0, 'access_author' => '', 'show_contextual_link' => 0, - 'show_on_page' => 1, - 'show_on_teaser' => 1, + 'show_in_links' => array( + 'full' => 1, + 'teaser' => 1, + ), 'i18n' => 0, 'api_version' => 3, ); From 0a7a43b144c7e2213349415c7433ccfcf11a2530 Mon Sep 17 00:00:00 2001 From: joelstein Date: Thu, 9 May 2013 07:49:59 +0100 Subject: [PATCH 289/629] Issue #1439168 by joelstein: Fixed flag trim removing flaggings for the anonymous user. --- flag.module | 2 ++ flag.rules.inc | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/flag.module b/flag.module index dbaabda..c77c15e 100644 --- a/flag.module +++ b/flag.module @@ -2072,6 +2072,8 @@ function flag_trim_flag($flag, $account, $cutoff_size) { ->fields('fc') ->condition('fid', $flag->fid) ->condition(db_or()->condition('uid', $account->uid)->condition('uid', 0)) + // Account for session ID (in the case of anonymous users). + ->condition('sid', flag_get_sid($account->uid)) ->orderBy('timestamp', 'DESC') ->execute(); $i = 1; diff --git a/flag.rules.inc b/flag.rules.inc index 9fdfd7b..8069b29 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -313,6 +313,12 @@ function flag_rules_action_unflag($flag, $entity, $flagging_user, $permissions_c * Base action implementation: Trim flag. */ function flag_rules_action_trim($flag, $flagging_user, $cutoff_size) { + // For some reason, when this action fires in response to a flagging event, + // as an anonymous user, then the $flagging_user is sent through as FALSE. + // Not sure why. This workaround fixes the problem in this specific case. + if ($flagging_user === FALSE) { + $flagging_user = $GLOBALS['user']; + } flag_trim_flag($flag, $flagging_user, $cutoff_size); } From acbf0289786a5dd0991015a0320debdf78e7005c Mon Sep 17 00:00:00 2001 From: zarabadoo Date: Thu, 9 May 2013 08:08:13 +0100 Subject: [PATCH 290/629] Issue #1793572 by Zarabadoo, socketwench: Changed the creation of CSS class variables from being handled in theme preprocessor to theme processor. --- flag.module | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/flag.module b/flag.module index c77c15e..0b32f83 100644 --- a/flag.module +++ b/flag.module @@ -1601,10 +1601,6 @@ function template_preprocess_flag(&$variables) { $variables['message_text'] = ''; } - $variables['flag_wrapper_classes'] = implode(' ', $variables['flag_wrapper_classes_array']); - $variables['flag_classes'] = implode(' ', $variables['flag_classes_array']); - $variables['message_classes'] = join(' ', $variables['message_classes_array']); - // Backward compatibility: The following section preserves some deprecated // variables either to make old flag.tpl.php files continue to work, or to // prevent PHP from generating E_NOTICEs there. @todo: Remove these sometime. @@ -1612,6 +1608,20 @@ function template_preprocess_flag(&$variables) { $variables['last_action'] = $variables['status']; } +/** + * Theme processor for flag.tpl.php. + * + * @param array &$variables + * An array of variables for the template. See 'flag.tpl.php' for their + * documentation. + */ +function template_process_flag(&$variables) { + // Convert class arrays to strings. + $variables['flag_wrapper_classes'] = implode(' ', $variables['flag_wrapper_classes_array']); + $variables['flag_classes'] = implode(' ', $variables['flag_classes_array']); + $variables['message_classes'] = implode(' ', $variables['message_classes_array']); +} + /** * Return an array of flag names keyed by fid. */ From 1363f2eb36cbce513b4e5dbe6598da3faceabd67 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 07:28:58 +0100 Subject: [PATCH 291/629] Issue #1892930 by joachim, chrisjlee: Added placement of flag links as pseudofields. --- flag.module | 27 +++++++++++++++++++++++++++ includes/flag/flag_entity.inc | 13 +++++++++++++ includes/flag/flag_flag.inc | 26 +++++++++++++++++++++----- theme/flag.tpl.php | 8 ++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/flag.module b/flag.module index 0b32f83..314878f 100644 --- a/flag.module +++ b/flag.module @@ -601,6 +601,19 @@ function flag_field_extra_fields() { 'weight' => 10 ); } + + if ($flag->show_as_field) { + $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $name] = array( + // It would be nicer to use % as the placeholder, but the label is + // run through check_plain() by field_ui_display_overview_form() + // (arguably incorrectly; see http://drupal.org/node/1991292). + 'label' => t('Flag: @title', array( + '@title' => $flag->title, + )), + 'description' => t('Individual flag link'), + 'weight' => 10, + ); + } } } @@ -921,6 +934,18 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { '#attributes' => array('class' => array('links', 'inline')), ); } + + // Get all possible flags for this entity type. + $flags = flag_get_flags($type); + foreach ($flags as $flag) { + $entity_id = $flag->get_entity_id($entity); + if ($flag->show_as_field) { + $entity->content['flag-' . $flag->name] = array( + '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, FALSE, array(), array('needs_wrapping_element' => TRUE)), + ); + } + } + } /** @@ -1463,6 +1488,7 @@ function flag_theme() { 'action' => NULL, 'entity_id' => NULL, 'after_flagging' => FALSE, + 'needs_wrapping_element' => FALSE, 'errors' => array(), ), 'template' => 'flag', @@ -1512,6 +1538,7 @@ function flag_theme() { * - $entity_id * - $after_flagging * - $errors + * - $needs_wrapping_element * * See 'flag.tpl.php' for their documentation. */ diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 2b0e89f..61d37fe 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -20,6 +20,8 @@ class flag_entity extends flag_flag { // entities. // @see hook_entity_view(). 'show_in_links' => array(), + // Output the flag as individual pseudofields. + 'show_as_field' => FALSE, // Add a checkbox for the flag in the entity form. // @see hook_field_attach_form(). 'show_on_form' => FALSE, @@ -62,6 +64,17 @@ class flag_entity extends flag_flag { '#default_value' => $defaults, ); + $form['display']['show_as_field'] = array( + '#type' => 'checkbox', + '#title' => t('Display link as field'), + '#description' => t('Show the flag link as a pseudofield, which can be ordered among other entity elements in the "Manage display" settings for the entity type.'), + '#default_value' => isset($this->show_as_field) ? $this->show_as_field : TRUE, + ); + if (empty($entity_info['fieldable'])) { + $form['display']['show_as_field']['#disabled'] = TRUE; + $form['display']['show_as_field']['#description'] = t("This entity type is not fieldable."); + } + $form['display']['show_on_form'] = array( '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 7541fad..b8b09a3 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1430,12 +1430,28 @@ class flag_flag { } /** - * Renders a flag/unflag link. This is a wrapper around theme('flag') that - * channels the call to the right template file. + * Renders a flag/unflag link. * - * For parameters documentation, see flag.tpl.php. + * This is a wrapper around theme('flag') that channels the call to the right + * template file. + * + * @param $action + * The action the link is about to carry out, either "flag" or "unflag". + * @param $entity_id + * The ID of the object to flag. + * @param $after_flagging = FALSE + * (Optional) Set to TRUE if this flag link is being displayed as the result + * of a flagging action. + * @param $errors = array() + * An array of error messages. + * @param $variables = array() + * An array of further variables to pass to theme('flag'). For parameters + * documentation, see flag.tpl.php + * + * @return + * The HTML for the flag link. */ - function theme($action, $entity_id, $after_flagging = FALSE, $errors = array()) { + function theme($action, $entity_id, $after_flagging = FALSE, $errors = array(), $variables = array()) { static $js_added = array(); global $user; @@ -1478,7 +1494,7 @@ class flag_flag { 'entity_id' => $entity_id, 'after_flagging' => $after_flagging, 'errors' => $errors, - )); + ) + $variables); } /** diff --git a/theme/flag.tpl.php b/theme/flag.tpl.php index df6bfdc..60a3113 100644 --- a/theme/flag.tpl.php +++ b/theme/flag.tpl.php @@ -27,6 +27,8 @@ * flagged. If displaying to the user immediately after flagging, this value * will be boolean TRUE. This is usually used in conjunction with immedate * JavaScript-based toggling of flags. + * - $needs_wrapping_element: Determines whether the flag displays a wrapping + * HTML DIV element. * * Template suggestions available, listed from the most specific template to * the least. Drupal will use the most specific template it finds: @@ -37,6 +39,9 @@ * advanced theming you may have to remove all the whitespace. */ ?> + +
+   @@ -49,3 +54,6 @@ + +
+ From 4af08d7ac427f57d3acc4af5484be28ac2c5cbff Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 07:37:00 +0100 Subject: [PATCH 292/629] Issue #1992790 by joachim: Fixed flag_create_link() docblock recommending a function call in a template. --- flag.module | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/flag.module b/flag.module index 314878f..55f3a71 100644 --- a/flag.module +++ b/flag.module @@ -2072,14 +2072,18 @@ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { * * You should call this function from your template when you want to put the * link on the page yourself. For example, you could call this function from - * your 'node.tpl.php': - * - * nid); ?> + * your theme preprocessor for node.tpl.php: + * @code + * $variables['my_flag_link'] = flag_create_link('bookmarks', $node->nid); + * @endcode * * @param $flag_name * The "machine readable" name of the flag; e.g. 'bookmarks'. * @param $entity_id * The entity ID to check for flagging, for example a node ID. + * + * @return + * The HTML for the themed flag link. */ function flag_create_link($flag_name, $entity_id) { $flag = flag_get_flag($flag_name); From 4bcd553804f46a7bb55d12c59101cf2e4d940741 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 07:43:10 +0100 Subject: [PATCH 293/629] Issue #1992794 by joachim: Removed backward compatibility variables from template_preprocess_flag(). --- flag.module | 6 ------ 1 file changed, 6 deletions(-) diff --git a/flag.module b/flag.module index 55f3a71..dd7a243 100644 --- a/flag.module +++ b/flag.module @@ -1627,12 +1627,6 @@ function template_preprocess_flag(&$variables) { else { $variables['message_text'] = ''; } - - // Backward compatibility: The following section preserves some deprecated - // variables either to make old flag.tpl.php files continue to work, or to - // prevent PHP from generating E_NOTICEs there. @todo: Remove these sometime. - $variables['setup'] = FALSE; - $variables['last_action'] = $variables['status']; } /** From 537feb05681680242301a8c07dfff2645ff0f119 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 07:51:18 +0100 Subject: [PATCH 294/629] Issue #1991336 by joachim: Removed optional parameters from $flag->theme(), as these can be passed into the $variables array. --- flag.module | 2 +- includes/flag.pages.inc | 5 ++++- includes/flag/flag_flag.inc | 18 ++++++++---------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/flag.module b/flag.module index dd7a243..0a2ecdd 100644 --- a/flag.module +++ b/flag.module @@ -941,7 +941,7 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { $entity_id = $flag->get_entity_id($entity); if ($flag->show_as_field) { $entity->content['flag-' . $flag->name] = array( - '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, FALSE, array(), array('needs_wrapping_element' => TRUE)), + '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array('needs_wrapping_element' => TRUE)), ); } } diff --git a/includes/flag.pages.inc b/includes/flag.pages.inc index ce4bd5c..cfb91ba 100644 --- a/includes/flag.pages.inc +++ b/includes/flag.pages.inc @@ -149,7 +149,10 @@ function flag_build_javascript_info($flag, $entity_id) { $errors = $flag->get_errors(); $info = array( 'status' => TRUE, - 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, TRUE, $errors), + 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array( + 'after_flagging' => TRUE, + 'errors' => $errors, + )), // Further information for the benefit of custom JavaScript event handlers: 'flagSuccess' => !$errors, 'contentId' => $entity_id, diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index b8b09a3..0c466a4 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1439,22 +1439,22 @@ class flag_flag { * The action the link is about to carry out, either "flag" or "unflag". * @param $entity_id * The ID of the object to flag. - * @param $after_flagging = FALSE - * (Optional) Set to TRUE if this flag link is being displayed as the result - * of a flagging action. - * @param $errors = array() - * An array of error messages. * @param $variables = array() - * An array of further variables to pass to theme('flag'). For parameters - * documentation, see flag.tpl.php + * An array of further variables to pass to theme('flag'). For the full list + * of parameters, see flag.tpl.php. Of particular interest: + * - after_flagging: Set to TRUE if this flag link is being displayed as the result + * of a flagging action. + * - errors: An array of error messages. * * @return * The HTML for the flag link. */ - function theme($action, $entity_id, $after_flagging = FALSE, $errors = array(), $variables = array()) { + function theme($action, $entity_id, $variables = array()) { static $js_added = array(); global $user; + $after_flagging = !empty($variables['after_flagging']); + // If the flagging user is anonymous, set a boolean for the benefit of // JavaScript code. Currently, only our "anti-crawlers" mechanism uses it. if ($user->uid == 0 && !isset($js_added['anonymous'])) { @@ -1492,8 +1492,6 @@ class flag_flag { 'flag' => $this, 'action' => $action, 'entity_id' => $entity_id, - 'after_flagging' => $after_flagging, - 'errors' => $errors, ) + $variables); } From 21f2c25ab7909ceab201c8759b5b01143d2ea827 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 08:10:02 +0100 Subject: [PATCH 295/629] Issue #1784402 by joachim: Changed handling of node forms to be done generically in hook_field_attach_form() instead of in hook_form_alter(). --- flag.module | 119 +++++++++++++--------------------------------------- 1 file changed, 29 insertions(+), 90 deletions(-) diff --git a/flag.module b/flag.module index 0a2ecdd..0d054b5 100644 --- a/flag.module +++ b/flag.module @@ -669,11 +669,6 @@ function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { * @see flag_field_attach_submit(). */ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) { - // Nodes have their own special form handling: see flag_form_alter(). - if ($entity_type == 'node') { - return; - } - list($id) = entity_extract_ids($entity_type, $entity); // Some modules are being stupid here. Commerce! if (empty($id)) { @@ -692,13 +687,25 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la } // Get the flag status. - // We don't have per-bundle defaults on general entities yet. - $flag_status = $id ? $flag->is_flagged($id) : FALSE; + if (isset($id)) { + $flag_status = $flag->is_flagged($id); + } + else { + // We don't have per-bundle defaults on general entities yet: default + // status is just unflagged. + $flag_status = FALSE; + // Apply the per-bundle defaults for nodes. + if ($entity_type == 'node') { + $flag_status = variable_get('flag_' . $flag->name . '_default_' . $form['type']['#value'], 0); + } + } // If the flag is not global and the user doesn't have access, skip it. // Global flags have their value set even if the user doesn't have access // to it, similar to the way "published" and "promote" keep the default // values even if the user doesn't have "administer nodes" permission. + // Furthermore, a global flag is set to its default value on new nodes + // even if the user creating the node doesn't have access to the flag. global $user; $access = $flag->access($id, $flag_status ? 'unflag' : 'flag'); if (!$access && !$flag->global) { @@ -711,6 +718,8 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la '#description' => $flag->get_label('flag_long', $id), '#default_value' => $flag_status, '#return_value' => 1, + // Used by our drupalSetSummary() on vertical tabs. + '#attributes' => array('title' => $flag->get_title()), ); // If the user does not have access to the flag, set as a value. @@ -736,6 +745,19 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la '#title' => t('Flags'), '#collapsible' => TRUE, ); + + if ($entity_type == 'node') { + // Turn the fieldset into a vertical tab. + $form['flag'] += array( + '#group' => 'additional_settings', + '#attributes' => array('class' => array('flag-fieldset')), + '#attached' => array( + 'js' => array( + 'vertical-tabs' => drupal_get_path('module', 'flag') . '/theme/flag-admin.js', + ), + ), + ); + } } } @@ -790,89 +812,6 @@ function flag_field_attach_save($entity_type, $entity) { } } -/** - * Implements hook_form_alter(). - */ -function flag_form_alter(&$form, &$form_state, $form_id) { - // Alter node forms. - if (isset($form['type']) && isset($form['#node']) && ($form_id == $form['type']['#value'] . '_node_form')) { - global $user; - $nid = !empty($form['nid']['#value']) ? $form['nid']['#value'] : NULL; - $flags = flag_get_flags('node', $form['type']['#value']); - - // Filter out flags which need to be included on the node form. - $flags_in_form = 0; - $flags_visible = 0; - foreach ($flags as $name => $flag) { - if (!$flag->show_on_form) { - continue; - } - - $flag_status_default = variable_get('flag_' . $flag->name . '_default_' . $form['type']['#value'], 0); - $flag_status = $nid ? $flag->is_flagged($nid) : $flag_status_default; - - // If the flag is not global and the user doesn't have access, skip it. - // Global flags have their value set even if the user doesn't have access - // to it, similar to the way "published" and "promote" keep the default - // values even if the user doesn't have "administer nodes" permission. - // Furthermore, a global flag is set to its default value on new nodes - // even if the user creating the node doesn't have access to the flag. - $access = $flag->access($nid, $flag_status ? 'unflag' : 'flag', $user); - if (!$access && !$flag->global) { - continue; - } - - if (!$nid) { - // To be able to process node tokens for a node which hasn't yet been - // saved (e.g., on node/add/article), we "save" it to the flag's cache - // under a pseudo ID. - $flag->remember_entity('new', $form['#node']); - } - - // Add the flag checkbox if displaying on the form. - $form['flag'][$flag->name] = array( - '#type' => 'checkbox', - '#title' => $flag->get_label('flag_short', $nid ? $nid : 'new'), - '#description' => $flag->get_label('flag_long', $nid ? $nid : 'new'), - '#default_value' => $flag_status, - '#return_value' => 1, - '#attributes' => array('title' => $flag->get_title()), // Used by our drupalSetSummary(). - ); - // If the user does not have access to the flag, set as a value. - if (!$access) { - $form['flag'][$flag->name]['#type'] = 'value'; - $form['flag'][$flag->name]['#value'] = $flag_status; - } - else { - $flags_visible++; - } - $flags_in_form++; - } - if ($flags_in_form) { - $form['flag'] += array( - '#weight' => 1, - '#tree' => TRUE, - ); - } - if ($flags_visible) { - $form['flag'] += array( - '#type' => 'fieldset', - '#title' => t('Flags'), - '#collapsible' => TRUE, - // Vertical tabs support: - '#group' => 'additional_settings', - '#attributes' => array('class' => array('flag-fieldset')), - '#attached' => array( - 'js' => array( - 'vertical-tabs' => drupal_get_path('module', 'flag') . '/theme/flag-admin.js', - ), - ), - ); - } - - } -} - /* * Implements hook_contextual_links_view_alter(). */ From dd81309210d1c177ddb50a47b9bab2fdf3ab6c3e Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 08:14:54 +0100 Subject: [PATCH 296/629] by joachim: Fixed missing flag access check on flag pseudofield. --- flag.module | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flag.module b/flag.module index 0d054b5..146e8ed 100644 --- a/flag.module +++ b/flag.module @@ -879,6 +879,12 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { foreach ($flags as $flag) { $entity_id = $flag->get_entity_id($entity); if ($flag->show_as_field) { + if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { + // User has no permission to use this flag or flag does not apply to this + // entity. The link is not skipped if the user has "flag" access but + // not "unflag" access (this way the unflag denied message is shown). + continue; + } $entity->content['flag-' . $flag->name] = array( '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array('needs_wrapping_element' => TRUE)), ); From b726861c1ab186a138748911b23b1657d13734fc Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 09:04:18 +0100 Subject: [PATCH 297/629] Issue #1892372 by joachim: Fixed node and comment preview showing flags not assigned to their particular bundle. --- flag.module | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/flag.module b/flag.module index 146e8ed..d3f7d7b 100644 --- a/flag.module +++ b/flag.module @@ -698,6 +698,12 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la if ($entity_type == 'node') { $flag_status = variable_get('flag_' . $flag->name . '_default_' . $form['type']['#value'], 0); } + + // For a new, unsaved entity, make a dummy entity ID so that the flag + // handler can remember the entity. This allows access to the flag to be + // correctly handled in node and comment preview. + $id = 'new'; + $flag->remember_entity($id, $entity); } // If the flag is not global and the user doesn't have access, skip it. @@ -878,6 +884,14 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { $flags = flag_get_flags($type); foreach ($flags as $flag) { $entity_id = $flag->get_entity_id($entity); + // For a new, unsaved entity, make a dummy entity ID so that the flag + // handler can remember the entity. This allows access to the flag to be + // correctly handled in node and comment preview. + if (is_null($entity_id)) { + $entity_id = 'new'; + } + $flag->remember_entity($entity_id, $entity); + if ($flag->show_as_field) { if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this @@ -916,6 +930,13 @@ function flag_link($type, $entity = NULL, $view_mode) { foreach ($flags as $flag) { $entity_id = $flag->get_entity_id($entity); + // For a new, unsaved entity, make a dummy entity ID so that the flag + // handler can remember the entity. This allows access to the flag to be + // correctly handled in node and comment preview. + if (is_null($entity_id)) { + $entity_id = 'new'; + } + $flag->remember_entity($entity_id, $entity); if (!$flag->uses_hook_link($view_mode)) { // Flag is not configured to show its link here. From 3339f37668a5a26309adfc716009de13aa33b9ca Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 09:31:53 +0100 Subject: [PATCH 298/629] Issue #1992810 by joachim: Removed flag_link() and refactored entity link creation in hook_entity_view(). --- flag.module | 95 +++++++++++++++++------------------------------------ 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/flag.module b/flag.module index d3f7d7b..ce05ac8 100644 --- a/flag.module +++ b/flag.module @@ -866,69 +866,21 @@ function flag_contextual_links_view_alter(&$element, $items) { /** * Implements hook_entity_view(). * - * Handles the 'show_in_links' flag option. + * Handles the 'show_in_links' and 'show_as_field' flag options. * * Note this is broken for taxonomy terms for version of Drupal core < 7.17. */ function flag_entity_view($entity, $type, $view_mode, $langcode) { - $links = flag_link($type, $entity, $view_mode); - if (isset($links)) { - $entity->content['links']['flag'] = array( - '#theme' => 'links', - '#links' => $links, - '#attributes' => array('class' => array('links', 'inline')), - ); - } - // Get all possible flags for this entity type. $flags = flag_get_flags($type); foreach ($flags as $flag) { - $entity_id = $flag->get_entity_id($entity); - // For a new, unsaved entity, make a dummy entity ID so that the flag - // handler can remember the entity. This allows access to the flag to be - // correctly handled in node and comment preview. - if (is_null($entity_id)) { - $entity_id = 'new'; - } - $flag->remember_entity($entity_id, $entity); - - if ($flag->show_as_field) { - if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { - // User has no permission to use this flag or flag does not apply to this - // entity. The link is not skipped if the user has "flag" access but - // not "unflag" access (this way the unflag denied message is shown). - continue; - } - $entity->content['flag-' . $flag->name] = array( - '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array('needs_wrapping_element' => TRUE)), - ); + // Check if the flag outputs on entity view. + if (!($flag->show_as_field || $flag->uses_hook_link($view_mode))) { + // Flag is not configured to output on entity view, so skip it to save on + // calls to access checks. + continue; } - } -} - -/** - * Creates an array of links for all the flags of given entity. - * - * @param $type - * The entity type. - * @param $entity - * The entity - * @param $view_mode - * String indicating the current view mode. - * - * @return - * An array of link data, suitable for passing to theme_links(). - */ -function flag_link($type, $entity = NULL, $view_mode) { - if (!isset($entity) || !flag_fetch_definition($type)) { - return; - } - - // Get all possible flags for this entity type. - $flags = flag_get_flags($type); - - foreach ($flags as $flag) { $entity_id = $flag->get_entity_id($entity); // For a new, unsaved entity, make a dummy entity ID so that the flag // handler can remember the entity. This allows access to the flag to be @@ -938,10 +890,6 @@ function flag_link($type, $entity = NULL, $view_mode) { } $flag->remember_entity($entity_id, $entity); - if (!$flag->uses_hook_link($view_mode)) { - // Flag is not configured to show its link here. - continue; - } if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { // User has no permission to use this flag or flag does not apply to this // entity. The link is not skipped if the user has "flag" access but @@ -949,16 +897,33 @@ function flag_link($type, $entity = NULL, $view_mode) { continue; } - // The flag links are actually fully rendered theme functions. - // The HTML attribute is set to TRUE to allow whatever the themer desires. - $links['flag-' . $flag->name] = array( - 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), - 'html' => TRUE, - ); + // We're good to go. Output the flag in the appropriate manner(s). + + // The old-style entity links output. + if ($flag->uses_hook_link($view_mode)) { + // The flag links are actually fully rendered theme functions. + // The HTML attribute is set to TRUE to allow whatever the themer desires. + $links['flag-' . $flag->name] = array( + 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), + 'html' => TRUE, + ); + } + + // The pseudofield output. + if ($flag->show_as_field) { + $entity->content['flag-' . $flag->name] = array( + '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array('needs_wrapping_element' => TRUE)), + ); + } } + // If any links were made, add them to the entity's links array. if (isset($links)) { - return $links; + $entity->content['links']['flag'] = array( + '#theme' => 'links', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } } From b1dc57d62385aad9e70710e1c1cb5a58240ffb25 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 09:40:41 +0100 Subject: [PATCH 299/629] Issue #843308 by mooffie, walker2238, joachim: Added support for multiple instances of the same flag on the same page. --- theme/flag.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/theme/flag.js b/theme/flag.js index 1b3bb38..3f1aedc 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -78,6 +78,19 @@ Drupal.flagLink = function(context) { if (!data.preventDefault) { // A handler may cancel updating the link. data.link = updateLink(element, data.newLink); } + + // Find all the link wrappers on the page for this flag, but exclude + // the triggering element because Flag's own javascript updates it. + var $wrappers = $('.flag-wrapper.flag-' + data.flagName.flagNameToCSS() + '-' + data.contentId).not(data.link); + var $newLink = $(data.newLink); + + // Hide message, because we want the message to be shown on the triggering element alone. + $('.flag-message', $newLink).hide(); + + // Finally, update the page. + $wrappers = $newLink.replaceAll($wrappers); + Drupal.attachBehaviors($wrappers.parent()); + $.event.trigger('flagGlobalAfterLinkUpdate', [data]); }, error: function (xmlhttp) { From 25b8f56e5529ed6cbbeeeaa08dc05c5a6108bb6c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 12 May 2013 13:01:55 +0100 Subject: [PATCH 300/629] Issue #1992814 by joachim: Renamed uses_hook_link() to shows_in_entity_links(). --- flag.module | 4 ++-- includes/flag/flag_entity.inc | 4 ++-- includes/flag/flag_flag.inc | 12 ++++++++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/flag.module b/flag.module index ce05ac8..c51648e 100644 --- a/flag.module +++ b/flag.module @@ -875,7 +875,7 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { $flags = flag_get_flags($type); foreach ($flags as $flag) { // Check if the flag outputs on entity view. - if (!($flag->show_as_field || $flag->uses_hook_link($view_mode))) { + if (!($flag->show_as_field || $flag->shows_in_entity_links($view_mode))) { // Flag is not configured to output on entity view, so skip it to save on // calls to access checks. continue; @@ -900,7 +900,7 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { // We're good to go. Output the flag in the appropriate manner(s). // The old-style entity links output. - if ($flag->uses_hook_link($view_mode)) { + if ($flag->shows_in_entity_links($view_mode)) { // The flag links are actually fully rendered theme functions. // The HTML attribute is set to TRUE to allow whatever the themer desires. $links['flag-' . $flag->name] = array( diff --git a/includes/flag/flag_entity.inc b/includes/flag/flag_entity.inc index 61d37fe..5114213 100644 --- a/includes/flag/flag_entity.inc +++ b/includes/flag/flag_entity.inc @@ -164,9 +164,9 @@ class flag_entity extends flag_flag { } /** - * Returns TRUE if the link should be displayed. + * Determine whether the flag should show a flag link in entity links. */ - function uses_hook_link($view_mode) { + function shows_in_entity_links($view_mode) { // Check for settings for the given view mode. if (isset($this->show_in_links[$view_mode])) { return (bool) $this->show_in_links[$view_mode]; diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 0c466a4..14368a8 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -628,10 +628,18 @@ class flag_flag { } /** - * Returns TRUE if the flag is configured to show the flag-link using hook_link. + * Determine whether the flag should show a flag link in entity links. + * * Derived classes are likely to implement this. + * + * @param $view_mode + * The view mode of the entity being displayed. + * + * @return + * A boolean indicating whether the flag link is to be shown in entity + * links. */ - function uses_hook_link($view_mode) { + function shows_in_entity_links($view_mode) { return FALSE; } From fc8cc6b5b643b1725c4b5a6e01474109717c7696 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 13 May 2013 22:06:37 +0100 Subject: [PATCH 301/629] Issue #1965040 by shawn_smiley: Changed handling of return values from hook_flag_user_access() to allow all implementing modules to be considered. --- flag.api.php | 9 +- includes/flag/flag_flag.inc | 18 ++- tests/flag.test | 157 +++++++++++++++++++++ tests/flagaccesstest/flagaccesstest.info | 6 + tests/flagaccesstest/flagaccesstest.module | 26 ++++ 5 files changed, 208 insertions(+), 8 deletions(-) create mode 100644 tests/flagaccesstest/flagaccesstest.info create mode 100644 tests/flagaccesstest/flagaccesstest.module diff --git a/flag.api.php b/flag.api.php index 1069eb9..08b1749 100644 --- a/flag.api.php +++ b/flag.api.php @@ -175,8 +175,13 @@ function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permissi * The user on whose behalf to test the flagging action. * * @return - * Boolean TRUE if the user is allowed to flag/unflag the given entity. - * FALSE otherwise. + * One of the following values: + * - TRUE: User has access to the flag. + * - FALSE: User does not have access to the flag. + * - NULL: This module does not perform checks on this flag/action. + * + * NOTE: Any module that returns FALSE will prevent the user from + * being able to use the flag. * * @see hook_flag_access_multiple() * @see flag_flag:access() diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 14368a8..f491b2c 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -490,12 +490,18 @@ class flag_flag { } // Allow modules to disallow (or allow) access to flagging. - $access_array = module_invoke_all('flag_access', $this, $entity_id, $action, $account); - - foreach ($access_array as $set_access) { - if (isset($set_access)) { - $access = $set_access; - } + // We grant access to the flag if both of the following conditions are met: + // - No modules say to deny access. + // - At least one module says to grant access. + // If no module specified either allow or deny, we fall back to the + // default access check above. + $module_access = module_invoke_all('flag_access', $this, $entity_id, $action, $account); + if (in_array(FALSE, $module_access, TRUE)) { + $access = FALSE; + } + elseif (in_array(TRUE, $module_access, TRUE)) { + // WARNING: This allows modules to bypass the default access check! + $access = TRUE; } return $access; diff --git a/tests/flag.test b/tests/flag.test index 4f99ed0..760fd32 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -703,3 +703,160 @@ class FlagLinkTypeConfirmTestCase extends DrupalWebTestCase { } } + +/** + * Verifies the implementation of hook_flag_access(). + */ +class FlagHookFlagAccessTestCase extends FlagTestCaseBase { + + /** + * Implements getInfo(). + */ + public static function getInfo() { + return array( + 'name' => t('Flag hook_flag_access() tests'), + 'description' => t('Checks the ability of modules to use hook_flag_access().'), + 'group' => t('Flag'), + ); + } + + /** + * Implements setUp(). + */ + function setUp() { + parent::setUp('flag'); + + $success = module_enable(array('flagaccesstest'), FALSE); + + // Create a test flag on article nodes. + $flag_data = array( + 'entity_type' => 'node', + 'name' => 'test_flag', + 'title' => 'Test Flag', + 'global' => 0, + 'types' => array( + 0 => 'article', + ), + 'flag_short' => 'Flag this item', + 'flag_long' => '', + 'flag_message' => '', + 'unflag_short' => 'Unflag this item', + 'unflag_long' => '', + 'unflag_message' => '', + 'unflag_denied_text' => 'You may not unflag this item', + // Use the normal link type as it involves no intermediary page loads. + 'link_type' => 'normal', + 'weight' => 0, + 'show_on_form' => 0, + 'access_author' => '', + 'show_contextual_link' => 0, + 'show_in_links' => array( + 'full' => 1, + 'teaser' => 1, + ), + 'i18n' => 0, + 'api_version' => 3, + ); + $flag = $this->createFlag($flag_data); + + // Create an article node that various users will try to flag. + $title = $this->randomName(8); + $node = array( + 'title' => $title, + 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), + 'uid' => 1, + 'type' => 'article', + 'is_new' => TRUE, + ); + $node = node_submit((object) $node); + node_save($node); + $this->nid = $node->nid; + } + + /** + * Verifies that the user sees the flag if a module returns NULL (Ignore). + */ + function testFlagAccessIgnore() { + variable_set('FlagHookFlagAccessTestCaseMode', 'ignore'); + $flag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); + $this->drupalLogin($flag_user); + + // Look at our node. + $this->drupalGet('node/' . $this->nid); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); + + // Click the link to flag the node. + $this->clickLink(t('Flag this item')); + + $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); + + // Click the link to unflag the node. + $this->clickLink(t('Unflag this item')); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); + } + + /** + * Verifies that the user sees the flag if a module returns TRUE (Allow). + */ + function testFlagAccessAllow() { + variable_set('FlagHookFlagAccessTestCaseMode', 'allow'); + $flag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); + $this->drupalLogin($flag_user); + + // Look at our node. + $this->drupalGet('node/' . $this->nid); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); + + // Click the link to flag the node. + $this->clickLink(t('Flag this item')); + + $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); + + // Click the link to unflag the node. + $this->clickLink(t('Unflag this item')); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); + } + + /** + * Verifies that the user sees the flag if a module returns TRUE (Allow) to override default access check. + */ + function testFlagAccessAllowOverride() { + variable_set('FlagHookFlagAccessTestCaseMode', 'allow'); + $flag_user = $this->drupalCreateUser(array()); + $this->drupalLogin($flag_user); + + // Look at our node. + $this->drupalGet('node/' . $this->nid); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); + + // Click the link to flag the node. + $this->clickLink(t('Flag this item')); + + $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); + + // Click the link to unflag the node. + $this->clickLink(t('Unflag this item')); + + $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); + } + + /** + * Verifies that the user does not see the flag if a module returns FALSE (Deny). + */ + function testFlagAccessDeny() { + variable_set('FlagHookFlagAccessTestCaseMode', 'deny'); + $flag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); + $this->drupalLogin($flag_user); + + // Look at our node. + $this->drupalGet('node/' . $this->nid); + + $this->assertNoLink('Flag this item', 0, 'The flag link does not appear on the page.'); + } + +} diff --git a/tests/flagaccesstest/flagaccesstest.info b/tests/flagaccesstest/flagaccesstest.info new file mode 100644 index 0000000..3c9c176 --- /dev/null +++ b/tests/flagaccesstest/flagaccesstest.info @@ -0,0 +1,6 @@ +name = Flag hook_flag_access test +description = Tests for hook_flag_access +core = 7.x +dependencies[] = flag +package = Flags +hidden = TRUE diff --git a/tests/flagaccesstest/flagaccesstest.module b/tests/flagaccesstest/flagaccesstest.module new file mode 100644 index 0000000..62a2ce7 --- /dev/null +++ b/tests/flagaccesstest/flagaccesstest.module @@ -0,0 +1,26 @@ + Date: Tue, 21 May 2013 20:56:59 +0100 Subject: [PATCH 302/629] Issue #1999604 by xandeadx: Fixed display field weight not applied to flag pseudofield. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index c51648e..8ca179e 100644 --- a/flag.module +++ b/flag.module @@ -911,7 +911,7 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { // The pseudofield output. if ($flag->show_as_field) { - $entity->content['flag-' . $flag->name] = array( + $entity->content['flag_' . $flag->name] = array( '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array('needs_wrapping_element' => TRUE)), ); } From b2f439982b677d2710bcf14d00aef742467dfd7f Mon Sep 17 00:00:00 2001 From: hefox Date: Fri, 21 Jun 2013 21:34:41 +0100 Subject: [PATCH 303/629] Issue #2025321 by hefox: Fixed incorrect key in Features export dependency array. --- includes/flag.features.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.features.inc b/includes/flag.features.inc index 4017421..f1fb30e 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -12,7 +12,7 @@ function flag_features_export($data, &$export, $module_name = '') { $pipe = array(); // Add flag module as a dependency. - $export['dependencies']['features'] = 'flag'; + $export['dependencies']['flag'] = 'flag'; // Ensure the modules that provide the flag are included as dependencies. $modules = flag_features_providing_module(); From 4cc60baf645e577f6bea3987fa60f200fcf4e6b4 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 11 Jul 2013 19:14:08 +0100 Subject: [PATCH 304/629] by joachim: Fixed mentions of 'node' in generic contexts. --- flag.module | 2 +- includes/flag/flag_flag.inc | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/flag.module b/flag.module index 8ca179e..32b5fa8 100644 --- a/flag.module +++ b/flag.module @@ -1870,7 +1870,7 @@ function flag_get_flag_flagging_data($flag_name) { } /** - * Find what a user has flagged, either a single node or on the entire site. + * Find what a user has flagged, either a single entity or on the entire site. * * @param $entity_type * The type of entity that will be retrieved. Usually 'node'. diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index f491b2c..177d34d 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -358,12 +358,17 @@ class flag_flag { } /** - * Stores some object in fetch_entity()'s cache, so subsequenet calls to - * fetch_entity() return it. + * Store an object in the flag handler's cache. * * This is needed because otherwise fetch_object() loads the object from the * database (by calling _load_entity()), whereas sometimes we want to fetch - * an object that hasn't yet been saved to the database. See flag_nodeapi(). + * an object that hasn't yet been saved to the database. Subsequent calls to + * fetch_entity() return the remembered object. + * + * @param $entity_id + * The ID of the object to cache. + * @param $object + * The object to cache. */ function remember_entity($entity_id, $object) { $this->fetch_entity($entity_id, $object); @@ -612,9 +617,10 @@ class flag_flag { * possibly subtype, of entity. * * @param $entity_type - * The type of entity being checked, usually "node". + * The type of entity being checked, such as "node". * @param $content_subtype - * The subtype (node type) being checked. + * The subtype being checked. For entities this will be the bundle name (the + * node type in the case of nodes). * * @return * TRUE if the flag is enabled for this type and subtype. From 41aa972dedfded73a500b62a71df8c076cf7d67f Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 12 Jul 2013 07:44:24 +0100 Subject: [PATCH 305/629] by joachim: Fixed errors and omissions in documentation. --- flag.module | 75 +++++++++++++++++++++++++------------ includes/flag/flag_flag.inc | 14 +++---- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/flag.module b/flag.module index 32b5fa8..77fdd9b 100644 --- a/flag.module +++ b/flag.module @@ -331,11 +331,16 @@ function flag_admin_menu_map() { /** * Menu loader for '%flag' arguments. * + * @param $flag_name + * The machine name of the flag. * @param $include_disabled - * Whether to return a disabled flag too. Normally only enabled flags are - * returned. Some menu items operate on disabled flags and in this case - * you need to turn on this switch by doing - * 'load arguments' => array(TRUE) in your menu router. + * (optional) Whether to return a disabled flag too. Normally only enabled + * flags are returned. Some menu items operate on disabled flags and in this + * case you need to turn on this switch by doing: + * @code + * 'load arguments' => array(TRUE) + * @endcode + * in your hook_menu(). * * @return * Either the flag object, or FALSE if none was found. @@ -463,7 +468,16 @@ function flag_hook_info() { } /** - * Returns a flag definition. + * Get a flag type definition. + * + * @param $entity_type + * (optional) The entity type to get the definition for, or NULL to return + * all flag types. + * + * @return + * The flag type definition array. + * + * @see hook_flag_type_info() */ function flag_fetch_definition($entity_type = NULL) { $definitions = &drupal_static(__FUNCTION__); @@ -491,6 +505,9 @@ function flag_fetch_definition($entity_type = NULL) { /** * Returns all flag types defined on the system. + * + * @return + * An array of flag type names. */ function flag_get_types() { $types = &drupal_static(__FUNCTION__); @@ -1108,7 +1125,7 @@ function flag_user_delete($account) { } /** - * Callback function for user account cancellation or deletion. + * Shared helper for user account cancellation or deletion. */ function flag_user_account_removal($account) { // Remove flags by this user. @@ -1224,8 +1241,15 @@ function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { /** * Flags or unflags an item. * + * @param $action + * Either 'flag' or 'unflag'. + * @param $flag_name + * The name of the flag to use. + * @param $entity_id + * The ID of the item to flag or unflag. * @param $account - * The user on whose behalf to flag. Leave empty for the current user. + * (optional) The user on whose behalf to flag. Omit for the current user. + * * @return * FALSE if some error occured (e.g., user has no permission, flag isn't * applicable to the item, etc.), TRUE otherwise. @@ -1651,7 +1675,7 @@ function flag_get_counts($entity_type, $entity_id) { * @param $flag_name * The flag name for which to retrieve a flag count. * @param $reset - * Reset the internal cache and execute the SQL query another time. + * (optional) Reset the internal cache and execute the SQL query another time. */ function flag_get_flag_counts($flag_name, $reset = FALSE) { $counts = &drupal_static(__FUNCTION__); @@ -1707,14 +1731,14 @@ function flag_get_flag($name = NULL, $fid = NULL) { * returned. * * @param $entity_type - * Optional. The type of entity for which to load the flags. Usually 'node'. + * (optional) The type of entity for which to load the flags. Usually 'node'. * @param $content_subtype - * Optional. The node type for which to load the flags. + * (optional) The node type for which to load the flags. * @param $account - * Optional. The user accont to filter available flags. If not set, all + * (optional) The user accont to filter available flags. If not set, all * flags for will this node will be returned. * - * @return $flags + * @return * An array of the structure [fid] = flag_object. */ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL) { @@ -1812,7 +1836,8 @@ function _flag_compare_weight($flag1, $flag2) { * Retrieve a list of flags defined by modules. * * @param $include_disabled - * Unless specified, only enabled flags will be returned. + * (optional) Unless specified, only enabled flags will be returned. + * * @return * An array of flag prototypes, not usable for flagging. Use flag_get_flags() * if needing to perform a flagging with any enabled flag. @@ -1856,8 +1881,11 @@ function flag_get_default_flags($include_disabled = FALSE) { /** * Get all flagged entities in a flag. * - * @param + * @param $flag_name * The flag name for which to retrieve flagged entites. + * + * @return + * An array of flagging data, keyed by the flagging ID. */ function flag_get_flag_flagging_data($flag_name) { $return = array(); @@ -1875,17 +1903,17 @@ function flag_get_flag_flagging_data($flag_name) { * @param $entity_type * The type of entity that will be retrieved. Usually 'node'. * @param $entity_id - * Optional. The entity ID to check for flagging. If none given, all + * (optional) The entity ID to check for flagging. If none given, all * entities flagged by this user will be returned. * @param $uid - * Optional. The user ID whose flags we're checking. If none given, the + * (optional) The user ID whose flags we're checking. If none given, the * current user will be used. * @param $sid - * Optional. The user SID (provided by Session API) whose flags we're + * (optional) The user SID (provided by Session API) whose flags we're * checking. If none given, the current user will be used. The SID is 0 for * logged in users. * - * @return $flags + * @return * If returning a single item's flags (that is, when $entity_id isn't NULL), * an array of the structure * [flag_name] => (flagging_id => [flagging_id], uid => [uid], entity_id => [entity_id], timestamp => [timestamp], ...) @@ -1952,7 +1980,7 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid * @param $entity_id * The entity ID to check for flagging. * @param $flag_name - * Optional. The name of a flag if wanting a list specific to a single flag. + * (optional) The name of a flag if wanting a list specific to a single flag. * * @return * If no flag name is given, an array of flagging data, keyed by the user @@ -2056,7 +2084,7 @@ function flag_trim_flag($flag, $account, $cutoff_size) { * @param $flag * The flag object. * @param $entity_id - * Optional. The entity ID on which all flaggings will be removed. If left + * (optional) The entity ID on which all flaggings will be removed. If left * empty, this will remove all of this flag's entities. */ function flag_reset_flag($flag, $entity_id = NULL) { @@ -2090,9 +2118,10 @@ function flag_reset_flag($flag, $entity_id = NULL) { * Return an array of link types provided by modules. * * @return - * An array of link types as defined by hook_flag_link_type_info(). These are keyed - * by the type name, and each value is an array of properties. In addition to - * those defined in hook_flag_link_type_info(), the following properties are set: + * An array of link types as defined by hook_flag_link_type_info(). These are + * keyed by the type name, and each value is an array of properties. In + * addition to those defined in hook_flag_link_type_info(), the following + * properties are set: * - 'module': The providing module. * - 'name': The machine name of the type. * diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 177d34d..25baab2 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -426,10 +426,10 @@ class flag_flag { * Determines whether the user has the permission to use this flag. * * @param $action - * Optional. The action to test, either "flag" or "unflag". If none given, + * (optional) The action to test, either "flag" or "unflag". If none given, * "flag" will be tested, which is the minimum permission to use a flag. * @param $account - * Optional. The user object. If none given, the current user will be used. + * (optional) The user object. If none given, the current user will be used. * * @return * Boolean TRUE if the user is allowed to flag/unflag. FALSE otherwise. @@ -529,7 +529,7 @@ class flag_flag { * The array of entity IDs to check. The keys are the entity IDs, the * values are the actions to test: either 'flag' or 'unflag'. * @param $account - * Optional. The account for which the actions will be compared against. + * (optional) The account for which the actions will be compared against. * If left empty, the current user will be used. * * @return @@ -675,7 +675,7 @@ class flag_flag { * @param $skip_permission_check * Flag the item even if the $account user don't have permission to do so. * @param $flagging - * Optional. This method works in tandem with Drupal's Field subsystem. + * (optional) This method works in tandem with Drupal's Field subsystem. * Pass in a flagging entity if you want operate on it as well. * * @return @@ -869,9 +869,9 @@ class flag_flag { * @param mixed $entity_id * The unique identifier of the object being flagged. * @param int $uid - * Optional. The user id of the user doing the flagging. + * (optional) The user id of the user doing the flagging. * @param mixed $sid - * Optional. The user SID (provided by Session API) who is doing the + * (optional) The user SID (provided by Session API) who is doing the * flagging. The SID is 0 for logged in users. * * @return stdClass @@ -896,7 +896,7 @@ class flag_flag { * item results in only one SQL query. * * @param $uid - * Optional. The user ID whose flags we're checking. If none given, the + * (optional) The user ID whose flags we're checking. If none given, the * current user will be used. * * @return From fcdc4a8e7e32a1addc1450512b832d83f9a28f21 Mon Sep 17 00:00:00 2001 From: bulat Date: Mon, 15 Jul 2013 07:25:15 +0100 Subject: [PATCH 306/629] Issue #2021191 by bulat: Added support for LIKE and IN operators on flagging entity bundle condition in EntityFieldQuery. --- flag.module | 42 +++++++++++--------- tests/flag.test | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 18 deletions(-) diff --git a/flag.module b/flag.module index 77fdd9b..340a0c5 100644 --- a/flag.module +++ b/flag.module @@ -140,34 +140,40 @@ function flagging_save($flagging) { /** * Implements hook_entity_query_alter(). * - * Converts EntityFieldQuery instances on flaggings that have an entity - * condition on bundles (flag machine names). + * Replaces bundle condition in EntityFieldQuery on flagging entities + * with query condition on [name] field in [flag] table. * - * Based on taxonomy_entity_query_alter(). + * @see flag_query_flagging_flag_names_alter() */ -function flag_entity_query_alter($query) { +function flag_entity_query_alter(EntityFieldQuery $query) { $conditions = &$query->entityConditions; // Alter only flagging queries with bundle conditions. if (isset($conditions['entity_type']) && $conditions['entity_type']['value'] == 'flagging' && isset($conditions['bundle'])) { - // Convert flag machine names to flag IDs. - $flags = flag_get_flags(); - $fids = array(); - if (is_array($conditions['bundle']['value'])) { - foreach ($conditions['bundle']['value'] as $flag_name) { - $fids[] = $flags[$flag_name]->fid; - } - } - else { - $flag_name = $conditions['bundle']['value']; - $fids = $flags[$flag_name]->fid; - } - - $query->propertyCondition('fid', $fids, $conditions['bundle']['operator']); + $query->addTag('flagging_flag_names'); // Add tag to alter query. + // Make value and operator of the bundle condition accessible + // in hook_query_TAG_alter. + $query->addMetaData('flag_name_value', $conditions['bundle']['value']); + $query->addMetaData('flag_name_operator', $conditions['bundle']['operator']); unset($conditions['bundle']); } } +/** + * Implements hook_query_TAG_alter() for flagging_flag_names tag. + * + * @see flag_entity_query_alter() + */ +function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { + // Get value and operator for bundle condition from meta data. + $value = $query->getMetaData('flag_name_value'); + $operator = $query->getMetaData('flag_name_operator'); + // Join [flag] and [flagging] tables by [fid] and + // apply bundle condition on [flag].[name] field. + $query->join('flag', 'f', 'flagging.fid = f.fid'); + $query->condition('f.name', $value, $operator); +} + /** * Implements hook_menu(). */ diff --git a/tests/flag.test b/tests/flag.test index 760fd32..e98a6ad 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -860,3 +860,103 @@ class FlagHookFlagAccessTestCase extends FlagTestCaseBase { } } + +/** + * Test use of EntityFieldQueries with flagging entities. + */ +class FlagEntityFieldQueryTestCase extends FlagTestCaseBase { + + /** + * Implements getInfo(). + */ + public static function getInfo() { + return array( + 'name' => t('Flagging Entity Field Query Extension'), + 'description' => t('Entity Field Query for flagging entities.'), + 'group' => t('Flag'), + ); + } + + /** + * Implements setUp(). + */ + function setUp() { + parent::setUp('flag'); + + $flag_data = array( + 'entity_type' => 'node', + 'name' => 'test_flag_1', + 'title' => 'Test Flag', + 'global' => 0, + 'types' => array( + 0 => 'article', + ), + 'flag_short' => 'Flag this item', + 'flag_long' => '', + 'flag_message' => '', + 'unflag_short' => 'Unflag this item', + 'unflag_long' => '', + 'unflag_message' => '', + 'unflag_denied_text' => 'You may not unflag this item', + // Use the normal link type as it involves no intermediary page loads. + 'link_type' => 'normal', + 'weight' => 0, + 'show_on_form' => 0, + 'access_author' => '', + 'show_contextual_link' => 0, + 'show_in_links' => array( + 'full' => 1, + 'teaser' => 1, + ), + 'i18n' => 0, + 'api_version' => 3, + ); + + $this->flag1 = $this->createFlag($flag_data); + $flag_data['name'] = 'test_flag_2'; + $this->flag2 = $this->createFlag($flag_data); + $flag_data['name'] = 'test_flag_3'; + $this->flag3 = $this->createFlag($flag_data); + + // Create test user who can flag and unflag. + $this->flag_unflag_user = $this->drupalCreateUser(array('flag test_flag_1', 'unflag test_flag_1', 'flag test_flag_2', 'unflag test_flag_2')); + $this->drupalLogin($this->flag_unflag_user); + + } + + /** + * Test use of EntityFieldQuery with flagging entities. + */ + function testEntityFieldQuery() { + $node_settings = array( + 'title' => $this->randomName(), + 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), + 'uid' => 1, + 'type' => 'article', + 'is_new' => TRUE, + ); + $node = $this->drupalCreateNode($node_settings); + + flag('flag', 'test_flag_1', $node->nid, $this->flag_unflag_user); + flag('flag', 'test_flag_2', $node->nid, $this->flag_unflag_user); + + $query = new EntityFieldQuery(); + $query->entityCondition('entity_type', 'flagging') + ->entityCondition('bundle', 'test_flag_1'); + + $flagged = $query->execute(); + $this->assertEqual(count($flagged['flagging']), 1); + + $query = new EntityFieldQuery(); + $query->entityCondition('entity_type', 'flagging') + ->entityCondition('bundle', 'test%', 'like'); + $flagged = $query->execute(); + $this->assertEqual(count($flagged['flagging']), 2); + + $query = new EntityFieldQuery(); + $query->entityCondition('entity_type', 'flagging') + ->entityCondition('bundle', array('test_flag_1', 'test_flag_2'), 'IN'); + $this->assertEqual(count($flagged['flagging']), 2); + } + +} From 37aaf412afbcef7c3ad82e25ec5bba8147be8210 Mon Sep 17 00:00:00 2001 From: dixon Date: Mon, 15 Jul 2013 07:29:50 +0100 Subject: [PATCH 307/629] Issue #1925922 by dixon_: Fixed retrieval of flag_link_type_info cache producing empty flags. --- flag.module | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 340a0c5..0e126b9 100644 --- a/flag.module +++ b/flag.module @@ -2141,7 +2141,9 @@ function flag_get_link_types() { if ($cache = cache_get('flag_link_type_info')) { $link_types = $cache->data; } - else { + // In some rare edge cases cache_get() can return an empty result. If it + // does, we make sure to fetch the link types again. + if (empty($link_types)) { $link_types = array(); foreach (module_implements('flag_link_type_info') as $module) { $module_types = module_invoke($module, 'flag_link_type_info'); From 6b79524bddc6a152480878c51765c71a57c85447 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 31 Jul 2013 07:47:04 +0100 Subject: [PATCH 308/629] by joachim: Fixed missing class docblocks. --- tests/flag.test | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/flag.test b/tests/flag.test index e98a6ad..7397890 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -33,6 +33,9 @@ abstract class FlagTestCaseBase extends DrupalWebTestCase { } +/** + * Test CRUD operations on Flagging entities. + */ class FlagFlaggingCRUDTestCase extends FlagTestCaseBase { /** @@ -209,6 +212,9 @@ class FlagFlaggingCRUDTestCase extends FlagTestCaseBase { } +/** + * Test Flag admin UI. + */ class FlagAdminTestCase extends FlagTestCaseBase { var $_flag = FALSE; @@ -583,6 +589,9 @@ class FlagAccessLinkTestCase extends FlagTestCaseBase { } +/** + * Test the 'confirm form' link type. + */ class FlagLinkTypeConfirmTestCase extends DrupalWebTestCase { /** From 42a0c79bf49864c9b68b96ea05f035a639678e7c Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 8 Aug 2013 12:55:37 +0100 Subject: [PATCH 309/629] Issue #2059959 by joachim: Fixed 'global' property can't be defined as FALSE in hook_flag_default_flags(). --- includes/flag/flag_flag.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/includes/flag/flag_flag.inc b/includes/flag/flag_flag.inc index 25baab2..071b148 100644 --- a/includes/flag/flag_flag.inc +++ b/includes/flag/flag_flag.inc @@ -1272,6 +1272,12 @@ class flag_flag { * Saves a flag to the database. It is a wrapper around update() and insert(). */ function save() { + // Allow the 'global' property to be a boolean, particularly when defined in + // hook_flag_default_flags(). Without this, a value of FALSE gets casted to + // an empty string which violates our schema. Other boolean properties are + // fine, as they are serialized. + $this->global = (int) $this->global; + if (isset($this->fid)) { $this->update(); $this->is_new = FALSE; From d6c4c4b4fa62c45caf25f9993d0c7f2615f9b7a5 Mon Sep 17 00:00:00 2001 From: ShabanaBlackborder Date: Fri, 16 Aug 2013 06:53:26 +0100 Subject: [PATCH 310/629] Issue #2023481 by generalredneck: Added Rules: Allow for grabbing flagged entities by user other than nodes. --- flag.rules.inc | 68 +++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/flag.rules.inc b/flag.rules.inc index 8069b29..8c31ce0 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -190,29 +190,6 @@ function flag_rules_action_info() { 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), - 'flag_fetch_entity_by_user' => array( - 'label' => t('Fetch content flagged by user'), - 'base' => 'flag_rules_action_fetch_entity_by_user', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - ), - 'flagging_user' => array( - 'type' => 'user', - 'label' => t('User who flagged the content'), - 'description' => t('For non-global flags, this is the user who flagged the content. (For global flags, this argument is ignored.)'), - ), - ), - 'provides' => array( - 'content_flagged_by_user' => array( - 'label' => t('Content flagged by user'), - 'type' => 'list', - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), ); $param_defaults = array( 'flagging_user' => array( @@ -229,38 +206,64 @@ function flag_rules_action_info() { ); foreach (flag_get_types() as $type) { $entity_info = entity_get_info($type); + $label = $entity_info['label']; $items += array( + 'flag_fetch_' . $type . '_by_user' => array( + 'label' => t('Fetch @label flagged by user', array('@label' => $label)), + 'base' => 'flag_rules_action_fetch_entity_by_user', + 'parameter' => array( + 'flag' => array( + 'type' => 'flag', + 'label' => t('Flag'), + 'flag_type' => $type, + 'description' => t('The flag to check for.'), + ), + 'flagging_user' => array( + 'type' => 'user', + 'label' => t('User who flagged the @label', array('@label' => $label)), + 'description' => t('For non-global flags, this is the user who flagged the @label. (For global flags, this argument is ignored.)', array('@label' => $label)), + ), + ), + 'provides' => array( + 'content_flagged_by_user' => array( + 'label' => t('Content flagged by user'), + 'type' => 'list<' . $type . '>', + ), + ), + 'group' => t('Flag'), + 'access callback' => 'flag_rules_integration_access', + ), 'flag_flag' . $type => array( - 'label' => t('Flag a @type', array('@type' => $type)), + 'label' => t('Flag a @label', array('@label' => $label)), 'base' => 'flag_rules_action_flag', 'parameter' => array( 'flag' => array( 'type' => 'flag', 'label' => t('Flag'), 'flag_type' => $type, - 'description' => t('The flag to check for.') + 'description' => t('The flag to check for.'), ), $type => array( 'type' => $type, - 'label' => isset($entity_info[$type]['label']) ? $entity_info[$type]['label'] : $type, + 'label' => $label, ), ) + $param_defaults, 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), 'flag_unflag' . $type => array( - 'label' => t('Unflag a @type', array('@type' => $type)), + 'label' => t('Unflag a @label', array('@label' => $label)), 'base' => 'flag_rules_action_unflag', 'parameter' => array( 'flag' => array( 'type' => 'flag', 'label' => t('Flag'), 'flag_type' => $type, - 'description' => t('The flag to check for.') + 'description' => t('The flag to check for.'), ), $type => array( 'type' => $type, - 'label' => isset($entity_info[$type]['label']) ? $entity_info[$type]['label'] : $type, + 'label' => $label, ), ) + $param_defaults, 'group' => t('Flag'), @@ -268,7 +271,7 @@ function flag_rules_action_info() { ), ); $items['flag_fetch_users_' . $type] = array( - 'label' => t('Fetch users who have flagged a @type', array('@type' => $type)), + 'label' => t('Fetch users who have flagged a @label', array('@label' => $label)), 'base' => 'flag_rules_action_fetch_users', 'parameter' => array( 'flag' => array( @@ -279,7 +282,7 @@ function flag_rules_action_info() { ), $type => array( 'type' => $type, - 'label' => isset($entity_info[$type]['label']) ? $entity_info[$type]['label'] : $type, + 'label' => $label, ), ), 'provides' => array( @@ -292,6 +295,9 @@ function flag_rules_action_info() { 'access callback' => 'flag_rules_integration_access', ); } + // For backward compatibility sake. This was the original name of the 'fetch node by user'. + $items['flag_fetch_entity_by_user'] = $items['flag_fetch_node_by_user']; + $items['flag_fetch_entity_by_user']['label'] .= ' '. t('(Legacy)'); return $items; } From b3900b5e9a25400d7453e788bb813e2a6007f4ac Mon Sep 17 00:00:00 2001 From: ShabanaBlackborder Date: Fri, 16 Aug 2013 07:08:18 +0100 Subject: [PATCH 311/629] Issue #1988258 by Shabana Blackborder: Added More options for Trim Flag rule. --- flag.module | 22 +++++++++++++++++----- flag.rules.inc | 9 +++++++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/flag.module b/flag.module index 0e126b9..b5c27e0 100644 --- a/flag.module +++ b/flag.module @@ -2066,16 +2066,28 @@ function flag_create_link($flag_name, $entity_id) { * The user object on behalf the trimming will occur. * @param $cutoff_size * The number of flaggings allowed. Any flaggings beyond that will be trimmed. + * @param $trim_newest + * An optional boolean indicating whether to trim the newest flags. */ -function flag_trim_flag($flag, $account, $cutoff_size) { - $result = db_select('flagging', 'fc') +function flag_trim_flag($flag, $account, $cutoff_size, $trim_newest) { + $query = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid) ->condition(db_or()->condition('uid', $account->uid)->condition('uid', 0)) // Account for session ID (in the case of anonymous users). - ->condition('sid', flag_get_sid($account->uid)) - ->orderBy('timestamp', 'DESC') - ->execute(); + ->condition('sid', flag_get_sid($account->uid)); + // If $trim_newest is TRUE, then, we should order by 'ASC' as we should trim + // the newest flags. + if ($trim_newest) { + $query->orderBy('timestamp', 'ASC'); + } + else { + $query->orderBy('timestamp', 'DESC') ; + } + + // Execute the query + $result = $query->execute(); + $i = 1; foreach ($result as $row) { if ($i++ > $cutoff_size) { diff --git a/flag.rules.inc b/flag.rules.inc index 8c31ce0..0208ca5 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -186,6 +186,11 @@ function flag_rules_action_info() { 'label' => t('Flag queue size'), 'description' => t('The maximum number of objects to keep in the queue. Newly flagged objects will be kept; older ones will be removed. Tip: by typing "1" here you implement a singleton.'), ), + 'trim_newest' => array( + 'type' => 'boolean', + 'label' => t('Trim newest flags'), + 'description' => t('Checking this will trim the newest flags. This will prevent new flags once a limit is reached.'), + ), ), 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', @@ -318,14 +323,14 @@ function flag_rules_action_unflag($flag, $entity, $flagging_user, $permissions_c /** * Base action implementation: Trim flag. */ -function flag_rules_action_trim($flag, $flagging_user, $cutoff_size) { +function flag_rules_action_trim($flag, $flagging_user, $cutoff_size, $trim_newest) { // For some reason, when this action fires in response to a flagging event, // as an anonymous user, then the $flagging_user is sent through as FALSE. // Not sure why. This workaround fixes the problem in this specific case. if ($flagging_user === FALSE) { $flagging_user = $GLOBALS['user']; } - flag_trim_flag($flag, $flagging_user, $cutoff_size); + flag_trim_flag($flag, $flagging_user, $cutoff_size, $trim_newest); } /** From 32be86bd316f3ad7e8aa2f823d27da864b1a5670 Mon Sep 17 00:00:00 2001 From: ShabanaBlackborder Date: Tue, 20 Aug 2013 08:41:37 +0100 Subject: [PATCH 312/629] Issue #1396196 by Shabana Blackborder: Added Rules action - get flag count. --- flag.module | 66 +++++++++++++++++++++++++++++++- flag.rules.inc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index b5c27e0..71bf6d1 100644 --- a/flag.module +++ b/flag.module @@ -1643,6 +1643,68 @@ function _flag_link_type_descriptions() { // --------------------------------------------------------------------------- // Non-Views public API +/** + * Get the count of flags for a certain entity. + * + * @param $flag + * The flag. + * @param $entity_type + * The entity type (usually 'node'). + * + * @return + * The flag count with the flag name and entity type as the array key. + */ +function flag_get_entity_flag_counts($flag, $entity_type) { + $counts = &drupal_static(__FUNCTION__); + + // We check to see if the flag count is already in the cache, + // if it's not, run the query. + if (!isset($counts[$flag->name][$entity_type])) { + $counts[$flag->name][$entity_type] = array(); + $result = db_select('flagging', 'f') + ->fields('f', array('fid')) + ->condition('fid', $flag->fid) + ->condition('entity_type', $entity_type) + ->countQuery() + ->execute() + ->fetchField(); + $counts[$flag->name][$entity_type] = $result; + } + + return $counts[$flag->name][$entity_type]; +} + +/** + * Get the user's flag count. + * + * @param $flag + * The flag. + * @param $user + * The user object. + * + * @return + * The flag count with the flag name and the uid as the array key. + */ +function flag_get_user_flag_counts($flag, $user) { + $counts = &drupal_static(__FUNCTION__); + + // We check to see if the flag count is already in the cache, + // if it's not, run the query. + if (!isset($counts[$flag->name][$user->uid])) { + $counts[$flag->name][$user->uid] = array(); + $result = db_select('flagging', 'f') + ->fields('f', array('fid')) + ->condition('fid', $flag->fid) + ->condition('uid', $user->uid) + ->countQuery() + ->execute() + ->fetchField(); + $counts[$flag->name][$user->uid] = $result; + } + + return $counts[$flag->name][$user->uid]; +} + /** * Get flag counts for all flags on a node. * @@ -1651,8 +1713,8 @@ function _flag_link_type_descriptions() { * @param $entity_id * The entity ID (usually the node ID). * - * @return $flags - * An array of the structure [name] => [number of flags]. + * @return + * The flag count with the entity type and id as array keys. */ function flag_get_counts($entity_type, $entity_id) { $counts = &drupal_static(__FUNCTION__); diff --git a/flag.rules.inc b/flag.rules.inc index 0208ca5..3810a1e 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -195,6 +195,70 @@ function flag_rules_action_info() { 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), + 'fetch_overall_flag_count' => array( + 'label' => t('Fetch overall flag count'), + 'base' => 'flag_rules_action_fetch_overall_flag_count', + 'parameter' => array( + 'flag' => array( + 'type' => 'flag', + 'label' => t('Flag'), + ), + ), + 'provides' => array( + 'overall_flag_count' => array( + 'label' => t('Overall flag count'), + 'type' => 'integer', + ), + ), + 'group' => t('Flag'), + 'access callback' => 'flag_rules_integration_access', + ), + 'fetch_entity_flag_count' => array( + 'label' => t('Fetch entity flag count'), + 'base' => 'flag_rules_action_fetch_entity_flag_count', + 'parameter' => array( + 'flag' => array( + 'type' => 'flag', + 'label' => t('Flag'), + ), + 'entity_type' => array( + 'type' => 'text', + 'label' => t('Entity type'), + 'options list' => 'flag_rules_get_flag_types', + 'restriction' => 'input', + ), + ), + 'provides' => array( + 'entity_flag_count' => array( + 'label' => t('Entity flag count'), + 'type' => 'integer', + ), + ), + 'group' => t('Flag'), + 'access callback' => 'flag_rules_integration_access', + ), + 'fetch_user_flag_count' => array( + 'label' => t('Fetch user flag count'), + 'base' => 'flag_rules_action_fetch_user_flag_count', + 'parameter' => array( + 'flag' => array( + 'type' => 'flag', + 'label' => t('Flag'), + ), + 'user' => array( + 'type' => 'user', + 'label' => t('User'), + ), + ), + 'provides' => array( + 'user_flag_count' => array( + 'label' => t('User flag count'), + 'type' => 'integer', + ), + ), + 'group' => t('Flag'), + 'access callback' => 'flag_rules_integration_access', + ), ); $param_defaults = array( 'flagging_user' => array( @@ -363,6 +427,44 @@ function flag_rules_action_fetch_entity_by_user($flag, $user) { return array('content_flagged_by_user' => $flagged); } +/** + * Base action implementation: Fetch overall count for a particular flag. + */ +function flag_rules_action_fetch_overall_flag_count($flag) { + $count = flag_get_flag_counts($flag->name); + return array('overall_flag_count' => $count); +} + +/** + * Helper function which will return all the available flag types. + * + * @return + * An array of flag type names keyed by the type name. + */ +function flag_rules_get_flag_types() { + $types = array(); + foreach (flag_get_types() as $type) { + $types[$type] = $type; + } + return $types; +} + +/** + * Base action implementation: Fetch count of flags for a particular entity. + */ +function flag_rules_action_fetch_entity_flag_count($flag, $entity_type) { + $count = flag_get_entity_flag_counts($flag, $entity_type); + return array('entity_flag_count' => $count); +} + +/** + * Base action implementation: Fetch user's flag count. + */ +function flag_rules_action_fetch_user_flag_count($flag, $user) { + $count = flag_get_user_flag_counts($flag, $user); + return array('user_flag_count' => $count); +} + /** * Implements hook_rules_condition_info(). */ From 67b0d360e9bda0f476be4c7be8778808ea967f50 Mon Sep 17 00:00:00 2001 From: ShabanaBlackborder Date: Wed, 21 Aug 2013 07:30:17 +0100 Subject: [PATCH 313/629] Issue #1689510 by Shabana Blackborder | c4rl: Added 'Trim a flag' action should support 'Skip permission check' parameter. --- flag.module | 14 ++++++++++---- flag.rules.inc | 30 +++++++++++++++--------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/flag.module b/flag.module index 71bf6d1..74da1ab 100644 --- a/flag.module +++ b/flag.module @@ -1255,17 +1255,19 @@ function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { * The ID of the item to flag or unflag. * @param $account * (optional) The user on whose behalf to flag. Omit for the current user. + * @permissions_check + * (optional) A boolean indicating whether to skip permissions. * * @return * FALSE if some error occured (e.g., user has no permission, flag isn't * applicable to the item, etc.), TRUE otherwise. */ -function flag($action, $flag_name, $entity_id, $account = NULL) { +function flag($action, $flag_name, $entity_id, $account = NULL, $permissions_check = FALSE) { if (!($flag = flag_get_flag($flag_name))) { // Flag does not exist. return FALSE; } - return $flag->flag($action, $entity_id, $account); + return $flag->flag($action, $entity_id, $account, $permissions_check); } /** @@ -2130,8 +2132,12 @@ function flag_create_link($flag_name, $entity_id) { * The number of flaggings allowed. Any flaggings beyond that will be trimmed. * @param $trim_newest * An optional boolean indicating whether to trim the newest flags. + * @param $permissions_check + * (optional) A boolean indicating whether to skip permissions. + * This will trim the flag if $permissions_check is TRUE even if the user + * doesn't have the permission to flag/unflag. */ -function flag_trim_flag($flag, $account, $cutoff_size, $trim_newest) { ++ function flag_trim_flag($flag, $account, $cutoff_size, $trim_newest, $permissions_check = FALSE) { $query = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid) @@ -2153,7 +2159,7 @@ function flag_trim_flag($flag, $account, $cutoff_size, $trim_newest) { $i = 1; foreach ($result as $row) { if ($i++ > $cutoff_size) { - flag('unflag', $flag->name, $row->entity_id, $account); + flag('unflag', $flag->name, $row->entity_id, $account, $permissions_check); } } } diff --git a/flag.rules.inc b/flag.rules.inc index 3810a1e..edadc2b 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -167,6 +167,14 @@ function flag_rules_event_info() { * Implements hook_rules_action_info(). */ function flag_rules_action_info() { + $param_defaults = array( + 'permission_check' => array( + 'type' => 'boolean', + 'label' => t('Skip permission check'), + 'description' => t('Whether to ignore permissions of the user on whose behalf to flag.'), + 'restriction' => 'input', + ), + ); $items = array( 'flag_trim' => array( 'label' => t('Trim a flag'), @@ -191,7 +199,7 @@ function flag_rules_action_info() { 'label' => t('Trim newest flags'), 'description' => t('Checking this will trim the newest flags. This will prevent new flags once a limit is reached.'), ), - ), + ) + $param_defaults, 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), @@ -260,18 +268,10 @@ function flag_rules_action_info() { 'access callback' => 'flag_rules_integration_access', ), ); - $param_defaults = array( - 'flagging_user' => array( - 'type' => 'user', - 'label' => t('User on whose behalf to flag'), - 'description' => t('For non-global flags, this is the user on whose behalf to flag the object. In addition, if checked below, the access permissions to the flag are checked against this user.'), - ), - 'permission_check' => array( - 'type' => 'boolean', - 'label' => t('Skip permission check'), - 'description' => t('Whether to ignore permissions of the user on whose behalf to flag.'), - 'restriction' => 'input', - ), + $param_defaults['flagging_user'] = array( + 'type' => 'user', + 'label' => t('User on whose behalf to flag'), + 'description' => t('For non-global flags, this is the user on whose behalf to flag the object. In addition, if checked below, the access permissions to the flag are checked against this user.'), ); foreach (flag_get_types() as $type) { $entity_info = entity_get_info($type); @@ -387,14 +387,14 @@ function flag_rules_action_unflag($flag, $entity, $flagging_user, $permissions_c /** * Base action implementation: Trim flag. */ -function flag_rules_action_trim($flag, $flagging_user, $cutoff_size, $trim_newest) { +function flag_rules_action_trim($flag, $flagging_user, $cutoff_size, $trim_newest, $permissions_check) { // For some reason, when this action fires in response to a flagging event, // as an anonymous user, then the $flagging_user is sent through as FALSE. // Not sure why. This workaround fixes the problem in this specific case. if ($flagging_user === FALSE) { $flagging_user = $GLOBALS['user']; } - flag_trim_flag($flag, $flagging_user, $cutoff_size, $trim_newest); + flag_trim_flag($flag, $flagging_user, $cutoff_size, $trim_newest, $permissions_check); } /** From 50cb6f8e553c59e7577d655ebb8c18a8d026d97c Mon Sep 17 00:00:00 2001 From: generalredneck Date: Wed, 21 Aug 2013 07:37:47 +0100 Subject: [PATCH 314/629] Issue #2054927 by generalredneck: Fixed Using the 'Flag Fetch By User' rule returns the wrong result when grabbing for Anonymous users. --- flag.info.inc | 7 +++++++ flag.module | 29 +++++++++++++++++++++++++++++ flag.rules.inc | 17 +++++++++++------ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/flag.info.inc b/flag.info.inc index 1870c5a..69bbb5c 100644 --- a/flag.info.inc +++ b/flag.info.inc @@ -61,6 +61,13 @@ function flag_entity_property_info_alter(&$info) { 'flag_name' => $flag->name, 'flag_entity_type' => $flag->entity_type, ); + $info['user']['properties']['flag_sid'] = array( + 'label' => t('Flag user session identifier'), + 'description' => t('Returns the sessions id used to distinguish anonymous users from each other.'), + 'type' => 'text', + 'getter callback' => 'flag_properties_get_user_sid', + 'computed' => TRUE, + ); // Entity property: list of users who have flagged this entity. // This can go on either the entity as a whole, or on bundles, depending // on whether the flag is limited by bundle. diff --git a/flag.module b/flag.module index 74da1ab..cb95198 100644 --- a/flag.module +++ b/flag.module @@ -2452,3 +2452,32 @@ function flag_properties_get_flagging_users($entity, array $options, $name, $ent return array_keys($flagging_data); } + +/** + * Getter callback that returns the SID of the user that is being retrieved. + * + * Callback for hook_entity_property_info_alter(). + * + * @param stdobj $entity + * The entity object representing a user for which we are getting inforamtion for. + * + * @param array $options + * Options reguarding the nature of the entity. Language, etc. + * + * @param string $name + * The name of the property we are running this callback for. + * + * @param string $entity_type + * The type that the stdobj $entity is supposed to be. + * + * @param $property_info + * The ifnromatin that represents the property we are providing a result for. + * + * @return an integer representing the user's sid field from the session_api table + * + * @ingroup callbacks + */ +function flag_properties_get_user_sid($entity, array $options, $name, $entity_type, $property_info) { + $sid = flag_get_sid($entity->uid, FALSE); + return $sid; +} diff --git a/flag.rules.inc b/flag.rules.inc index edadc2b..25a5ee6 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -415,14 +415,19 @@ function flag_rules_action_fetch_users($flag, $entity) { /** * Base action implementation: Fetch entities who were flagged a user. */ -function flag_rules_action_fetch_entity_by_user($flag, $user) { - $result = db_select('flagging', 'fc') +function flag_rules_action_fetch_entity_by_user($flag, $entity) { + $user = entity_metadata_wrapper('user', $entity); + $sid = $user->flag_sid->value(); + $query = db_select('flagging', 'fc') ->fields('fc', array('entity_id')) ->condition('entity_type', $flag->entity_type) - ->condition('uid', $user->uid) - ->condition('fid', $flag->fid) - ->execute(); - + ->condition('uid', $user->uid->value()) + ->condition('fid', $flag->fid); + // Filter out any bad session ids and any users that aren't anonymous. + if (!empty($sid) && $sid != -1) { + $query->condition('sid', $sid); + } + $result = $query->execute(); $flagged = $result->fetchCol(); return array('content_flagged_by_user' => $flagged); } From c0b0820bcbff6a3e6c5f1c1f60baa1bde50f664a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 21 Aug 2013 07:50:54 +0100 Subject: [PATCH 315/629] Issue #2059967 by joachim: Fixed exported flags containing internal / automatically generated flag properties. --- includes/flag.export.inc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 5053c67..8924925 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -47,19 +47,23 @@ function flag_export_flags($flags = array(), $module = '', $indent = '') { // Allow other modules to change the exported flag. drupal_alter('flag_export', $new_flag); - // Remove the flag ID. - unset($new_flag['fid']); - // The name is emitted as the key for the array. - unset($new_flag['name']); - -// Do not export the whole entity info, as it is just used as helper data. - if (isset($new_flag['entity_info'])) { - unset($new_flag['entity_info']); + // Remove properties we don't export. + $unset_properties = array( + // Remove the flag ID. + 'fid', + // The name is emitted as the key for the array. + 'name', + // The entity info is just used as helper data. + 'entity_info', + // Remove roles. + 'roles', + // Remove errors. + 'errors', + ); + foreach ($unset_properties as $property) { + unset($new_flag[$property]); } - // Remove roles. - unset($new_flag['roles']); - $output .= $indent . '// Exported flag: "' . check_plain($flag->get_title()) . '"' . ".\n"; $output .= $indent . '$flags[\'' . $flag->name . '\'] = ' . (function_exists('features_var_export') ? features_var_export($new_flag, $indent) : var_export($new_flag, TRUE)) . ";\n"; } From 3ce446971c2a68cb21c6f22db1256d30e09d4957 Mon Sep 17 00:00:00 2001 From: berliner Date: Wed, 21 Aug 2013 07:54:14 +0100 Subject: [PATCH 316/629] Issue #1448530 by berliner, sunnyuff: Fixed missing sample code in hook_flag_default_flags(). --- flag.api.php | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/flag.api.php b/flag.api.php index 08b1749..88aef7a 100644 --- a/flag.api.php +++ b/flag.api.php @@ -57,7 +57,37 @@ function hook_flag_type_info_alter(&$definitions) { * Define default flags. */ function hook_flag_default_flags() { - + $flags = array(); + $flags['bookmarks'] = array ( + 'entity_type' => 'node', + 'title' => 'Bookmarks', + 'global' => FALSE, + 'types' => array ( + 0 => 'article', + 1 => 'blog', + ), + 'flag_short' => 'Bookmark this', + 'flag_long' => 'Add this post to your bookmarks', + 'flag_message' => 'This post has been added to your bookmarks', + 'unflag_short' => 'Unbookmark this', + 'unflag_long' => 'Remove this post from your bookmarks', + 'unflag_message' => 'This post has been removed from your bookmarks', + 'unflag_denied_text' => '', + 'link_type' => 'toggle', + 'weight' => 0, + 'show_in_links' => array ( + 'full' => TRUE, + 'token' => FALSE, + ), + 'show_as_field' => FALSE, + 'show_on_form' => FALSE, + 'access_author' => '', + 'show_contextual_link' => TRUE, + 'show_on_profile' => FALSE, + 'access_uid' => '', + 'api_version' => 3, + ); + return $flags; } /** From 32ccf214e5688993bd0d4ac17e1eb19d0aabb7ac Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 21 Aug 2013 16:45:14 +0100 Subject: [PATCH 317/629] Issue #1689510 (follow-up) by joachim: Fixed stray character from patch. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index cb95198..d4ec02a 100644 --- a/flag.module +++ b/flag.module @@ -2137,7 +2137,7 @@ function flag_create_link($flag_name, $entity_id) { * This will trim the flag if $permissions_check is TRUE even if the user * doesn't have the permission to flag/unflag. */ -+ function flag_trim_flag($flag, $account, $cutoff_size, $trim_newest, $permissions_check = FALSE) { +function flag_trim_flag($flag, $account, $cutoff_size, $trim_newest, $permissions_check = FALSE) { $query = db_select('flagging', 'fc') ->fields('fc') ->condition('fid', $flag->fid) From 30ad12a0b612acca5eb3832b16ea6f43559cc63f Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 21 Aug 2013 16:45:23 +0100 Subject: [PATCH 318/629] by joachim: Fixed @param documentation. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index d4ec02a..bf63c49 100644 --- a/flag.module +++ b/flag.module @@ -1255,7 +1255,7 @@ function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { * The ID of the item to flag or unflag. * @param $account * (optional) The user on whose behalf to flag. Omit for the current user. - * @permissions_check + * @param permissions_check * (optional) A boolean indicating whether to skip permissions. * * @return From d38b1199fc753c315dfee101b425f8d3b5959821 Mon Sep 17 00:00:00 2001 From: git Date: Fri, 23 Aug 2013 08:26:18 +0100 Subject: [PATCH 319/629] Issue #1619114 by cspurk, a.ross, smartango, Shabana Blackborder: Fixed invalid session IDs causing exceptions when anonymous user no longer has a cookie. --- flag.module | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/flag.module b/flag.module index bf63c49..93fda28 100644 --- a/flag.module +++ b/flag.module @@ -2267,6 +2267,21 @@ function flag_check_token($token, $entity_id) { /** * Set the Session ID for a user. Utilizes the Session API module. + * + * Creates a Session ID for an anonymous user and returns it. It will always + * return 0 for registered users. + * + * @param int $uid + * (optional) The user ID to create a session ID for. Defaults to the + * current user. + * @param bool $create + * (optional) Determines whether a session should be created if it doesn't + * exist yet. Defaults to TRUE. + * + * @return + * The session ID, if a session was created. If not, the return value is 0. + * + * @see flag_get_sid() */ function flag_set_sid($uid = NULL, $create = TRUE) { $sids = &drupal_static(__FUNCTION__, array()); @@ -2275,8 +2290,13 @@ function flag_set_sid($uid = NULL, $create = TRUE) { $uid = $GLOBALS['user']->uid; } - if (!isset($sids[$uid])) { + // Set the sid if none has been set yet. If the caller specified to create an + // sid and we have an invalid one (-1), create it. + if (!isset($sids[$uid]) || ($sids[$uid] == -1 && $create)) { if (module_exists('session_api') && session_api_available() && $uid == 0) { + // This returns one of the following: + // - -1. This indicates that no session exists and none was created. + // - A positive integer with the Session ID when it does exist. $sids[$uid] = session_api_get_sid($create); } else { @@ -2284,18 +2304,28 @@ function flag_set_sid($uid = NULL, $create = TRUE) { } } - return $sids[$uid]; + // Keep the -1 case internal and let the outside world only distinguish two + // cases: (1) there is an SID; (2) there is no SID (-> 0). + return $sids[$uid] == -1 ? 0 : $sids[$uid]; } /** * Get the Session ID for a user. Utilizes the Session API module. * - * @param $uid - * The user ID. If the UID is 0 (anonymous users), then a SID will be - * returned. SID will always be 0 for any authenticated user. - * @param $create - * If the user doesn't yet have a session, should one be created? Defaults - * to FALSE. + * Gets the Session ID for an anonymous user. It will always return 0 for + * registered users. + * + * @param int $uid + * (optional) The user ID to return the session ID for. Defaults to the + * current user. + * @param bool $create + * (optional) Determines whether a session should be created if it doesn't + * exist yet. Defaults to TRUE. + * + * @return + * The session ID, if the session exists. If not, the return value is 0. + * + * @see flag_set_sid() */ function flag_get_sid($uid = NULL, $create = FALSE) { return flag_set_sid($uid, $create); From 97ad686b669a1f47395cf849400ef21226884b33 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Fri, 23 Aug 2013 09:53:08 +0100 Subject: [PATCH 320/629] Issue #1619114 (follow-up) by a.ross: Fixed error in @param documentation. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 93fda28..3881f60 100644 --- a/flag.module +++ b/flag.module @@ -2320,7 +2320,7 @@ function flag_set_sid($uid = NULL, $create = TRUE) { * current user. * @param bool $create * (optional) Determines whether a session should be created if it doesn't - * exist yet. Defaults to TRUE. + * exist yet. Defaults to FALSE. * * @return * The session ID, if the session exists. If not, the return value is 0. From 5dd3e64fa080f37a39f5989aea02e9bbaa7d9bfe Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Mon, 26 Aug 2013 08:26:27 +0100 Subject: [PATCH 321/629] Issue #2056271 by joachim: Fixed Flag pseudofields don't show in display options without a manual cache clear. --- includes/flag.admin.inc | 34 ++++++++++++++++++++++++++-------- includes/flag.export.inc | 8 +++++++- includes/flag.features.inc | 7 ++++++- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 4ab59d6..926a993 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -668,7 +668,7 @@ function flag_form_submit($form, &$form_state) { $flag->enable(); drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); // We clear caches more vigorously if the flag was new. - _flag_clear_cache(!empty($flag->is_new)); + _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); // Save permissions. // This needs to be done after the flag cache has been cleared, so that @@ -753,7 +753,7 @@ function flag_delete_confirm_submit($form, &$form_state) { if ($form_state['values']['confirm']) { $flag->delete(); $flag->disable(); - _flag_clear_cache(TRUE); + _flag_clear_cache($flag->entity_type, TRUE); } drupal_set_message(t('Flag @name has been deleted.', array('@name' => $flag->get_title()))); $form_state['redirect'] = FLAG_ADMIN_PATH; @@ -771,26 +771,44 @@ function flag_check_link_types($element) { } /** - * Clears various caches when a flag is modified. + * Clears various caches when one or more flags are modified. * - * @param $clear_entity_info - * Whether to also clear the entity info cache. This is needed when adding or - * deleting a flag, as this changes the bundles on the flagging entity. In + * @param $entity_types + * The entity types for the flags. May be a single value or an array. + * @param $is_insert_or_delete + * Whether the modified flag is being inserted (saved for the first time) or + * deleted. This results in a more vigorous clearing of caches. In * particular, when no flags exist yet, no Field admin UI paths exist and these * need to be created. */ -function _flag_clear_cache($clear_entity_info = FALSE) { +function _flag_clear_cache($entity_types, $is_insert_or_delete = FALSE) { + if (!is_array($entity_types)) { + $entity_types = array($entity_types); + } + // Reset our flags cache, thereby making the following code aware of the // modifications. drupal_static_reset('flag_get_flags'); - if ($clear_entity_info) { + if ($is_insert_or_delete) { + // A new or deleted flag means we are changing bundles on the Flagging + // entity, and thus need to clear the entity info cache. entity_info_cache_clear(); } + // Clear FieldAPI's field_extra cache, so our changes to pseudofields are + // noticed. It's rather too much effort to both a) check whether the + // pseudofield setting has changed either way, and b) specifically clear just + // the bundles that are (or were!!) affected, so we just clear for all bundles + // on our entity type regardlesss. + foreach ($entity_types as $entity_type) { + cache_clear_all("field_info:bundle_extra:$entity_type:", 'cache_field', TRUE); + } + if (module_exists('views')) { views_invalidate_cache(); } + // The title of a flag may appear in the menu (indirectly, via our "default // views"), so we need to clear the menu cache. This call also clears the // page cache, which is desirable too because the flag labels may have diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 8924925..539899c 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -145,6 +145,10 @@ function flag_import_form_validate($form, &$form_state) { function flag_import_form_submit($form, &$form_state) { module_load_include('inc', 'flag', 'includes/flag.admin'); + // Build up values for the cache clear. + $entity_types = array(); + $new = FALSE; + foreach ($form_state['flags'] as $flag) { $flag->save(); if (!empty($flag->status)) { @@ -152,12 +156,14 @@ function flag_import_form_submit($form, &$form_state) { } if ($flag->is_new) { drupal_set_message(t('Flag @name has been imported.', array('@name' => $flag->name))); + $new = TRUE; } else { drupal_set_message(t('Flag @name has been updated.', array('@name' => $flag->name))); } + $entity_types[] = $flag->entity_type; } - _flag_clear_cache(); + _flag_clear_cache($entity_types, $new); $form_state['redirect'] = FLAG_ADMIN_PATH; } diff --git a/includes/flag.features.inc b/includes/flag.features.inc index f1fb30e..c61dc1b 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -80,6 +80,9 @@ function flag_features_revert($module = NULL) { module_load_include('inc', 'flag', '/includes/flag.admin'); $default_flags = module_invoke($module, 'flag_default_flags'); + // Build up values for the cache clear. + $entity_types = array(); + // Revert flags that are defined in code. foreach ($default_flags as $flag_name => $flag_info) { if (is_numeric($flag_name)) { @@ -90,8 +93,10 @@ function flag_features_revert($module = NULL) { if ($flag && $flag->revert() === FALSE) { drupal_set_message(t('Could not revert flag %flag-name to the state described in your code: Your flag was created by a different version of the Flag module than is now being used.', array('%flag-name' => $flag->name)), 'error'); } + + $entity_types[] = $flag->entity_type; } - _flag_clear_cache(); + _flag_clear_cache($entity_types); } } From c88b0754c98f9b749ef054892bb402e6e949f3bf Mon Sep 17 00:00:00 2001 From: git Date: Tue, 27 Aug 2013 14:46:06 +0100 Subject: [PATCH 322/629] by Justin_KleinKeane, joachim: Fixed output of Flag title on admin page. --- includes/flag.admin.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 926a993..5f668a6 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -88,7 +88,7 @@ function theme_flag_admin_listing($variables) { $permission = "flag $flag->name"; $roles = user_roles(FALSE, $permission); $row = array(); - $row[] = $flag->title . ' (' . t('Machine name: @name', array('@name' => $flag->name)) . ')'; + $row[] = check_plain($flag->title) . ' (' . t('Machine name: @name', array('@name' => $flag->name)) . ')'; if (count($flags) > 1) { $row[] = drupal_render($form['flags'][$flag->name]['weight']); } From 9143028e1c887dbeeaea732484ea6926eb90a545 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sat, 31 Aug 2013 15:27:57 +0100 Subject: [PATCH 323/629] Issue #2078451 by joachim: Fixed module .info config path for Flag Actions. --- flag_actions.info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag_actions.info b/flag_actions.info index 7fc0913..9f1403b 100644 --- a/flag_actions.info +++ b/flag_actions.info @@ -3,7 +3,7 @@ description = Execute actions on Flag events. core = 7.x dependencies[] = flag package = Flags -configure = admin/structure/webform/flags +configure = admin/structure/flags/actions files[] = flag.install files[] = flag_actions.module \ No newline at end of file From 32643f3f8501d0c916202d09d959062db17f3d0b Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Sun, 1 Sep 2013 00:14:44 +0100 Subject: [PATCH 324/629] Issue #2074505 by joachim: Fixed use of obsolete hook_flag() in Flag Actions module. --- flag_actions.module | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/flag_actions.module b/flag_actions.module index 6992c2b..f4c3aed 100644 --- a/flag_actions.module +++ b/flag_actions.module @@ -6,10 +6,17 @@ */ /** - * Implements hook_flag(). Trigger actions if any are available. + * Implements hook_flag_flag(). Trigger actions if any are available. */ -function flag_actions_flag($event, $flag, $entity_id, $account) { - flag_actions_do($event, $flag, $entity_id, $account); +function flag_actions_flag_flag($flag, $entity_id, $account, $flagging) { + flag_actions_do('flag', $flag, $entity_id, $account); +} + +/** + * Implements hook_flag_unflag(). Trigger actions if any are available. + */ +function flag_actions_flag_unflag($flag, $entity_id, $account, $flagging) { + flag_actions_do('unflag', $flag, $entity_id, $account); } /** From a9713fca1130383ef88a132f49d2b6b39525e48a Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Wed, 4 Sep 2013 08:30:17 +0100 Subject: [PATCH 325/629] Issue #2047869 by joachim: Fixed flag pseudofield not showing on flags that use flag_entity class. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 3881f60..0a94d2c 100644 --- a/flag.module +++ b/flag.module @@ -612,7 +612,7 @@ function flag_field_extra_fields() { $flags = flag_get_flags(); foreach ($flags as $name => $flag) { // Skip flags that aren't on entities. - if (!is_subclass_of($flag, 'flag_entity')) { + if (!($flag instanceof flag_entity)) { continue; } From e939df381c67129eda90290e5f8512a5b577a665 Mon Sep 17 00:00:00 2001 From: generalredneck Date: Wed, 4 Sep 2013 15:37:59 +0100 Subject: [PATCH 326/629] Issue #2077017 by generalredneck: Fixed Most Recent Update (7.x-3.1) Broke Rules Configurations. --- flag.rules.inc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/flag.rules.inc b/flag.rules.inc index 25a5ee6..23cefcc 100644 --- a/flag.rules.inc +++ b/flag.rules.inc @@ -168,6 +168,11 @@ function flag_rules_event_info() { */ function flag_rules_action_info() { $param_defaults = array( + 'flagging_user' => array( + 'type' => 'user', + 'label' => t('User on whose behalf to flag'), + 'description' => t('For non-global flags, this is the user on whose behalf to flag the object. In addition, if checked below, the access permissions to the flag are checked against this user.'), + ), 'permission_check' => array( 'type' => 'boolean', 'label' => t('Skip permission check'), @@ -199,7 +204,8 @@ function flag_rules_action_info() { 'label' => t('Trim newest flags'), 'description' => t('Checking this will trim the newest flags. This will prevent new flags once a limit is reached.'), ), - ) + $param_defaults, + 'permission_check' => $param_defaults['permission_check'], + ), 'group' => t('Flag'), 'access callback' => 'flag_rules_integration_access', ), @@ -268,11 +274,6 @@ function flag_rules_action_info() { 'access callback' => 'flag_rules_integration_access', ), ); - $param_defaults['flagging_user'] = array( - 'type' => 'user', - 'label' => t('User on whose behalf to flag'), - 'description' => t('For non-global flags, this is the user on whose behalf to flag the object. In addition, if checked below, the access permissions to the flag are checked against this user.'), - ); foreach (flag_get_types() as $type) { $entity_info = entity_get_info($type); $label = $entity_info['label']; From 94defd4ee8b434658900e770c8c1099038428e76 Mon Sep 17 00:00:00 2001 From: ShabanaBlackborder Date: Wed, 11 Sep 2013 06:32:15 +0100 Subject: [PATCH 327/629] Issue #2017557 by Shabana Blackborder: Fixed getInfo in .test should return untranslated strings. --- tests/flag.test | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/flag.test b/tests/flag.test index 7397890..8d67758 100644 --- a/tests/flag.test +++ b/tests/flag.test @@ -43,9 +43,9 @@ class FlagFlaggingCRUDTestCase extends FlagTestCaseBase { */ public static function getInfo() { return array( - 'name' => t('Flagging CRUD'), - 'description' => t('Basic CRUD operations on flagging entities.'), - 'group' => t('Flag'), + 'name' => 'Flagging CRUD', + 'description' => 'Basic CRUD operations on flagging entities.', + 'group' => 'Flag', ); } @@ -223,9 +223,9 @@ class FlagAdminTestCase extends FlagTestCaseBase { */ public static function getInfo() { return array( - 'name' => t('Flag admin tests'), - 'description' => t('Add, edit and delete flags.'), - 'group' => t('Flag'), + 'name' => 'Flag admin tests', + 'description' => 'Add, edit and delete flags.', + 'group' => 'Flag', ); } @@ -377,9 +377,9 @@ class FlagAccessFormTestCase extends FlagTestCaseBase { */ public static function getInfo() { return array( - 'name' => t('Flag access: entity forms'), - 'description' => t('Access to flag and unflag entities via entity forms.'), - 'group' => t('Flag'), + 'name' => 'Flag access: entity forms', + 'description' => 'Access to flag and unflag entities via entity forms.', + 'group' => 'Flag', ); } @@ -473,9 +473,9 @@ class FlagAccessLinkTestCase extends FlagTestCaseBase { */ public static function getInfo() { return array( - 'name' => t('Flag access tests'), - 'description' => t('Access to flag and unflag entities using the basic link.'), - 'group' => t('Flag'), + 'name' => 'Flag access tests', + 'description' => 'Access to flag and unflag entities using the basic link.', + 'group' => 'Flag', ); } @@ -599,9 +599,9 @@ class FlagLinkTypeConfirmTestCase extends DrupalWebTestCase { */ public static function getInfo() { return array( - 'name' => t('Flag confirm link tests'), - 'description' => t('Flag confirm form link type.'), - 'group' => t('Flag'), + 'name' => 'Flag confirm link tests', + 'description' => 'Flag confirm form link type.', + 'group' => 'Flag', ); } @@ -723,9 +723,9 @@ class FlagHookFlagAccessTestCase extends FlagTestCaseBase { */ public static function getInfo() { return array( - 'name' => t('Flag hook_flag_access() tests'), - 'description' => t('Checks the ability of modules to use hook_flag_access().'), - 'group' => t('Flag'), + 'name' => 'Flag hook_flag_access() tests', + 'description' => 'Checks the ability of modules to use hook_flag_access().', + 'group' => 'Flag', ); } @@ -880,9 +880,9 @@ class FlagEntityFieldQueryTestCase extends FlagTestCaseBase { */ public static function getInfo() { return array( - 'name' => t('Flagging Entity Field Query Extension'), - 'description' => t('Entity Field Query for flagging entities.'), - 'group' => t('Flag'), + 'name' => 'Flagging Entity Field Query Extension', + 'description' => 'Entity Field Query for flagging entities.', + 'group' => 'Flag', ); } From 2991c22713fa8cce3809c61854cc23fff7709aa3 Mon Sep 17 00:00:00 2001 From: Joachim Noreiko Date: Thu, 12 Sep 2013 21:06:54 +0100 Subject: [PATCH 328/629] Issue #2087907 by joachim: Changed name of $flag_content variables to $flagging_data. --- flag.module | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/flag.module b/flag.module index 0a94d2c..77fce72 100644 --- a/flag.module +++ b/flag.module @@ -2013,8 +2013,8 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid ->condition('sid', $sid) ->execute(); - foreach ($result as $flag_content) { - $flagged_content[$uid][$sid][$entity_type][$entity_id][$flag_names[$flag_content->fid]] = $flag_content; + foreach ($result as $flagging_data) { + $flagged_content[$uid][$sid][$entity_type][$entity_id][$flag_names[$flagging_data->fid]] = $flagging_data; } } return $flagged_content[$uid][$sid][$entity_type][$entity_id]; @@ -2033,8 +2033,8 @@ function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid ) ->condition('sid', $sid) ->execute(); - foreach ($result as $flag_content) { - $flagged_content[$uid][$sid][$entity_type]['all'][$flag_names[$flag_content->fid]][$flag_content->entity_id] = $flag_content; + foreach ($result as $flagging_data) { + $flagged_content[$uid][$sid][$entity_type]['all'][$flag_names[$flagging_data->fid]][$flagging_data->entity_id] = $flagging_data; } } return $flagged_content[$uid][$sid][$entity_type]['all']; @@ -2071,11 +2071,11 @@ function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { ->orderBy('timestamp', 'DESC') ->execute(); $entity_flags[$entity_type][$entity_id] = array(); - foreach ($result as $flag_content) { + foreach ($result as $flagging_data) { // Build a list of flaggings for all flags by user. - $entity_flags[$entity_type][$entity_id]['users'][$flag_content->uid][$flag_names[$flag_content->fid]] = $flag_content; + $entity_flags[$entity_type][$entity_id]['users'][$flagging_data->uid][$flag_names[$flagging_data->fid]] = $flagging_data; // Build a list of flaggings for each individual flag. - $entity_flags[$entity_type][$entity_id]['flags'][$flag_names[$flag_content->fid]][$flag_content->uid] = $flag_content; + $entity_flags[$entity_type][$entity_id]['flags'][$flag_names[$flagging_data->fid]][$flagging_data->uid] = $flagging_data; } } if (empty($entity_flags[$entity_type][$entity_id])) { From 7661a43020244794a573b20e4e24a58535e140e9 Mon Sep 17 00:00:00 2001 From: Volx Date: Fri, 13 Sep 2013 10:05:50 +0100 Subject: [PATCH 329/629] Issue #1971980 by Volx: Fixed Features export not taking into account provision of flag types by flag_definition_alter(). --- includes/flag.features.inc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/includes/flag.features.inc b/includes/flag.features.inc index c61dc1b..9374930 100644 --- a/includes/flag.features.inc +++ b/includes/flag.features.inc @@ -111,5 +111,14 @@ function flag_features_providing_module() { $modules[$key] = isset($value['module']) ? $value['module'] : $module; } } + + // Any entity type without a flag providing module will be provided by the + // flag module. + foreach (entity_get_info() as $entity_type => $entity) { + if (!isset($modules[$entity_type]) && empty($entity['configuration']) && $entity_type !== 'taxonomy_vocabulary') { + $modules[$entity_type] = 'flag'; + } + } + return $modules; } From 7a86ce02b67a96d4726a576b7f006ca8ceb1818f Mon Sep 17 00:00:00 2001 From: Tess Date: Wed, 25 Sep 2013 19:15:04 -0500 Subject: [PATCH 330/629] Converted *.info files to *.info.yml --- flag.info => flag.info.yml | 0 flag_bookmark/{flag_bookmark.info => flag_bookmark.info.yml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename flag.info => flag.info.yml (100%) rename flag_bookmark/{flag_bookmark.info => flag_bookmark.info.yml} (100%) diff --git a/flag.info b/flag.info.yml similarity index 100% rename from flag.info rename to flag.info.yml diff --git a/flag_bookmark/flag_bookmark.info b/flag_bookmark/flag_bookmark.info.yml similarity index 100% rename from flag_bookmark/flag_bookmark.info rename to flag_bookmark/flag_bookmark.info.yml From 3baea7ef19494fa3e149944610991d546115397f Mon Sep 17 00:00:00 2001 From: Tess Date: Wed, 25 Sep 2013 19:17:02 -0500 Subject: [PATCH 331/629] Converted get_t() in flag.install to just t(), see: https://drupal.org/node/2021435 --- flag.info.yml | 33 +++++----------------------- flag.install | 13 +++++------ flag_bookmark/flag_bookmark.info.yml | 12 +++++----- 3 files changed, 19 insertions(+), 39 deletions(-) diff --git a/flag.info.yml b/flag.info.yml index a718f39..7ee6475 100644 --- a/flag.info.yml +++ b/flag.info.yml @@ -1,27 +1,6 @@ -name = Flag -description = Create customized flags that users can set on entities. -core = 7.x -package = Flags -configure = admin/structure/flags - -; Files that contain classes. -; Flag classes -files[] = includes/flag/flag_flag.inc -files[] = includes/flag/flag_entity.inc -files[] = includes/flag/flag_node.inc -files[] = includes/flag/flag_comment.inc -files[] = includes/flag/flag_user.inc -files[] = includes/flag.cookie_storage.inc - -files[] = includes/flag.entity.inc -files[] = flag.rules.inc - -; Views -files[] = includes/views/flag_handler_argument_entity_id.inc -files[] = includes/views/flag_handler_field_ops.inc -files[] = includes/views/flag_handler_field_flagged.inc -files[] = includes/views/flag_handler_filter_flagged.inc -files[] = includes/views/flag_handler_sort_flagged.inc -files[] = includes/views/flag_handler_relationships.inc -files[] = includes/views/flag_plugin_argument_validate_flaggability.inc -files[] = tests/flag.test +name: Flag +description: Create customized flags that users can set on entities. +core: 8.x +type: module +package: Flags +configure: admin/structure/flags diff --git a/flag.install b/flag.install index 7a4cb9f..3f07700 100644 --- a/flag.install +++ b/flag.install @@ -224,15 +224,14 @@ function flag_uninstall() { */ function flag_requirements($phase) { $requirements = array(); - $t = get_t(); if ($phase == 'runtime') { if (module_exists('translation') && !module_exists('translation_helpers')) { $requirements['flag_translation'] = array( - 'title' => $t('Flag'), + 'title' => t('Flag'), 'severity' => REQUIREMENT_ERROR, - 'description' => $t('To have the flag module work with translations, you need to install and enable the Translation helpers module.'), - 'value' => $t('Translation helpers module not found.'), + 'description' => t('To have the flag module work with translations, you need to install and enable the Translation helpers module.'), + 'value' => t('Translation helpers module not found.'), ); } if (module_exists('session_api')) { @@ -245,10 +244,10 @@ function flag_requirements($phase) { $contents = file_get_contents('./robots.txt'); if (strpos($contents, $robots_string) === FALSE) { $requirements['flag_robots'] = array( - 'title' => $t('Flag robots.txt problem'), + 'title' => t('Flag robots.txt problem'), 'severity' => REQUIREMENT_WARNING, - 'description' => $t('Flag module may currently be used with anonymous users, however the robots.txt file does not exclude the "@flag-path" path, which may cause search engines to randomly flag and unflag content when they index the site. It is highly recommended to add "@robots-string" to your robots.txt file (located in the root of your Drupal installation).', array('@flag-path' => $flag_path, '@robots-string' => $robots_string)), - 'value' => $t('Search engines flagging content'), + 'description' => t('Flag module may currently be used with anonymous users, however the robots.txt file does not exclude the "@flag-path" path, which may cause search engines to randomly flag and unflag content when they index the site. It is highly recommended to add "@robots-string" to your robots.txt file (located in the root of your Drupal installation).', array('@flag-path' => $flag_path, '@robots-string' => $robots_string)), + 'value' => t('Search engines flagging content'), ); } } diff --git a/flag_bookmark/flag_bookmark.info.yml b/flag_bookmark/flag_bookmark.info.yml index 6c16066..d5babcc 100644 --- a/flag_bookmark/flag_bookmark.info.yml +++ b/flag_bookmark/flag_bookmark.info.yml @@ -1,5 +1,7 @@ -name = Flag Bookmark -description = Provides an example bookmark flag and supporting views. -core = 7.x -dependencies[] = flag -package = Flags +name: Flag Bookmark +description: Provides an example bookmark flag and supporting views. +core: 8.x +type: module +dependencies: + - flag +package: Flags From ad2965d73da6887d8c82b3afce66f6e4dd57684a Mon Sep 17 00:00:00 2001 From: Tess Date: Fri, 27 Sep 2013 10:07:43 -0500 Subject: [PATCH 332/629] Converted flag_* to PSR-0 standard --- flag.flag.inc | 8 ++++---- flag.module | 14 +++++++------- includes/flag.admin.inc | 9 ++++++--- .../Drupal/flag/Handlers/AbstractFlag.php | 18 ++++-------------- lib/Drupal/flag/Handlers/BrokenFlag.php | 19 +++++++++++++++++++ .../Drupal/flag/Handlers/CommentFlag.php | 4 +++- .../Drupal/flag/Handlers/Flag.php | 15 +++++++++------ .../Drupal/flag/Handlers/NodeFlag.php | 4 +++- .../Drupal/flag/Handlers/UserFlag.php | 4 +++- 9 files changed, 58 insertions(+), 37 deletions(-) rename includes/flag/flag_flag.inc => lib/Drupal/flag/Handlers/AbstractFlag.php (99%) create mode 100644 lib/Drupal/flag/Handlers/BrokenFlag.php rename includes/flag/flag_comment.inc => lib/Drupal/flag/Handlers/CommentFlag.php (97%) rename includes/flag/flag_entity.inc => lib/Drupal/flag/Handlers/Flag.php (95%) rename includes/flag/flag_node.inc => lib/Drupal/flag/Handlers/NodeFlag.php (98%) rename includes/flag/flag_user.inc => lib/Drupal/flag/Handlers/UserFlag.php (97%) diff --git a/flag.flag.inc b/flag.flag.inc index 242ab77..695a800 100644 --- a/flag.flag.inc +++ b/flag.flag.inc @@ -20,12 +20,12 @@ function flag_flag_type_info() { 'node' => array( 'title' => t('Nodes'), 'description' => t("Nodes are a Drupal site's primary content."), - 'handler' => 'flag_node', + 'handler' => '\Drupal\flag\Handlers\NodeFlag', ), 'user' => array( 'title' => t('Users'), 'description' => t('Users who have created accounts on your site.'), - 'handler' => 'flag_user', + 'handler' => '\Drupal\flag\Handlers\UserFlag', ), ); @@ -33,7 +33,7 @@ function flag_flag_type_info() { $definitions['comment'] = array( 'title' => t('Comments'), 'description' => t('Comments are responses to node content.'), - 'handler' => 'flag_comment', + 'handler' => '\Drupal\flag\Handlers\CommentFlag', 'module' => 'comment', ); } @@ -42,7 +42,7 @@ function flag_flag_type_info() { $definitions['taxonomy_term'] = array( 'title' => t('Taxonomy Terms'), 'description' => t('Taxonomy terms are used to categorize content.'), - 'handler' => 'flag_entity', + 'handler' => '\Drupal\flag\Handlers\Flag', 'module' => 'taxonomy', ); } diff --git a/flag.module b/flag.module index 77fce72..f486bce 100644 --- a/flag.module +++ b/flag.module @@ -488,14 +488,14 @@ function flag_hook_info() { function flag_fetch_definition($entity_type = NULL) { $definitions = &drupal_static(__FUNCTION__); if (!isset($definitions)) { - if ($cache = cache_get('flag_type_info')) { + if ($cache = cache()->get('flag_type_info')) { $definitions = $cache->data; } else { $definitions = module_invoke_all('flag_type_info'); drupal_alter('flag_type_info', $definitions); - cache_set('flag_type_info', $definitions); + cache()->set('flag_type_info', $definitions); } } @@ -534,7 +534,7 @@ function flag_get_types() { * entity type property could not be found in the flag configuration data. * * @return - * A flag handler object. This may be the special class flag_broken is there is + * A flag handler object. This may be the special class BrokenFlag is there is * a problem with the flag. */ function flag_create_handler($entity_type) { @@ -543,7 +543,7 @@ function flag_create_handler($entity_type) { $handler = new $definition['handler']; } else { - $handler = new flag_broken; + $handler = new \Drupal\flag\Handlers\BrokenFlag(); } $handler->entity_type = $entity_type; $handler->construct(); @@ -2218,10 +2218,10 @@ function flag_get_link_types() { $link_types = &drupal_static(__FUNCTION__); if (!isset($link_types)) { - if ($cache = cache_get('flag_link_type_info')) { + if ($cache = cache()->get('flag_link_type_info')) { $link_types = $cache->data; } - // In some rare edge cases cache_get() can return an empty result. If it + // In some rare edge cases cache()->get() can return an empty result. If it // does, we make sure to fetch the link types again. if (empty($link_types)) { $link_types = array(); @@ -2242,7 +2242,7 @@ function flag_get_link_types() { } drupal_alter('flag_link_type_info', $link_types); - cache_set('flag_link_type_info', $link_types); + cache()->set('flag_link_type_info', $link_types); } } diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 5f668a6..9724ff2 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -5,6 +5,9 @@ * Contains administrative pages for creating, editing, and deleting flags. */ +use Drupal\flag\Handlers\AbstractFlag; +use Drupal\flag\Handlers\BrokenFlag; + /** * Flag administration page. Display a list of existing flags. */ @@ -227,7 +230,7 @@ function theme_flag_admin_page($variables) { */ function flag_add_page($entity_type = NULL) { if (isset($entity_type)) { - $flag = flag_flag::factory_by_entity_type($entity_type); + $flag = \Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); // Mark the flag as new. $flag->is_new = TRUE; $type_info = flag_fetch_definition($entity_type); @@ -270,8 +273,8 @@ function flag_add_form($form, &$form_state) { } function flag_add_form_validate($form, &$form_state) { - $flag = flag_flag::factory_by_entity_type($form_state['values']['type']); - if (get_class($flag) == 'flag_broken') { + $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); + if (get_class($flag) == 'BrokenFlag') { form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); } } diff --git a/includes/flag/flag_flag.inc b/lib/Drupal/flag/Handlers/AbstractFlag.php similarity index 99% rename from includes/flag/flag_flag.inc rename to lib/Drupal/flag/Handlers/AbstractFlag.php index 071b148..66c9570 100644 --- a/includes/flag/flag_flag.inc +++ b/lib/Drupal/flag/Handlers/AbstractFlag.php @@ -2,11 +2,11 @@ /** * @file - * Contains the flag_flag class. - * Flag type classes use an object oriented style inspired by that - * of Views 2. + * Contains \Drupal\flag\Handlers\flag_flag */ +namespace Drupal\flag\Handlers; + /** * This abstract class represents a flag, or, in Views 2 terminology, "a handler". * @@ -37,7 +37,7 @@ * that can't be found, the special handler flag_broken. Finally, this calls * $flag->construct() on the new handler object. */ -class flag_flag { +class AbstractFlag { /** * The database ID. @@ -1539,13 +1539,3 @@ function _flag_url($path, $fragment = NULL, $absolute = TRUE) { return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); } } - -/** - * A dummy flag to be used where the real implementation can't be found. - */ -class flag_broken extends flag_flag { - function options_form(&$form) { - drupal_set_message(t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->entity_type)), 'error'); - $form = array(); - } -} diff --git a/lib/Drupal/flag/Handlers/BrokenFlag.php b/lib/Drupal/flag/Handlers/BrokenFlag.php new file mode 100644 index 0000000..0ea9d3e --- /dev/null +++ b/lib/Drupal/flag/Handlers/BrokenFlag.php @@ -0,0 +1,19 @@ + $this->entity_type)), 'error'); + $form = array(); + } +} diff --git a/includes/flag/flag_comment.inc b/lib/Drupal/flag/Handlers/CommentFlag.php similarity index 97% rename from includes/flag/flag_comment.inc rename to lib/Drupal/flag/Handlers/CommentFlag.php index 58b15fc..a0148dd 100644 --- a/includes/flag/flag_comment.inc +++ b/lib/Drupal/flag/Handlers/CommentFlag.php @@ -5,10 +5,12 @@ * Contains the flag_comment class. */ +namespace Drupal\flag\Handlers; + /** * Implements a comment flag. */ -class flag_comment extends flag_entity { +class CommentFlag extends Flag { function options() { $options = parent::options(); $options += array( diff --git a/includes/flag/flag_entity.inc b/lib/Drupal/flag/Handlers/Flag.php similarity index 95% rename from includes/flag/flag_entity.inc rename to lib/Drupal/flag/Handlers/Flag.php index 5114213..f659049 100644 --- a/includes/flag/flag_entity.inc +++ b/lib/Drupal/flag/Handlers/Flag.php @@ -2,13 +2,15 @@ /** * @file - * Contains the flag_entity class. + * Contains the Flag class. */ +namespace Drupal\flag\Handlers; + /** * Base entity flag handler. */ -class flag_entity extends flag_flag { +class Flag extends AbstractFlag { /** * Adds additional options that are common for all entity types. */ @@ -36,9 +38,9 @@ function options() { */ function options_form(&$form) { $bundles = array(); - $entity_info = entity_get_info($this->entity_type); - foreach ($entity_info['bundles'] as $bundle_key => $bundle) { - $bundles[$bundle_key] = check_plain($bundle['label']); + $bundle_info = entity_get_bundles($this->entity_type); + foreach ($bundle_info as $bundle_key => $info) { + $bundles[$bundle_key] = $info['label']; } $form['access']['types'] = array( '#type' => 'checkboxes', @@ -51,7 +53,8 @@ function options_form(&$form) { // Add checkboxes to show flag link on each entity view mode. $options = array(); $defaults = array(); - foreach ($entity_info['view modes'] as $name => $view_mode) { + $view_modes = entity_get_view_modes($this->entity_type); + foreach ($view_modes as $name => $view_mode) { $options[$name] = t('Display on @name view mode', array('@name' => $view_mode['label'])); $defaults[$name] = !empty($this->show_in_links[$name]) ? $name : 0; } diff --git a/includes/flag/flag_node.inc b/lib/Drupal/flag/Handlers/NodeFlag.php similarity index 98% rename from includes/flag/flag_node.inc rename to lib/Drupal/flag/Handlers/NodeFlag.php index 1f087b8..18a5b7f 100644 --- a/includes/flag/flag_node.inc +++ b/lib/Drupal/flag/Handlers/NodeFlag.php @@ -5,10 +5,12 @@ * Contains the flag_node class. */ +namespace Drupal\flag\Handlers; + /** * Implements a node flag. */ -class flag_node extends flag_entity { +class NodeFlag extends Flag { function options() { $options = parent::options(); // Use own display settings in the meanwhile. diff --git a/includes/flag/flag_user.inc b/lib/Drupal/flag/Handlers/UserFlag.php similarity index 97% rename from includes/flag/flag_user.inc rename to lib/Drupal/flag/Handlers/UserFlag.php index 72dc201..e009c5c 100644 --- a/includes/flag/flag_user.inc +++ b/lib/Drupal/flag/Handlers/UserFlag.php @@ -5,10 +5,12 @@ * Contains the flag_user class. */ +namespace Drupal\flag\Handlers; + /** * Implements a user flag. */ -class flag_user extends flag_entity { +class UserFlag extends Flag { function options() { $options = parent::options(); $options += array( From bc76cb663e37a0b524443e936a58840faac2ec51 Mon Sep 17 00:00:00 2001 From: Tess Date: Sat, 28 Sep 2013 12:13:26 -0500 Subject: [PATCH 333/629] Implemented FlagAdminController --- flag.module | 6 +- flag.routing.yml | 6 ++ includes/flag.admin.inc | 2 + .../flag/Controller/FlagAdminController.php | 59 +++++++++++++++++++ lib/Drupal/flag/Handlers/AbstractFlag.php | 2 +- 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 flag.routing.yml create mode 100644 lib/Drupal/flag/Controller/FlagAdminController.php diff --git a/flag.module b/flag.module index f486bce..7648a03 100644 --- a/flag.module +++ b/flag.module @@ -10,6 +10,8 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); +use Drupal\flag\Handlers\AbstractFlag; + /** * Implements hook_entity_info(). */ @@ -178,6 +180,7 @@ function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { * Implements hook_menu(). */ function flag_menu() { + /* $items[FLAG_ADMIN_PATH] = array( 'title' => 'Flags', 'page callback' => 'flag_admin_page', @@ -187,6 +190,7 @@ function flag_menu() { 'file' => 'includes/flag.admin.inc', 'type' => MENU_NORMAL_ITEM, ); + */ $items[FLAG_ADMIN_PATH . '/list'] = array( 'title' => 'List', 'type' => MENU_DEFAULT_LOCAL_TASK, @@ -1827,7 +1831,7 @@ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = ->execute(); foreach ($result as $row) { if (!isset($flags[$row->name])) { - $flags[$row->name] = flag_flag::factory_by_row($row); + $flags[$row->name] = AbstractFlag::factory_by_row($row); } else { $flags[$row->name]->types[] = $row->type; diff --git a/flag.routing.yml b/flag.routing.yml new file mode 100644 index 0000000..cae70b2 --- /dev/null +++ b/flag.routing.yml @@ -0,0 +1,6 @@ +flag.settings: + path: 'admin/structure/flags' + defaults: + _content: '\Drupal\flag\Controller\FlagAdminController::content' + requirements: + _permission: 'administer flags' \ No newline at end of file diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 9724ff2..44d461d 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -11,6 +11,7 @@ use Drupal\flag\Handlers\BrokenFlag; /** * Flag administration page. Display a list of existing flags. */ +/* function flag_admin_page() { $flags = flag_get_flags(); $default_flags = flag_get_default_flags(TRUE); @@ -21,6 +22,7 @@ function flag_admin_page() { 'flag_admin_listing' => $flag_admin_listing, )); } +*/ /** * A form for ordering the weights of all the active flags in the system. diff --git a/lib/Drupal/flag/Controller/FlagAdminController.php b/lib/Drupal/flag/Controller/FlagAdminController.php new file mode 100644 index 0000000..7251a0f --- /dev/null +++ b/lib/Drupal/flag/Controller/FlagAdminController.php @@ -0,0 +1,59 @@ + $flags, 'default_flags' => $default_flags)); + + if (!module_exists('views')) { + $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; + } + else { + $output .= '

'; + $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', array('@views-url' => url('admin/structure/views'))); + if (flag_get_flag('bookmarks')) { + $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', array('@views-url' => url('admin/structure/views', array('query' => array('tag' => 'flag'))))); + } + $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', array('@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954')); + $output .= '

'; + } + + if (!module_exists('flag_actions')) { + $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules'))) . '

'; + } + else { + $output .= '

' . t('Flagging an item may trigger actions.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'))) . '

'; + } + + if (!module_exists('rules')) { + $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', array('@rules-url' => url('http://drupal.org/node/407070'))) . '

'; + } + else { + $output .= '

' . t('Flagging an item may trigger rules.', array('@rules-url' => url('admin/config/workflow/rules'))) . '

'; + } + + $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', array('@handbook-url' => 'http://drupal.org/handbook/modules/flag')) . '

'; + + return array( + '#type' => 'markup', + '#markup' => $output, + ); + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Handlers/AbstractFlag.php b/lib/Drupal/flag/Handlers/AbstractFlag.php index 66c9570..a43ebad 100644 --- a/lib/Drupal/flag/Handlers/AbstractFlag.php +++ b/lib/Drupal/flag/Handlers/AbstractFlag.php @@ -1287,7 +1287,7 @@ function save() { $this->is_new = TRUE; } // Clear the page cache for anonymous users. - cache_clear_all('*', 'cache_page', TRUE); + cache()->deleteTags(array('content' => TRUE)); } /** From 03166365e3d97709207d380ec193f6181f93ddbe Mon Sep 17 00:00:00 2001 From: Tess Date: Sun, 29 Sep 2013 16:34:59 -0500 Subject: [PATCH 334/629] Initial implementation of Flag add controllers. API not final yet: https://drupal.org/node/2077473 --- flag.module | 27 +- flag.routing.yml | 20 +- includes/flag.admin.inc | 20 +- lib/Drupal/flag/Form/FlagAddForm.php | 371 +++++++++++++++++++++++ lib/Drupal/flag/Form/FlagAddPageForm.php | 61 ++++ 5 files changed, 474 insertions(+), 25 deletions(-) create mode 100644 lib/Drupal/flag/Form/FlagAddForm.php create mode 100644 lib/Drupal/flag/Form/FlagAddPageForm.php diff --git a/flag.module b/flag.module index 7648a03..b9706c5 100644 --- a/flag.module +++ b/flag.module @@ -180,17 +180,12 @@ function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { * Implements hook_menu(). */ function flag_menu() { - /* + $items[FLAG_ADMIN_PATH] = array( 'title' => 'Flags', - 'page callback' => 'flag_admin_page', - 'access callback' => 'user_access', - 'access arguments' => array('administer flags'), + 'route_name' => 'flag_settings', 'description' => 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).', - 'file' => 'includes/flag.admin.inc', - 'type' => MENU_NORMAL_ITEM, ); - */ $items[FLAG_ADMIN_PATH . '/list'] = array( 'title' => 'List', 'type' => MENU_DEFAULT_LOCAL_TASK, @@ -198,13 +193,20 @@ function flag_menu() { ); $items[FLAG_ADMIN_PATH . '/add'] = array( 'title' => 'Add flag', - 'page callback' => 'flag_add_page', +/* 'page callback' => 'flag_add_page', 'access callback' => 'user_access', 'access arguments' => array('administer flags'), 'file' => 'includes/flag.admin.inc', - 'type' => MENU_LOCAL_ACTION, +*/ + 'route_name' => 'flag_add_page', + 'type' => MENU_SIBLING_LOCAL_TASK, 'weight' => 1, ); + $items[FLAG_ADMIN_PATH . '/add/%node_type'] = array( + 'title' => 'Flag Add', + 'route_name' => 'flag_add', + 'type' => MENU_CALLBACK, + ); $items[FLAG_ADMIN_PATH . '/import'] = array( 'title' => 'Import', 'page callback' => 'drupal_get_form', @@ -452,7 +454,9 @@ function flag_help($path, $arg) { } /** - * Implements hook_init(). + * Implements hook_init() + * + * @todo Figure out where Rules module, see https://drupal.org/node/1211396 */ function flag_init() { module_load_include('inc', 'flag', 'includes/flag.actions'); @@ -1004,8 +1008,7 @@ function flag_entity_delete($entity, $type) { return; } - list($id) = entity_extract_ids($type, $entity); - _flag_entity_delete($type, $id); + _flag_entity_delete($entity->entityType(), $entity->id()); } /** diff --git a/flag.routing.yml b/flag.routing.yml index cae70b2..dd3d2ec 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -1,6 +1,20 @@ -flag.settings: - path: 'admin/structure/flags' +flag_settings: + path: '/admin/structure/flags' defaults: _content: '\Drupal\flag\Controller\FlagAdminController::content' requirements: - _permission: 'administer flags' \ No newline at end of file + _permission: 'administer flags' + +flag_add_page: + path: '/admin/structure/flags/add' + defaults: + _form: '\Drupal\flag\Form\FlagAddPageForm' + requirements: + _permission: 'administer flags' + +flag_add: + path: '/admin/structure/flags/add/{entity_type}' + defaults: + _form: '\Drupal\flag\Form\FlagAddForm' + requirements: + _permission: 'administer flags' diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 44d461d..64fb23b 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -229,7 +229,7 @@ function theme_flag_admin_page($variables) { * * @see flag_add_form() * @see flag_form() - */ + *//* function flag_add_page($entity_type = NULL) { if (isset($entity_type)) { $flag = \Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); @@ -243,10 +243,10 @@ function flag_add_page($entity_type = NULL) { drupal_set_title(t('Select flag type')); return drupal_get_form('flag_add_form'); } - +*/ /** * Present a form for creating a new flag, setting the type of flag. - */ + *//* function flag_add_form($form, &$form_state) { $types = array(); foreach (flag_fetch_definition() as $type => $info) { @@ -284,10 +284,10 @@ function flag_add_form_validate($form, &$form_state) { function flag_add_form_submit($form, &$form_state) { $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type']; } - +*/ /** * Add/Edit flag page. - */ + *//* function flag_form($form, &$form_state, $flag) { $form['#flag'] = $flag; $form['#flag_name'] = $flag->name; @@ -564,7 +564,7 @@ function flag_form($form, &$form_state, $flag) { return $form; } - +*/ /** * FormAPI after_build function set states on link type options fieldsets. * @@ -635,7 +635,7 @@ function flag_form_locked_process($element, &$form_state, $form) { /** * Add/Edit flag form validate. - */ + *//* function flag_form_validate($form, &$form_state) { $form_state['values']['title'] = trim($form_state['values']['title']); $form_values = $form_state['values']; @@ -659,10 +659,10 @@ function flag_form_validate($form, &$form_state) { } } } - +*/ /** * Add/Edit flag form submit. - */ + *//* function flag_form_submit($form, &$form_state) { $flag = $form['#flag']; @@ -703,7 +703,7 @@ function flag_form_submit($form, &$form_state) { $form_state['redirect'] = FLAG_ADMIN_PATH; } - +*/ /** * Output the access options for roles in a table. */ diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php new file mode 100644 index 0000000..c1e5fe1 --- /dev/null +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -0,0 +1,371 @@ +is_new = TRUE; + $type_info = flag_fetch_definition($entity_type); + drupal_set_title(t('Add new @type flag', array('@type' => $type_info['title']))); + + + $form['#flag'] = $flag; + $form['#flag_name'] = $flag->name; + + $form['title'] = array( + '#type' => 'textfield', + '#title' => t('Title'), + '#default_value' => $flag->title, + '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), + '#maxlength' => 255, + '#required' => TRUE, + '#weight' => -3, + ); + + $form['name'] = array( + '#type' => 'machine_name', + '#title' => t('Machine name'), + '#default_value' => $flag->name, + '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), + '#maxlength' => 32, + '#weight' => -2, + '#machine_name' => array( + 'exists' => 'flag_get_flag', + 'source' => array('title'), + ), + ); + + $form['global'] = array( + '#type' => 'checkbox', + '#title' => t('Global flag'), + '#default_value' => $flag->global, + '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), + '#weight' => -1, + ); + // Don't allow the 'global' checkbox to be changed when flaggings exist: + // there are too many unpleasant consequences in either direction. + // @todo: Allow this, but with a confirmation form, assuming anyone actually + // needs this feature. + if (!empty($flag->fid) && flag_get_flag_counts($flag->name)) { + $form['global']['#disabled'] = TRUE; + $form['global']['#description'] .= '
' . t('This setting cannot be changed when flaggings exist for this flag.'); + } + + $form['messages'] = array( + '#type' => 'fieldset', + '#title' => t('Messages'), + ); + + $form['messages']['flag_short'] = array( + '#type' => 'textfield', + '#title' => t('Flag link text'), + '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), + '#description' => t('The text for the "flag this" link for this flag.'), + '#required' => TRUE, + ); + + $form['messages']['flag_long'] = array( + '#type' => 'textfield', + '#title' => t('Flag link description'), + '#default_value' => $flag->flag_long, + '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'), + ); + + $form['messages']['flag_message'] = array( + '#type' => 'textfield', + '#title' => t('Flagged message'), + '#default_value' => $flag->flag_message, + '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), + ); + + $form['messages']['unflag_short'] = array( + '#type' => 'textfield', + '#title' => t('Unflag link text'), + '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), + '#description' => t('The text for the "unflag this" link for this flag.'), + '#required' => TRUE, + ); + + $form['messages']['unflag_long'] = array( + '#type' => 'textfield', + '#title' => t('Unflag link description'), + '#default_value' => $flag->unflag_long, + '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'), + ); + + $form['messages']['unflag_message'] = array( + '#type' => 'textfield', + '#title' => t('Unflagged message'), + '#default_value' => $flag->unflag_message, + '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), + ); + + $form['messages']['tokens_help'] = array( + '#title' => t('Token replacement'), + '#type' => 'fieldset', + '#description' => + '

' . t('The above six texts may contain any of the tokens listed below. For example, "Flag link text" could be entered as:') . '

' . + theme('item_list', array( + 'items' => array( + t('Add <em>[node:title]</em> to your favorites'), + t('Add this [node:type] to your favorites'), + t('Vote for this proposal ([node:flag-vote-count] people have already done so)'), + ), + 'attributes' => array('class' => 'token-examples'), + )) . + '

' . t('These tokens will be replaced with the appropriate fields from the node (or user, or comment).') . '

' . + theme('flag_tokens_browser', array('types' => $flag->get_labels_token_types())), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $form['access'] = array( + '#type' => 'fieldset', + '#title' => t('Flag access'), + '#tree' => FALSE, + '#weight' => 10, + ); + + // Flag classes will want to override this form element. + $form['access']['types'] = array( + '#type' => 'checkboxes', + '#title' => t('Flaggable types'), + '#options' => array(), + '#default_value' => $flag->types, + '#description' => t('Check any sub-types that this flag may be used on.'), + '#required' => TRUE, + '#weight' => 10, + ); + + // Disabled access breaks checkboxes unless #value is hard coded. + if (!empty($flag->locked['types'])) { + $form['access']['types']['#value'] = $flag->types; + } + + // Load the user permissions into the flag. + if (isset($flag->fid)) { + $flag->fetch_roles(); + } + elseif (isset($flag->import_roles)) { + // Convert the roles data from old API 2 flags that have been run through + // the update system. + // @see FlagUpdate_2::update() + $flag->roles = $flag->import_roles; + } + else { + // For new flags, provide a reasonable default value. + $flag->roles = array( + 'flag' => array(DRUPAL_AUTHENTICATED_RID), + 'unflag' => array(DRUPAL_AUTHENTICATED_RID), + ); + } + + $form['access']['roles'] = array( + '#title' => t('Roles that may use this flag'), + '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), + '#theme' => 'flag_form_roles', + '#theme_wrappers' => array('form_element'), + '#weight' => -2, + '#attached' => array( + 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), + 'css' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.css'), + ), + ); + if (module_exists('session_api')) { + $form['access']['roles']['#description'] .= ' ' . t('Support for anonymous users is being provided by Session API.'); + } + else { + $form['access']['roles']['#description'] .= ' ' . t('Anonymous users may flag content if the Session API module is installed.'); + } + + $form['access']['roles']['flag'] = array( + '#type' => 'checkboxes', + '#options' => user_roles(!module_exists('session_api')), + '#default_value' => $flag->roles['flag'], + '#parents' => array('roles', 'flag'), + ); + $form['access']['roles']['unflag'] = array( + '#type' => 'checkboxes', + '#options' => user_roles(!module_exists('session_api')), + '#default_value' => $flag->roles['unflag'], + '#parents' => array('roles', 'unflag'), + ); + + $form['access']['unflag_denied_text'] = array( + '#type' => 'textfield', + '#title' => t('Unflag not allowed text'), + '#default_value' => $flag->unflag_denied_text, + '#description' => t('If a user is allowed to flag but not unflag, this text will be displayed after flagging. Often this is the past-tense of the link text, such as "flagged".'), + '#weight' => -1, + ); + + $form['display'] = array( + '#type' => 'fieldset', + '#title' => t('Display options'), + '#description' => t('Flags are usually controlled through links that allow users to toggle their behavior. You can choose how users interact with flags by changing options here. It is legitimate to have none of the following checkboxes ticked, if, for some reason, you wish to place the the links on the page yourself.', array('@placement-url' => 'http://drupal.org/node/295383')), + '#tree' => FALSE, + '#weight' => 20, + // @todo: Move flag_link_type_options_states() into controller? + '#after_build' => array('flag_link_type_options_states'), + ); + + $form['display']['link_type'] = array( + '#type' => 'radios', + '#title' => t('Link type'), + '#options' => _flag_link_type_options(), + // @todo: Move flag_check_link_types into controller? + '#after_build' => array('flag_check_link_types'), + '#default_value' => $flag->link_type, + // Give this a high weight so additions by the flag classes for entity- + // specific options go above. + '#weight' => 18, + '#attached' => array( + 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), + ), + '#attributes' => array( + 'class' => array('flag-link-options'), + ), + ); + // Add the descriptions to each ratio button element. These attach to the + // elements when FormAPI expands them. + foreach (_flag_link_type_descriptions() as $key => $description) { + $form['display']['link_type'][$key]['#description'] = $description; + } + + $form['display']['link_options_intro'] = array( + // This is a hack to allow a markup element to use FormAPI states. + // @see http://www.bywombats.com/blog/06-25-2011/using-containers-states-enabled-markup-form-elements + '#type' => 'container', + '#children' => '', + '#weight' => 20, + ); + + $form['display']['link_options_confirm'] = array( + '#type' => 'fieldset', + '#title' => t('Options for the "Confirmation form" link type'), + // Any "link type" provider module must put its settings fields inside + // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is + // the machine-name of the link type. This is necessary for the + // radiobutton's JavaScript dependency feature to work. + '#id' => 'link-options-confirm', + '#weight' => 21, + ); + + $form['display']['link_options_confirm']['flag_confirmation'] = array( + '#type' => 'textfield', + '#title' => t('Flag confirmation message'), + '#default_value' => isset($flag->flag_confirmation) ? $flag->flag_confirmation : '', + '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), + ); + + $form['display']['link_options_confirm']['unflag_confirmation'] = array( + '#type' => 'textfield', + '#title' => t('Unflag confirmation message'), + '#default_value' => isset($flag->unflag_confirmation) ? $flag->unflag_confirmation : '', + '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), + ); + + $form['actions'] = array( + '#type' => 'actions', + ); + + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save flag'), + // We put this button on the form before calling $flag->options_form() + // to give the flag handler a chance to remove it (e.g. flag_broken). + '#weight' => 999, + ); + + // Add our process handler to disable access to locked properties. + //@todo: Fix reference to flag_form_locked_process, or replace entirely. +// $form['#process'][] = 'flag_form_locked_process'; + + // Allow the flag handler to make additions and changes to the form. + // Note that the flag_broken handler will completely empty the form array! + $flag->options_form($form); + + return $form; + } + + public function validateForm(array &$form, array &$form_state) { + $form_state['values']['title'] = trim($form_state['values']['title']); + $form_values = $form_state['values']; + + if ($form_values['link_type'] == 'confirm') { + if (empty($form_values['flag_confirmation'])) { + form_set_error('flag_confirmation', t('A flag confirmation message is required when using the confirmation link type.')); + } + if (empty($form_values['unflag_confirmation'])) { + form_set_error('unflag_confirmation', t('An unflag confirmation message is required when using the confirmation link type.')); + } + } + + + $flag = $form['#flag']; + $flag->form_input($form_values); + $errors = $flag->validate(); + foreach ($errors as $field => $field_errors) { + foreach ($field_errors as $error) { + form_set_error($field, $error['message']); + } + } + } + + public function submitForm(array &$form, array &$form_state) { + $flag = $form['#flag']; + + $form_state['values']['title'] = trim($form_state['values']['title']); + $flag->form_input($form_state['values']); + + $flag->save(); + $flag->enable(); + drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); + // We clear caches more vigorously if the flag was new. + _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); + + // Save permissions. + // This needs to be done after the flag cache has been cleared, so that + // the new permissions are picked up by hook_permission(). + // This may need to move to the flag class when we implement extra permissions + // for different flag types: http://drupal.org/node/879988 + + // If the flag machine name as changed, clean up all the obsolete permissions. + if ($flag->name != $form['#flag_name']) { + $old_name = $form['#flag_name']; + $permissions = array("flag $old_name", "unflag $old_name"); + foreach (array_keys(user_roles()) as $rid) { + user_role_revoke_permissions($rid, $permissions); + } + } + + foreach (array_keys(user_roles(!module_exists('session_api'))) as $rid) { + // Create an array of permissions, based on the checkboxes element name. + $permissions = array( + "flag $flag->name" => $flag->roles['flag'][$rid], + "unflag $flag->name" => $flag->roles['unflag'][$rid], + ); + user_role_change_permissions($rid, $permissions); + } + // @todo: when we add database caching for flags we'll have to clear the + // cache again here. + + $form_state['redirect'] = FLAG_ADMIN_PATH; + } +} \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php new file mode 100644 index 0000000..31efe73 --- /dev/null +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -0,0 +1,61 @@ + $info) { + $types[$type] = $info['title'] . '
' . $info['description'] . '
'; + } + + $form['type'] = array( + '#type' => 'radios', + '#title' => t('Flag type'), + '#default_value' => 'node', + '#description' => t('The type of object this flag will affect. This cannot be changed once the flag is created.'), + '#required' => TRUE, + '#options' => $types, + ); + + $form['actions'] = array( + '#type' => 'actions', + ); + + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Continue'), + ); + + return $form; + } + + public function validateForm(array &$form, array &$form_state) { + $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); + if (get_class($flag) == 'BrokenFlag') { + form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); + } + } + + public function submitForm(array &$form, array &$form_state) { + $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type']; + } +} \ No newline at end of file From bad4accd9f467f04c638b7eaf0ec9a7950481ab8 Mon Sep 17 00:00:00 2001 From: Tess Date: Sun, 29 Sep 2013 20:50:11 -0500 Subject: [PATCH 335/629] Converted import form to controller. --- flag.module | 10 +-- flag.routing.yml | 7 ++ includes/flag.export.inc | 97 --------------------- lib/Drupal/flag/Form/FlagImportForm.php | 108 ++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 106 deletions(-) create mode 100644 lib/Drupal/flag/Form/FlagImportForm.php diff --git a/flag.module b/flag.module index b9706c5..42e2e09 100644 --- a/flag.module +++ b/flag.module @@ -193,11 +193,6 @@ function flag_menu() { ); $items[FLAG_ADMIN_PATH . '/add'] = array( 'title' => 'Add flag', -/* 'page callback' => 'flag_add_page', - 'access callback' => 'user_access', - 'access arguments' => array('administer flags'), - 'file' => 'includes/flag.admin.inc', -*/ 'route_name' => 'flag_add_page', 'type' => MENU_SIBLING_LOCAL_TASK, 'weight' => 1, @@ -209,10 +204,7 @@ function flag_menu() { ); $items[FLAG_ADMIN_PATH . '/import'] = array( 'title' => 'Import', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_import_form'), - 'access arguments' => array('use flag import'), - 'file' => 'includes/flag.export.inc', + 'route_name' => 'flag_import', 'type' => MENU_LOCAL_TASK, 'weight' => 2, ); diff --git a/flag.routing.yml b/flag.routing.yml index dd3d2ec..caac053 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -18,3 +18,10 @@ flag_add: _form: '\Drupal\flag\Form\FlagAddForm' requirements: _permission: 'administer flags' + +flag_import: + path: '/admin/structure/flags/import' + defaults: + _form: '\Drupal\flag\Form\FlagImportForm' + requirements: + _permission: 'use flag import' \ No newline at end of file diff --git a/includes/flag.export.inc b/includes/flag.export.inc index 539899c..b8d1af9 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -71,103 +71,6 @@ function flag_export_flags($flags = array(), $module = '', $indent = '') { return $output; } -/** - * Form to import a flag. - */ -function flag_import_form() { - $form = array(); - - $form['import'] = array( - '#title' => t('Flag import code'), - '#type' => 'textarea', - '#default_value' => '', - '#rows' => 15, - '#required' => TRUE, - '#description' => t('Paste the code from a flag export here to import it into you site. Flags imported with the same name will update existing flags. Flags with a new name will be created.', array('@export-url' => url(FLAG_ADMIN_PATH . '/export'))), - ); - $form['submit'] = array( - '#value' => t('Import'), - '#type' => 'submit', - ); - - return $form; -} - -/** - * Validate handler; Import a flag. - */ -function flag_import_form_validate($form, &$form_state) { - $flags = array(); - ob_start(); - eval($form_state['values']['import']); - ob_end_clean(); - - if (!isset($flags) || !is_array($flags)) { - form_set_error('import', t('A valid list of flags could not be found in the import code.')); - return; - } - - // Create the flag object. - foreach ($flags as $flag_name => $flag_info) { - // Backward compatibility: old exported flags have their names in $flag_info - // instead, so we use the += operator to not overwrite it. - $flag_info += array( - 'name' => $flag_name, - ); - $new_flag = flag_flag::factory_by_array($flag_info); - - // Give new flags with the same name a matching FID, which tells Flag to - // update the existing flag, rather than creating a new one. - if ($existing_flag = flag_get_flag($new_flag->name)) { - $new_flag->fid = $existing_flag->fid; - } - - if ($errors = $new_flag->validate()) { - $message = t('The import of the %flag flag failed because the following errors were encountered during the import:', array('%flag' => $new_flag->name)); - $message_errors = array(); - foreach ($errors as $field => $field_errors) { - foreach ($field_errors as $error) { - $message_errors[] = $error['message']; - } - } - form_set_error('import', $message . theme('item_list', array('items' => $message_errors))); - } - else { - // Save the new flag for the submit handler. - $form_state['flags'][] = $new_flag; - } - } -} - -/** - * Submit handler; Import a flag. - */ -function flag_import_form_submit($form, &$form_state) { - module_load_include('inc', 'flag', 'includes/flag.admin'); - - // Build up values for the cache clear. - $entity_types = array(); - $new = FALSE; - - foreach ($form_state['flags'] as $flag) { - $flag->save(); - if (!empty($flag->status)) { - $flag->enable(); - } - if ($flag->is_new) { - drupal_set_message(t('Flag @name has been imported.', array('@name' => $flag->name))); - $new = TRUE; - } - else { - drupal_set_message(t('Flag @name has been updated.', array('@name' => $flag->name))); - } - $entity_types[] = $flag->entity_type; - } - _flag_clear_cache($entity_types, $new); - - $form_state['redirect'] = FLAG_ADMIN_PATH; -} - /** * Export a flag and display it in a form. */ diff --git a/lib/Drupal/flag/Form/FlagImportForm.php b/lib/Drupal/flag/Form/FlagImportForm.php new file mode 100644 index 0000000..3b20956 --- /dev/null +++ b/lib/Drupal/flag/Form/FlagImportForm.php @@ -0,0 +1,108 @@ + t('Flag import code'), + '#type' => 'textarea', + '#default_value' => '', + '#rows' => 15, + '#required' => TRUE, + '#description' => t('Paste the code from a flag export here to import it into you site. Flags imported with the same name will update existing flags. Flags with a new name will be created.', array('@export-url' => url(FLAG_ADMIN_PATH . '/export'))), + ); + $form['submit'] = array( + '#value' => t('Import'), + '#type' => 'submit', + ); + + return $form; + } + + public function validateForm(array &$form, array &$form_state) { + $flags = array(); + ob_start(); + eval($form_state['values']['import']); + ob_end_clean(); + + if (!isset($flags) || !is_array($flags)) { + form_set_error('import', t('A valid list of flags could not be found in the import code.')); + return; + } + + // Create the flag object. + foreach ($flags as $flag_name => $flag_info) { + // Backward compatibility: old exported flags have their names in $flag_info + // instead, so we use the += operator to not overwrite it. + $flag_info += array( + 'name' => $flag_name, + ); + $new_flag = AbstractFlag::factory_by_array($flag_info); + + // Give new flags with the same name a matching FID, which tells Flag to + // update the existing flag, rather than creating a new one. + if ($existing_flag = flag_get_flag($new_flag->name)) { + $new_flag->fid = $existing_flag->fid; + } + + if ($errors = $new_flag->validate()) { + $message = t('The import of the %flag flag failed because the following errors were encountered during the import:', array('%flag' => $new_flag->name)); + $message_errors = array(); + foreach ($errors as $field => $field_errors) { + foreach ($field_errors as $error) { + $message_errors[] = $error['message']; + } + } + form_set_error('import', $message . theme('item_list', array('items' => $message_errors))); + } + else { + // Save the new flag for the submit handler. + $form_state['flags'][] = $new_flag; + } + } + } + + public function submitForm(array &$form, array &$form_state) { + module_load_include('inc', 'flag', 'includes/flag.admin'); + + // Build up values for the cache clear. + $entity_types = array(); + $new = FALSE; + + foreach ($form_state['flags'] as $flag) { + $flag->save(); + if (!empty($flag->status)) { + $flag->enable(); + } + if ($flag->is_new) { + drupal_set_message(t('Flag @name has been imported.', array('@name' => $flag->name))); + $new = TRUE; + } + else { + drupal_set_message(t('Flag @name has been updated.', array('@name' => $flag->name))); + } + $entity_types[] = $flag->entity_type; + } + _flag_clear_cache($entity_types, $new); + + $form_state['redirect'] = FLAG_ADMIN_PATH; + } + +} \ No newline at end of file From 3758a0c111e9bb92896e6c4b7968dd47bc2f02bd Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 2 Oct 2013 09:13:04 -0700 Subject: [PATCH 336/629] Initial commit --- LICENSE | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 4 + 2 files changed, 343 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..28fa40b --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Github sandbox for the Drupal 8 version of Flag module + Copyright (C) 2013 socketwench + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..de4f188 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +flag-drupal8 +============ + +Github sandbox for the Drupal 8 version of Flag module From 2fa87b8b9ea1cb1f6a06921d869185b16098eab6 Mon Sep 17 00:00:00 2001 From: Tess Date: Thu, 3 Oct 2013 19:16:29 -0500 Subject: [PATCH 337/629] Made FlagUpdate classes PSR-0 compatable. --- flag.routing.yml | 9 +- includes/flag.export.inc | 143 ------------------------ lib/Drupal/flag/Export/FlagUpdate_2.php | 40 +++++++ lib/Drupal/flag/Export/FlagUpdate_3.php | 58 ++++++++++ lib/Drupal/flag/Form/FlagExportForm.php | 78 +++++++++++++ 5 files changed, 184 insertions(+), 144 deletions(-) create mode 100644 lib/Drupal/flag/Export/FlagUpdate_2.php create mode 100644 lib/Drupal/flag/Export/FlagUpdate_3.php create mode 100644 lib/Drupal/flag/Form/FlagExportForm.php diff --git a/flag.routing.yml b/flag.routing.yml index caac053..d47f4c2 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -24,4 +24,11 @@ flag_import: defaults: _form: '\Drupal\flag\Form\FlagImportForm' requirements: - _permission: 'use flag import' \ No newline at end of file + _permission: 'use flag import' + +flag_export: + path: '/admin/structure/flags/export' + defaults: + _form: '\Drupal\flag\Form\FlagExportForm' + requirements: + _permission: 'use flag import' diff --git a/includes/flag.export.inc b/includes/flag.export.inc index b8d1af9..9285722 100644 --- a/includes/flag.export.inc +++ b/includes/flag.export.inc @@ -71,65 +71,6 @@ function flag_export_flags($flags = array(), $module = '', $indent = '') { return $output; } -/** - * Export a flag and display it in a form. - */ -function flag_export_form($form, &$form_state, $flag = NULL) { - // If we were passed a flag, use it as the list of flags to export. - if ($flag) { - $flags = array($flag); - } - - // Display a list of flags to export. - if (!isset($flags)) { - if (isset($form_state['values']['flags'])) { - $flags = array(); - foreach ($form_state['values']['flags'] as $flag_name) { - if ($flag_name && $flag = flag_get_flag($flag_name)) { - $flags[] = $flag; - } - } - } - else { - $form['flags'] = array( - '#type' => 'checkboxes', - '#title' => t('Flags to export'), - '#options' => drupal_map_assoc(array_keys(flag_get_flags())), - '#description' => t('Exporting your flags is useful for moving flags from one site to another, or when including your flag definitions in a module.'), - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Export'), - ); - } - } - - if (isset($flags)) { - $code = flag_export_flags($flags); - - // Link to the Features page if module is present, otherwise link to the - // Drupal project page. - $features_link = module_exists('features') ? url('admin/build/features') : url('http://drupal.org/project/features'); - - $form['export'] = array( - '#type' => 'textarea', - '#title' => t('Flag exports'), - '#description' => t('Use the exported code to later import it. Exports can be included in modules using hook_flag_default_flags() or using the Features module.', array('@import-flag' => url(FLAG_ADMIN_PATH . '/import'), '@features-url' => $features_link)), - '#value' => $code, - '#rows' => 15, - ); - } - - return $form; -} - -/** - * Submit handler; Rebuild the export form after the list of flags has been set. - */ -function flag_export_form_submit($form, &$form_state) { - $form_state['rebuild'] = TRUE; -} - /** * Page for displaying an upgrade message and export form for Flag 1.x flags. */ @@ -195,87 +136,3 @@ function flag_update_export(&$flag) { $flag->api_version = $update_handler->new_api_version; } } - -/** - * Flag update class for API 1 flags -> API 2. - * - * The class name after the prefix is immaterial, though we follow the Drupal - * system update convention whereby the number here is what we update to. - */ -class FlagUpdate_2 { - - /** - * The API version this class updates a flag from. - * - * @todo: Change this to a class constant when we drop support for PHP 5.2. - */ - public $old_api_version = 1; - - /** - * The API version this class updates a flag to. - */ - public $new_api_version = 2; - - /** - * The update function for the flag. - */ - static function update(&$flag) { - if (isset($flag->roles) && !isset($flag->roles['flag'])) { - $flag->roles = array( - 'flag' => $flag->roles, - 'unflag' => $flag->roles, - ); - } - } -} - -/** - * Flag update class for API 2 flags -> API 3. - */ -class FlagUpdate_3 { - - public $old_api_version = 2; - public $new_api_version = 3; - - static function update(&$flag) { - // Change the content_type property to entity_type. - if (isset($flag->content_type)) { - $flag->entity_type = $flag->content_type; - unset($flag->content_type); - } - - // We can't convert the flag roles data to user permissions at this point - // because the flag is disabled and hence hook_permission() doesn't see it - // to define its permissions. - // Instead, we copy it to import_roles, which the flag add form will handle - // on new flags (which this flag will behave as when it is re-enabled). - // @see flag_form() - if (isset($flag->roles)) { - $flag->import_roles = $flag->roles; - } - - // Update show_on_teaser property to use new view mode settings. - if (!empty($flag->show_on_teaser)) { - $flag->show_in_links['teaser'] = TRUE; - unset($flag->show_on_teaser); - } - - // Update show_on_page property to use new view mode settings. - if (!empty($flag->show_on_page)) { - $flag->show_in_links['full'] = TRUE; - unset($flag->show_on_page); - } - - // Update show_on_comment and show_on_entity properties to use new view - // mode settings. Since the old logic was to show on all view modes, do that. - if (!empty($flag->show_on_entity) || !empty($flag->show_on_comment)) { - if ($entity_info = entity_get_info($flag->entity_type)) { - foreach ($entity_info['view modes'] as $view_mode => $value) { - $flag->show_in_links[$view_mode] = TRUE; - } - } - - unset($flag->show_on_entity, $flag->show_on_comment); - } - } -} diff --git a/lib/Drupal/flag/Export/FlagUpdate_2.php b/lib/Drupal/flag/Export/FlagUpdate_2.php new file mode 100644 index 0000000..39dd989 --- /dev/null +++ b/lib/Drupal/flag/Export/FlagUpdate_2.php @@ -0,0 +1,40 @@ + API 2. + * + * The class name after the prefix is immaterial, though we follow the Drupal + * system update convention whereby the number here is what we update to. + */ +class FlagUpdate_2 { + + /** + * The API version this class updates a flag from. + * + * @todo: Change this to a class constant when we drop support for PHP 5.2. + */ + public $old_api_version = 1; + + /** + * The API version this class updates a flag to. + */ + public $new_api_version = 2; + + /** + * The update function for the flag. + */ + static function update(&$flag) { + if (isset($flag->roles) && !isset($flag->roles['flag'])) { + $flag->roles = array( + 'flag' => $flag->roles, + 'unflag' => $flag->roles, + ); + } + } +} \ No newline at end of file diff --git a/lib/Drupal/flag/Export/FlagUpdate_3.php b/lib/Drupal/flag/Export/FlagUpdate_3.php new file mode 100644 index 0000000..4951c70 --- /dev/null +++ b/lib/Drupal/flag/Export/FlagUpdate_3.php @@ -0,0 +1,58 @@ + API 3. + */ +class FlagUpdate_3 { + + public $old_api_version = 2; + public $new_api_version = 3; + + static function update(&$flag) { + // Change the content_type property to entity_type. + if (isset($flag->content_type)) { + $flag->entity_type = $flag->content_type; + unset($flag->content_type); + } + + // We can't convert the flag roles data to user permissions at this point + // because the flag is disabled and hence hook_permission() doesn't see it + // to define its permissions. + // Instead, we copy it to import_roles, which the flag add form will handle + // on new flags (which this flag will behave as when it is re-enabled). + // @see flag_form() + if (isset($flag->roles)) { + $flag->import_roles = $flag->roles; + } + + // Update show_on_teaser property to use new view mode settings. + if (!empty($flag->show_on_teaser)) { + $flag->show_in_links['teaser'] = TRUE; + unset($flag->show_on_teaser); + } + + // Update show_on_page property to use new view mode settings. + if (!empty($flag->show_on_page)) { + $flag->show_in_links['full'] = TRUE; + unset($flag->show_on_page); + } + + // Update show_on_comment and show_on_entity properties to use new view + // mode settings. Since the old logic was to show on all view modes, do that. + if (!empty($flag->show_on_entity) || !empty($flag->show_on_comment)) { + if ($entity_info = entity_get_info($flag->entity_type)) { + foreach ($entity_info['view modes'] as $view_mode => $value) { + $flag->show_in_links[$view_mode] = TRUE; + } + } + + unset($flag->show_on_entity, $flag->show_on_comment); + } + } +} \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagExportForm.php b/lib/Drupal/flag/Form/FlagExportForm.php new file mode 100644 index 0000000..93acc6b --- /dev/null +++ b/lib/Drupal/flag/Form/FlagExportForm.php @@ -0,0 +1,78 @@ + 'checkboxes', + '#title' => t('Flags to export'), + '#options' => drupal_map_assoc(array_keys(flag_get_flags())), + '#description' => t('Exporting your flags is useful for moving flags from one site to another, or when including your flag definitions in a module.'), + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Export'), + ); + } + } + + // @todo: Move to another controller + if (isset($flags)) { + $code = flag_export_flags($flags); + + // Link to the Features page if module is present, otherwise link to the + // Drupal project page. + $features_link = module_exists('features') ? url('admin/build/features') : url('http://drupal.org/project/features'); + + $form['export'] = array( + '#type' => 'textarea', + '#title' => t('Flag exports'), + '#description' => t('Use the exported code to later import it. Exports can be included in modules using hook_flag_default_flags() or using the Features module.', array('@import-flag' => url(FLAG_ADMIN_PATH . '/import'), '@features-url' => $features_link)), + '#value' => $code, + '#rows' => 15, + ); + } + + return $form; + + } + + public function submitForm(array &$form, array &$form_state) { + $form_state['rebuild'] = TRUE; + } + +} \ No newline at end of file From 3581dcc3f66b419f1500a13a7afe0ac83354c1e1 Mon Sep 17 00:00:00 2001 From: Tess Date: Sat, 12 Oct 2013 23:41:01 -0500 Subject: [PATCH 338/629] Initial creation of Flag config entity, and flag type plugin. --- flag.routing.yml | 7 +++ flag.services.yml | 4 ++ lib/Drupal/flag/Annotation/Flag.php | 47 ++++++++++++++ .../flag/Controller/FlagListController.php | 35 +++++++++++ lib/Drupal/flag/Entity/Flag.php | 63 +++++++++++++++++++ lib/Drupal/flag/FlagInterface.php | 17 +++++ lib/Drupal/flag/FlagPluginManager.php | 38 +++++++++++ .../flag/Plugin/Derivative/FlagBase.php | 44 +++++++++++++ lib/Drupal/flag/Plugin/Flag/FlagBase.php | 31 +++++++++ lib/Drupal/flag/config/schema/flag.schema.yml | 13 ++++ 10 files changed, 299 insertions(+) create mode 100644 flag.services.yml create mode 100644 lib/Drupal/flag/Annotation/Flag.php create mode 100644 lib/Drupal/flag/Controller/FlagListController.php create mode 100644 lib/Drupal/flag/Entity/Flag.php create mode 100644 lib/Drupal/flag/FlagInterface.php create mode 100644 lib/Drupal/flag/FlagPluginManager.php create mode 100644 lib/Drupal/flag/Plugin/Derivative/FlagBase.php create mode 100644 lib/Drupal/flag/Plugin/Flag/FlagBase.php create mode 100644 lib/Drupal/flag/config/schema/flag.schema.yml diff --git a/flag.routing.yml b/flag.routing.yml index d47f4c2..12d4cec 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -12,6 +12,13 @@ flag_add_page: requirements: _permission: 'administer flags' +flag.flag_list: + path: '/admin/structure/flagz/add' + defaults: + _entity_list: 'flag_flag' + requirements: + _permission: 'administer flags' + flag_add: path: '/admin/structure/flags/add/{entity_type}' defaults: diff --git a/flag.services.yml b/flag.services.yml new file mode 100644 index 0000000..191cf27 --- /dev/null +++ b/flag.services.yml @@ -0,0 +1,4 @@ +services: + plugin.manager.flag.flag: + class: Drupal\Flag\FlagPluginManager + arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] diff --git a/lib/Drupal/flag/Annotation/Flag.php b/lib/Drupal/flag/Annotation/Flag.php new file mode 100644 index 0000000..d739ee3 --- /dev/null +++ b/lib/Drupal/flag/Annotation/Flag.php @@ -0,0 +1,47 @@ +getLabel($entity); + + return $row + parent::buildRow($entity); + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php new file mode 100644 index 0000000..324214c --- /dev/null +++ b/lib/Drupal/flag/Entity/Flag.php @@ -0,0 +1,63 @@ +alterInfo($module_handler, 'tour_tips_info'); + $this->setCacheBackend($cache_backend, $language_manager, 'tour'); + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Derivative/FlagBase.php b/lib/Drupal/flag/Plugin/Derivative/FlagBase.php new file mode 100644 index 0000000..7e3f134 --- /dev/null +++ b/lib/Drupal/flag/Plugin/Derivative/FlagBase.php @@ -0,0 +1,44 @@ +flagStorage = $flag_storage; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('entity.manager')->getStorageController('flag') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions(array $base_plugin_definition) { + foreach ($this->flagStorage->loadMultiple() as $flag => $entity) { + $this->derivatives[$flag] = $base_plugin_definition; + $this->derivatives[$flag]['admin_label'] = $entity->label(); + $this->derivatives[$flag]['cache'] = DRUPAL_NO_CACHE; + } + return $this->derivatives; + } +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/FlagBase.php b/lib/Drupal/flag/Plugin/Flag/FlagBase.php new file mode 100644 index 0000000..e3df92e --- /dev/null +++ b/lib/Drupal/flag/Plugin/Flag/FlagBase.php @@ -0,0 +1,31 @@ + Date: Sun, 13 Oct 2013 19:55:13 -0500 Subject: [PATCH 339/629] Added more Flag entity fields to the class and schema. --- lib/Drupal/flag/Entity/Flag.php | 93 +++++++++++++++++++ lib/Drupal/flag/config/schema/flag.schema.yml | 35 ++++++- 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 324214c..b9478f2 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -53,6 +53,20 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $uuid; + /** + * The entity type this flag works with. + * + * @var string + */ + public $entity_type = NULL; + + /** + * The flag's "machine readable" name. + * + * @var string + */ + public $name = ''; + /** * The flag label. * @@ -60,4 +74,83 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $label; + /** + * Whether this flag state should act as a single toggle to all users. + * + * @var bool + */ + public $is_global = FALSE; + + /** + * The sub-types, AKA bundles, this flag applies to. + * + * This may be an empty array to indicate all types apply. + * + * @var array + */ + public $types = array(); + + /** + * The text for the "flag this" link for this flag. + * + * @var string + */ + public $flag_short = ''; + + /** + * The description of the "flag this" link. + * + * @var string + */ + public $flag_long = ''; + + /** + * Message displayed after flagging an entity. + * + * @var string + */ + public $flag_message = ''; + + /** + * The text for the "unflag this" link for this flag. + * + * @var string + */ + public $unflag_short = ''; + + /** + * The description of the "unflag this" link. + * + * @var string + */ + public $unflag_long = ''; + + /** + * Message displayed after flagging an entity. + * + * @var string + */ + public $unflag_message = ''; + + /** + * Message displayed if users aren't allowed to unflag. + * + * @var string + */ + public $unflag_denied_text = ''; + + /** + * The link type used by the flag, as defined in hook_flag_link_type_info(). + * + * @var string + */ + public $link_type = 'toggle'; //@todo Convert to plugin + + /** + * The weight of the flag. + * + * @var int + */ + public $weight = 0; + } \ No newline at end of file diff --git a/lib/Drupal/flag/config/schema/flag.schema.yml b/lib/Drupal/flag/config/schema/flag.schema.yml index d9df4d5..9bc3030 100644 --- a/lib/Drupal/flag/config/schema/flag.schema.yml +++ b/lib/Drupal/flag/config/schema/flag.schema.yml @@ -10,4 +10,37 @@ flag.flag.*: label: 'UUID' label: type: label - label: 'Label' \ No newline at end of file + label: 'Label' + is_global: + type: boolean + label: 'Is flag global' + flag_short: + type: string + label: 'Flag Link Text' + flag_long: + type: string + label: 'Flag Description' + flag_message: + type: string + label: 'Flag Message' + unflag_short: + type: string + label: 'Unflag Link Text' + unflag_long: + type: string + label: 'Unflag Description' + unflag_message: + type: string + label: 'Unflag Message' + unflag_denied_text: + type: string + label: 'Unflag Denied Text' + weight: + type: integer + label: 'Weight' +# link_type: +# type: sequence +# label: 'Link Type' +# sequence: +# - type: flag.link.[plugin] +# label: 'Flag Link Type's \ No newline at end of file From d67070c4f47f4d9d1f06bbb4b2bf14c8baa045e7 Mon Sep 17 00:00:00 2001 From: Tess Date: Mon, 14 Oct 2013 23:24:06 -0500 Subject: [PATCH 340/629] Converted FlagAddForm to an EntityFormController. --- flag.routing.yml | 2 +- lib/Drupal/flag/Entity/Flag.php | 6 +++ lib/Drupal/flag/Form/FlagAddForm.php | 69 ++++++++++++++++------------ 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index 12d4cec..a6f8acf 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -22,7 +22,7 @@ flag.flag_list: flag_add: path: '/admin/structure/flags/add/{entity_type}' defaults: - _form: '\Drupal\flag\Form\FlagAddForm' + _entity_form: flag_flag.add requirements: _permission: 'administer flags' diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index b9478f2..af22934 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -25,6 +25,12 @@ * controllers = { * "storage" = "Drupal\Core\Config\Entity\ConfigStorageController", * "list" = "Drupal\flag\Controller\FlagListController", + * "form" = { + * "add" = "Drupal\flag\Form\FlagAddForm", + * "edit" = "Drupal\flag\Form\FlagAddForm", + * "delete" = "Drupal\flag\Form\FlagAddForm" + * } + * }, * config_prefix = "flag.flag", * entity_keys = { diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index c1e5fe1..d23d043 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -8,21 +8,20 @@ namespace Drupal\flag\Form; -use Drupal\Core\Form\FormBase; +use Drupal\Core\Entity\EntityFormController; use Drupal\flag\Handlers\AbstractFlag; -class FlagAddForm extends FormBase{ +class FlagAddForm extends EntityFormController { - public function getFormID() { - return 'flag_add'; - } + public function form(array $form, array &$form_state, $entity_type = NULL) { + $form = parent::form($form, $form_state); + + $flag = $this->entity; //\Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); - public function buildForm(array $form, array &$form_state, $entity_type = NULL) { - $flag = \Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); // Mark the flag as new. $flag->is_new = TRUE; $type_info = flag_fetch_definition($entity_type); - drupal_set_title(t('Add new @type flag', array('@type' => $type_info['title']))); + // drupal_set_title(t('Add new @type flag', array('@type' => $type_info['title']))); $form['#flag'] = $flag; @@ -54,7 +53,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) $form['global'] = array( '#type' => 'checkbox', '#title' => t('Global flag'), - '#default_value' => $flag->global, + '#default_value' => $flag->is_global, '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), '#weight' => -1, ); @@ -62,7 +61,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) // there are too many unpleasant consequences in either direction. // @todo: Allow this, but with a confirmation form, assuming anyone actually // needs this feature. - if (!empty($flag->fid) && flag_get_flag_counts($flag->name)) { + if (!empty($flag->id) && flag_get_flag_counts($flag->name)) { $form['global']['#disabled'] = TRUE; $form['global']['#description'] .= '
' . t('This setting cannot be changed when flaggings exist for this flag.'); } @@ -115,7 +114,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#default_value' => $flag->unflag_message, '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), ); - +/* $form['messages']['tokens_help'] = array( '#title' => t('Token replacement'), '#type' => 'fieldset', @@ -134,7 +133,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#collapsible' => TRUE, '#collapsed' => TRUE, ); - +*/ $form['access'] = array( '#type' => 'fieldset', '#title' => t('Flag access'), @@ -152,14 +151,14 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#required' => TRUE, '#weight' => 10, ); - +/* // Disabled access breaks checkboxes unless #value is hard coded. if (!empty($flag->locked['types'])) { $form['access']['types']['#value'] = $flag->types; } // Load the user permissions into the flag. - if (isset($flag->fid)) { + if (isset($flag->id)) { $flag->fetch_roles(); } elseif (isset($flag->import_roles)) { @@ -175,7 +174,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) 'unflag' => array(DRUPAL_AUTHENTICATED_RID), ); } - +*/ $form['access']['roles'] = array( '#title' => t('Roles that may use this flag'), '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), @@ -197,13 +196,13 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) $form['access']['roles']['flag'] = array( '#type' => 'checkboxes', '#options' => user_roles(!module_exists('session_api')), - '#default_value' => $flag->roles['flag'], +// '#default_value' => $flag->roles['flag'], '#parents' => array('roles', 'flag'), ); $form['access']['roles']['unflag'] = array( '#type' => 'checkboxes', '#options' => user_roles(!module_exists('session_api')), - '#default_value' => $flag->roles['unflag'], +// '#default_value' => $flag->roles['unflag'], '#parents' => array('roles', 'unflag'), ); @@ -266,7 +265,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#id' => 'link-options-confirm', '#weight' => 21, ); - +/* $form['display']['link_options_confirm']['flag_confirmation'] = array( '#type' => 'textfield', '#title' => t('Flag confirmation message'), @@ -280,7 +279,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#default_value' => isset($flag->unflag_confirmation) ? $flag->unflag_confirmation : '', '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), ); - +*/ $form['actions'] = array( '#type' => 'actions', ); @@ -299,12 +298,17 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) // Allow the flag handler to make additions and changes to the form. // Note that the flag_broken handler will completely empty the form array! - $flag->options_form($form); +// $flag->options_form($form); return $form; } - public function validateForm(array &$form, array &$form_state) { + /** + * Overrides Drupal\Core\Entity\EntityFormController::validate(). + */ + public function validate(array $form, array &$form_state) { + parent::validate($form, $form_state); + $form_state['values']['title'] = trim($form_state['values']['title']); $form_values = $form_state['values']; @@ -319,8 +323,8 @@ public function validateForm(array &$form, array &$form_state) { $flag = $form['#flag']; - $flag->form_input($form_values); - $errors = $flag->validate(); +// @todo: Move this into the flag controller here. +// $errors = $flag->validate(); foreach ($errors as $field => $field_errors) { foreach ($field_errors as $error) { form_set_error($field, $error['message']); @@ -328,17 +332,17 @@ public function validateForm(array &$form, array &$form_state) { } } - public function submitForm(array &$form, array &$form_state) { - $flag = $form['#flag']; + public function save(array $form, array &$form_state) { + $flag = $this->entity; $form_state['values']['title'] = trim($form_state['values']['title']); - $flag->form_input($form_state['values']); - $flag->save(); - $flag->enable(); + $status = $flag->save(); +// $flag->enable(); drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); + // We clear caches more vigorously if the flag was new. - _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); +// _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); // Save permissions. // This needs to be done after the flag cache has been cleared, so that @@ -354,7 +358,7 @@ public function submitForm(array &$form, array &$form_state) { user_role_revoke_permissions($rid, $permissions); } } - +/* foreach (array_keys(user_roles(!module_exists('session_api'))) as $rid) { // Create an array of permissions, based on the checkboxes element name. $permissions = array( @@ -363,9 +367,14 @@ public function submitForm(array &$form, array &$form_state) { ); user_role_change_permissions($rid, $permissions); } +*/ // @todo: when we add database caching for flags we'll have to clear the // cache again here. $form_state['redirect'] = FLAG_ADMIN_PATH; } + + public function delete(array $form, array &$form_state) { + $form_state['redirect'] = 'admin/structure/flag'; + } } \ No newline at end of file From 980c063d417298d64847f84ab7fdc69c0c056ee8 Mon Sep 17 00:00:00 2001 From: Tess Date: Sat, 19 Oct 2013 23:04:16 -0500 Subject: [PATCH 341/629] Converted admin/structure/flags to a list entity controller. --- flag.module | 18 +++- flag.routing.yml | 14 +-- .../flag/Controller/FlagAdminController.php | 59 ------------ .../flag/Controller/FlagListController.php | 44 +++++++++ lib/Drupal/flag/Entity/Flag.php | 22 +++-- lib/Drupal/flag/FlagInterface.php | 4 + lib/Drupal/flag/Form/FlagAddForm.php | 94 ++++++++++--------- 7 files changed, 134 insertions(+), 121 deletions(-) delete mode 100644 lib/Drupal/flag/Controller/FlagAdminController.php diff --git a/flag.module b/flag.module index 42e2e09..4e083bc 100644 --- a/flag.module +++ b/flag.module @@ -183,12 +183,13 @@ function flag_menu() { $items[FLAG_ADMIN_PATH] = array( 'title' => 'Flags', - 'route_name' => 'flag_settings', + // 'route_name' => 'flag_settings', 'description' => 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).', - ); - $items[FLAG_ADMIN_PATH . '/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, +// ); +// $items[FLAG_ADMIN_PATH . '/list'] = array( +// 'title' => 'List', +// 'type' => MENU_DEFAULT_LOCAL_TASK, + 'route_name' => 'flag.flag_list', 'weight' => -10, ); $items[FLAG_ADMIN_PATH . '/add'] = array( @@ -1793,6 +1794,10 @@ function flag_get_flag($name = NULL, $fid = NULL) { return FALSE; } +function flag_load_by_id($id) { + return entity_load('flag_flag', $id); +} + /** * List all flags available. * @@ -1811,6 +1816,8 @@ function flag_get_flag($name = NULL, $fid = NULL) { * An array of the structure [fid] = flag_object. */ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL) { + return entity_load_multiple('flag_flag'); +/** $flags = &drupal_static(__FUNCTION__); // Retrieve a list of all flags, regardless of the parameters. @@ -1889,6 +1896,7 @@ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = } return $filtered_flags; + */ } /** diff --git a/flag.routing.yml b/flag.routing.yml index a6f8acf..e27d89f 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -1,9 +1,9 @@ -flag_settings: - path: '/admin/structure/flags' - defaults: - _content: '\Drupal\flag\Controller\FlagAdminController::content' - requirements: - _permission: 'administer flags' +#flag_settings: +# path: '/admin/structure/flags' +# defaults: +# _content: '\Drupal\flag\Controller\FlagAdminController::content' +# requirements: +# _permission: 'administer flags' flag_add_page: path: '/admin/structure/flags/add' @@ -13,7 +13,7 @@ flag_add_page: _permission: 'administer flags' flag.flag_list: - path: '/admin/structure/flagz/add' + path: '/admin/structure/flags' defaults: _entity_list: 'flag_flag' requirements: diff --git a/lib/Drupal/flag/Controller/FlagAdminController.php b/lib/Drupal/flag/Controller/FlagAdminController.php deleted file mode 100644 index 7251a0f..0000000 --- a/lib/Drupal/flag/Controller/FlagAdminController.php +++ /dev/null @@ -1,59 +0,0 @@ - $flags, 'default_flags' => $default_flags)); - - if (!module_exists('views')) { - $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; - } - else { - $output .= '

'; - $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', array('@views-url' => url('admin/structure/views'))); - if (flag_get_flag('bookmarks')) { - $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', array('@views-url' => url('admin/structure/views', array('query' => array('tag' => 'flag'))))); - } - $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', array('@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954')); - $output .= '

'; - } - - if (!module_exists('flag_actions')) { - $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules'))) . '

'; - } - else { - $output .= '

' . t('Flagging an item may trigger actions.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'))) . '

'; - } - - if (!module_exists('rules')) { - $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', array('@rules-url' => url('http://drupal.org/node/407070'))) . '

'; - } - else { - $output .= '

' . t('Flagging an item may trigger rules.', array('@rules-url' => url('admin/config/workflow/rules'))) . '

'; - } - - $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', array('@handbook-url' => 'http://drupal.org/handbook/modules/flag')) . '

'; - - return array( - '#type' => 'markup', - '#markup' => $output, - ); - } - -} \ No newline at end of file diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index 3f78170..d77173e 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -23,6 +23,50 @@ public function buildHeader() { return $header + parent::buildHeader(); } + public function render() { + $build['table'] = parent::render(); + + $output = ""; + + //@todo Move this too hook_help()? + if (!module_exists('views')) { + $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; + } + else { + $output .= '

'; + $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', array('@views-url' => url('admin/structure/views'))); + if (flag_get_flag('bookmarks')) { + $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', array('@views-url' => url('admin/structure/views', array('query' => array('tag' => 'flag'))))); + } + $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', array('@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954')); + $output .= '

'; + } + + if (!module_exists('flag_actions')) { + $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules'))) . '

'; + } + else { + $output .= '

' . t('Flagging an item may trigger actions.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'))) . '

'; + } + + if (!module_exists('rules')) { + $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', array('@rules-url' => url('http://drupal.org/node/407070'))) . '

'; + } + else { + $output .= '

' . t('Flagging an item may trigger rules.', array('@rules-url' => url('admin/config/workflow/rules'))) . '

'; + } + + $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', array('@handbook-url' => 'http://drupal.org/handbook/modules/flag')) . '

'; + + + $build['markup'] = array( + '#type' => 'markup', + '#markup' => $output, + ); + + return $build; + } + /** * Overrides Drupal\Core\Entity\EntityListController::buildRow(). */ diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index af22934..141ebbe 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -66,13 +66,6 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $entity_type = NULL; - /** - * The flag's "machine readable" name. - * - * @var string - */ - public $name = ''; - /** * The flag label. * @@ -87,6 +80,13 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $is_global = FALSE; + /** + * Whether this flag is enabled. + * + * @var bool + */ + public $enabled = TRUE; + /** * The sub-types, AKA bundles, this flag applies to. * @@ -159,4 +159,12 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $weight = 0; + public function enable() { + $this->enabled = TRUE; + } + + public function disable() { + $this->enabled = FALSE; + } + } \ No newline at end of file diff --git a/lib/Drupal/flag/FlagInterface.php b/lib/Drupal/flag/FlagInterface.php index ffa4d8c..0113880 100644 --- a/lib/Drupal/flag/FlagInterface.php +++ b/lib/Drupal/flag/FlagInterface.php @@ -14,4 +14,8 @@ interface FlagInterface extends ConfigEntityInterface { // todo: Add getters and setters as necessary. + public function enable(); + + public function disable(); + } \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index d23d043..67b14ef 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -13,8 +13,8 @@ class FlagAddForm extends EntityFormController { - public function form(array $form, array &$form_state, $entity_type = NULL) { - $form = parent::form($form, $form_state); + public function buildForm(array $form, array &$form_state, $entity_type = NULL) { + $form = parent::buildForm($form, $form_state); $flag = $this->entity; //\Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); @@ -25,29 +25,28 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { $form['#flag'] = $flag; - $form['#flag_name'] = $flag->name; + $form['#flag_name'] = $flag->id; - $form['title'] = array( + $form['label'] = array( '#type' => 'textfield', - '#title' => t('Title'), - '#default_value' => $flag->title, + '#title' => t('Label'), + '#default_value' => $flag->label(), '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), '#maxlength' => 255, '#required' => TRUE, '#weight' => -3, ); - $form['name'] = array( + $form['id'] = array( '#type' => 'machine_name', '#title' => t('Machine name'), - '#default_value' => $flag->name, + '#default_value' => $flag->id(), '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#maxlength' => 32, '#weight' => -2, '#machine_name' => array( - 'exists' => 'flag_get_flag', - 'source' => array('title'), + 'exists' => 'flag_load_by_id', ), + '#disabled' => !$flag->isNew(), ); $form['global'] = array( @@ -61,11 +60,11 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { // there are too many unpleasant consequences in either direction. // @todo: Allow this, but with a confirmation form, assuming anyone actually // needs this feature. - if (!empty($flag->id) && flag_get_flag_counts($flag->name)) { +/* if (!empty($flag->id) && flag_get_flag_counts($flag->id)) { $form['global']['#disabled'] = TRUE; $form['global']['#description'] .= '
' . t('This setting cannot be changed when flaggings exist for this flag.'); } - +*/ $form['messages'] = array( '#type' => 'fieldset', '#title' => t('Messages'), @@ -141,11 +140,17 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { '#weight' => 10, ); + $bundles = entity_get_bundles($entity_type); + $entity_bundles = array(); + foreach ($bundles as $bundle_id => $bundle_row) { + $entity_bundles[$bundle_id] = $bundle_row['label']; + } + // Flag classes will want to override this form element. $form['access']['types'] = array( '#type' => 'checkboxes', '#title' => t('Flaggable types'), - '#options' => array(), + '#options' => $entity_bundles, '#default_value' => $flag->types, '#description' => t('Check any sub-types that this flag may be used on.'), '#required' => TRUE, @@ -221,7 +226,7 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { '#tree' => FALSE, '#weight' => 20, // @todo: Move flag_link_type_options_states() into controller? - '#after_build' => array('flag_link_type_options_states'), +// '#after_build' => array('flag_link_type_options_states'), ); $form['display']['link_type'] = array( @@ -229,7 +234,7 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { '#title' => t('Link type'), '#options' => _flag_link_type_options(), // @todo: Move flag_check_link_types into controller? - '#after_build' => array('flag_check_link_types'), +// '#after_build' => array('flag_check_link_types'), '#default_value' => $flag->link_type, // Give this a high weight so additions by the flag classes for entity- // specific options go above. @@ -265,7 +270,7 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { '#id' => 'link-options-confirm', '#weight' => 21, ); -/* + $form['display']['link_options_confirm']['flag_confirmation'] = array( '#type' => 'textfield', '#title' => t('Flag confirmation message'), @@ -279,18 +284,6 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { '#default_value' => isset($flag->unflag_confirmation) ? $flag->unflag_confirmation : '', '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), ); -*/ - $form['actions'] = array( - '#type' => 'actions', - ); - - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save flag'), - // We put this button on the form before calling $flag->options_form() - // to give the flag handler a chance to remove it (e.g. flag_broken). - '#weight' => 999, - ); // Add our process handler to disable access to locked properties. //@todo: Fix reference to flag_form_locked_process, or replace entirely. @@ -303,13 +296,19 @@ public function form(array $form, array &$form_state, $entity_type = NULL) { return $form; } + protected function actions(array $form, array &$form_state) { + $actions = parent::actions($form, $form_state); + $actions['submit']['#value'] = t('Save Flag'); + return $actions; + } + /** * Overrides Drupal\Core\Entity\EntityFormController::validate(). */ public function validate(array $form, array &$form_state) { parent::validate($form, $form_state); - $form_state['values']['title'] = trim($form_state['values']['title']); + $form_state['values']['label'] = trim($form_state['values']['label']); $form_values = $form_state['values']; if ($form_values['link_type'] == 'confirm') { @@ -320,26 +319,32 @@ public function validate(array $form, array &$form_state) { form_set_error('unflag_confirmation', t('An unflag confirmation message is required when using the confirmation link type.')); } } - - - $flag = $form['#flag']; -// @todo: Move this into the flag controller here. -// $errors = $flag->validate(); - foreach ($errors as $field => $field_errors) { - foreach ($field_errors as $error) { - form_set_error($field, $error['message']); - } +/* + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { + form_set_error('label', t('The flag name may only contain lowercase letters, underscores, and numbers.')); } +*/ } + /** + * Overrides Drupal\Core\Entity\EntityFormController::save(). + */ public function save(array $form, array &$form_state) { $flag = $this->entity; $form_state['values']['title'] = trim($form_state['values']['title']); + $flag->enable(); $status = $flag->save(); -// $flag->enable(); - drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); + $uri = $flag->uri(); + if ($status == SAVED_UPDATED) { + drupal_set_message(t('Flag %label has been updated.', array('%label' => $flag->label()))); + watchdog('flag', 'Flag %label has been updated.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + } + else { + drupal_set_message(t('Flag %label has been added.', array('%label' => $flag->label()))); + watchdog('flag', 'Flag %label has been added.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + } // We clear caches more vigorously if the flag was new. // _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); @@ -351,7 +356,7 @@ public function save(array $form, array &$form_state) { // for different flag types: http://drupal.org/node/879988 // If the flag machine name as changed, clean up all the obsolete permissions. - if ($flag->name != $form['#flag_name']) { + if ($flag->id != $form['#flag_name']) { $old_name = $form['#flag_name']; $permissions = array("flag $old_name", "unflag $old_name"); foreach (array_keys(user_roles()) as $rid) { @@ -371,9 +376,12 @@ public function save(array $form, array &$form_state) { // @todo: when we add database caching for flags we'll have to clear the // cache again here. - $form_state['redirect'] = FLAG_ADMIN_PATH; + $form_state['redirect'] = 'admin/structure/flags'; } + /** + * Overrides Drupal\Core\Entity\EntityFormController::delete(). + */ public function delete(array $form, array &$form_state) { $form_state['redirect'] = 'admin/structure/flag'; } From e391d948f5b7508a6d029fcd3d723298a90947a0 Mon Sep 17 00:00:00 2001 From: Tess Date: Sun, 20 Oct 2013 23:00:45 -0500 Subject: [PATCH 342/629] Added Flagging content entity. --- flag.module | 2 +- flag.routing.yml | 14 +- includes/flag.admin.inc | 477 ------------------ lib/Drupal/flag/Annotation/Flag.php | 2 +- .../flag/Controller/FlagListController.php | 28 +- lib/Drupal/flag/Entity/Flag.php | 5 +- lib/Drupal/flag/Entity/Flagging.php | 84 +++ lib/Drupal/flag/FlaggingInterface.php | 16 + 8 files changed, 130 insertions(+), 498 deletions(-) create mode 100644 lib/Drupal/flag/Entity/Flagging.php create mode 100644 lib/Drupal/flag/FlaggingInterface.php diff --git a/flag.module b/flag.module index 4e083bc..cdc25b9 100644 --- a/flag.module +++ b/flag.module @@ -372,7 +372,7 @@ function flag_load($flag_name, $include_disabled = FALSE) { */ function _flag_menu_title($flag) { // The following conditional it to handle a D7 bug (@todo: link). - return $flag ? $flag->get_title() : ''; + return $flag ? $flag->label : ''; } /** diff --git a/flag.routing.yml b/flag.routing.yml index e27d89f..efda13c 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -1,10 +1,3 @@ -#flag_settings: -# path: '/admin/structure/flags' -# defaults: -# _content: '\Drupal\flag\Controller\FlagAdminController::content' -# requirements: -# _permission: 'administer flags' - flag_add_page: path: '/admin/structure/flags/add' defaults: @@ -26,6 +19,13 @@ flag_add: requirements: _permission: 'administer flags' +flag_edit: + path: '/admin/structure/flags/manage/{entity_type}' + defaults: + _entity_form: flag_flag.edit + requirements: + _permission: 'administer flags' + flag_import: path: '/admin/structure/flags/import' defaults: diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc index 64fb23b..555e5d4 100644 --- a/includes/flag.admin.inc +++ b/includes/flag.admin.inc @@ -8,22 +8,6 @@ use Drupal\flag\Handlers\AbstractFlag; use Drupal\flag\Handlers\BrokenFlag; -/** - * Flag administration page. Display a list of existing flags. - */ -/* -function flag_admin_page() { - $flags = flag_get_flags(); - $default_flags = flag_get_default_flags(TRUE); - $flag_admin_listing = drupal_get_form('flag_admin_listing', $flags); - return theme('flag_admin_page', array( - 'flags' => $flags, - 'default_flags' => $default_flags, - 'flag_admin_listing' => $flag_admin_listing, - )); -} -*/ - /** * A form for ordering the weights of all the active flags in the system. */ @@ -175,396 +159,6 @@ function theme_flag_admin_listing_disabled($variables) { return $output; } -/** - * Theme the output for the main flag administration page. - */ -function theme_flag_admin_page($variables) { - $flags = $variables['flags']; - $default_flags = $variables['default_flags']; - - $output = ''; - - $output .= drupal_render($variables['flag_admin_listing']); - $output .= theme('flag_admin_listing_disabled', array('flags' => $flags, 'default_flags' => $default_flags)); - - if (!module_exists('views')) { - $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; - } - else { - $output .= '

'; - $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', array('@views-url' => url('admin/structure/views'))); - if (flag_get_flag('bookmarks')) { - $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', array('@views-url' => url('admin/structure/views', array('query' => array('tag' => 'flag'))))); - } - $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', array('@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954')); - $output .= '

'; - } - - if (!module_exists('flag_actions')) { - $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules'))) . '

'; - } - else { - $output .= '

' . t('Flagging an item may trigger actions.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'))) . '

'; - } - - if (!module_exists('rules')) { - $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', array('@rules-url' => url('http://drupal.org/node/407070'))) . '

'; - } - else { - $output .= '

' . t('Flagging an item may trigger rules.', array('@rules-url' => url('admin/config/workflow/rules'))) . '

'; - } - - $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', array('@handbook-url' => 'http://drupal.org/handbook/modules/flag')) . '

'; - - return $output; -} - -/** - * Menu callback for adding a new flag. - * - * @param $entity_type - * The entity type for the new flag, taken from the path argument. If not - * present (i.e., '/add'), a form showing all possible flag types is shown. - * Otherwise, this shows a form for adding af flag the given type. - * - * @see flag_add_form() - * @see flag_form() - *//* -function flag_add_page($entity_type = NULL) { - if (isset($entity_type)) { - $flag = \Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); - // Mark the flag as new. - $flag->is_new = TRUE; - $type_info = flag_fetch_definition($entity_type); - drupal_set_title(t('Add new @type flag', array('@type' => $type_info['title']))); - return drupal_get_form('flag_form', $flag); - } - - drupal_set_title(t('Select flag type')); - return drupal_get_form('flag_add_form'); -} -*/ -/** - * Present a form for creating a new flag, setting the type of flag. - *//* -function flag_add_form($form, &$form_state) { - $types = array(); - foreach (flag_fetch_definition() as $type => $info) { - $types[$type] = $info['title'] . '
' . $info['description'] . '
'; - } - - $form['type'] = array( - '#type' => 'radios', - '#title' => t('Flag type'), - '#default_value' => 'node', - '#description' => t('The type of object this flag will affect. This cannot be changed once the flag is created.'), - '#required' => TRUE, - '#options' => $types, - ); - - $form['actions'] = array( - '#type' => 'actions', - ); - - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Continue'), - ); - - return $form; -} - -function flag_add_form_validate($form, &$form_state) { - $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); - if (get_class($flag) == 'BrokenFlag') { - form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); - } -} - -function flag_add_form_submit($form, &$form_state) { - $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type']; -} -*/ -/** - * Add/Edit flag page. - *//* -function flag_form($form, &$form_state, $flag) { - $form['#flag'] = $flag; - $form['#flag_name'] = $flag->name; - - $form['title'] = array( - '#type' => 'textfield', - '#title' => t('Title'), - '#default_value' => $flag->title, - '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), - '#maxlength' => 255, - '#required' => TRUE, - '#weight' => -3, - ); - - $form['name'] = array( - '#type' => 'machine_name', - '#title' => t('Machine name'), - '#default_value' => $flag->name, - '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#maxlength' => 32, - '#weight' => -2, - '#machine_name' => array( - 'exists' => 'flag_get_flag', - 'source' => array('title'), - ), - ); - - $form['global'] = array( - '#type' => 'checkbox', - '#title' => t('Global flag'), - '#default_value' => $flag->global, - '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), - '#weight' => -1, - ); - // Don't allow the 'global' checkbox to be changed when flaggings exist: - // there are too many unpleasant consequences in either direction. - // @todo: Allow this, but with a confirmation form, assuming anyone actually - // needs this feature. - if (!empty($flag->fid) && flag_get_flag_counts($flag->name)) { - $form['global']['#disabled'] = TRUE; - $form['global']['#description'] .= '
' . t('This setting cannot be changed when flaggings exist for this flag.'); - } - - $form['messages'] = array( - '#type' => 'fieldset', - '#title' => t('Messages'), - ); - - $form['messages']['flag_short'] = array( - '#type' => 'textfield', - '#title' => t('Flag link text'), - '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), - '#description' => t('The text for the "flag this" link for this flag.'), - '#required' => TRUE, - ); - - $form['messages']['flag_long'] = array( - '#type' => 'textfield', - '#title' => t('Flag link description'), - '#default_value' => $flag->flag_long, - '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'), - ); - - $form['messages']['flag_message'] = array( - '#type' => 'textfield', - '#title' => t('Flagged message'), - '#default_value' => $flag->flag_message, - '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - ); - - $form['messages']['unflag_short'] = array( - '#type' => 'textfield', - '#title' => t('Unflag link text'), - '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), - '#description' => t('The text for the "unflag this" link for this flag.'), - '#required' => TRUE, - ); - - $form['messages']['unflag_long'] = array( - '#type' => 'textfield', - '#title' => t('Unflag link description'), - '#default_value' => $flag->unflag_long, - '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'), - ); - - $form['messages']['unflag_message'] = array( - '#type' => 'textfield', - '#title' => t('Unflagged message'), - '#default_value' => $flag->unflag_message, - '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - ); - - $form['messages']['tokens_help'] = array( - '#title' => t('Token replacement'), - '#type' => 'fieldset', - '#description' => - '

' . t('The above six texts may contain any of the tokens listed below. For example, "Flag link text" could be entered as:') . '

' . - theme('item_list', array( - 'items' => array( - t('Add <em>[node:title]</em> to your favorites'), - t('Add this [node:type] to your favorites'), - t('Vote for this proposal ([node:flag-vote-count] people have already done so)'), - ), - 'attributes' => array('class' => 'token-examples'), - )) . - '

' . t('These tokens will be replaced with the appropriate fields from the node (or user, or comment).') . '

' . - theme('flag_tokens_browser', array('types' => $flag->get_labels_token_types())), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - - $form['access'] = array( - '#type' => 'fieldset', - '#title' => t('Flag access'), - '#tree' => FALSE, - '#weight' => 10, - ); - - // Flag classes will want to override this form element. - $form['access']['types'] = array( - '#type' => 'checkboxes', - '#title' => t('Flaggable types'), - '#options' => array(), - '#default_value' => $flag->types, - '#description' => t('Check any sub-types that this flag may be used on.'), - '#required' => TRUE, - '#weight' => 10, - ); - - // Disabled access breaks checkboxes unless #value is hard coded. - if (!empty($flag->locked['types'])) { - $form['access']['types']['#value'] = $flag->types; - } - - // Load the user permissions into the flag. - if (isset($flag->fid)) { - $flag->fetch_roles(); - } - elseif (isset($flag->import_roles)) { - // Convert the roles data from old API 2 flags that have been run through - // the update system. - // @see FlagUpdate_2::update() - $flag->roles = $flag->import_roles; - } - else { - // For new flags, provide a reasonable default value. - $flag->roles = array( - 'flag' => array(DRUPAL_AUTHENTICATED_RID), - 'unflag' => array(DRUPAL_AUTHENTICATED_RID), - ); - } - - $form['access']['roles'] = array( - '#title' => t('Roles that may use this flag'), - '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), - '#theme' => 'flag_form_roles', - '#theme_wrappers' => array('form_element'), - '#weight' => -2, - '#attached' => array( - 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), - 'css' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.css'), - ), - ); - if (module_exists('session_api')) { - $form['access']['roles']['#description'] .= ' ' . t('Support for anonymous users is being provided by Session API.'); - } - else { - $form['access']['roles']['#description'] .= ' ' . t('Anonymous users may flag content if the Session API module is installed.'); - } - - $form['access']['roles']['flag'] = array( - '#type' => 'checkboxes', - '#options' => user_roles(!module_exists('session_api')), - '#default_value' => $flag->roles['flag'], - '#parents' => array('roles', 'flag'), - ); - $form['access']['roles']['unflag'] = array( - '#type' => 'checkboxes', - '#options' => user_roles(!module_exists('session_api')), - '#default_value' => $flag->roles['unflag'], - '#parents' => array('roles', 'unflag'), - ); - - $form['access']['unflag_denied_text'] = array( - '#type' => 'textfield', - '#title' => t('Unflag not allowed text'), - '#default_value' => $flag->unflag_denied_text, - '#description' => t('If a user is allowed to flag but not unflag, this text will be displayed after flagging. Often this is the past-tense of the link text, such as "flagged".'), - '#weight' => -1, - ); - - $form['display'] = array( - '#type' => 'fieldset', - '#title' => t('Display options'), - '#description' => t('Flags are usually controlled through links that allow users to toggle their behavior. You can choose how users interact with flags by changing options here. It is legitimate to have none of the following checkboxes ticked, if, for some reason, you wish to place the the links on the page yourself.', array('@placement-url' => 'http://drupal.org/node/295383')), - '#tree' => FALSE, - '#weight' => 20, - '#after_build' => array('flag_link_type_options_states'), - ); - - $form['display']['link_type'] = array( - '#type' => 'radios', - '#title' => t('Link type'), - '#options' => _flag_link_type_options(), - '#after_build' => array('flag_check_link_types'), - '#default_value' => $flag->link_type, - // Give this a high weight so additions by the flag classes for entity- - // specific options go above. - '#weight' => 18, - '#attached' => array( - 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), - ), - '#attributes' => array( - 'class' => array('flag-link-options'), - ), - ); - // Add the descriptions to each ratio button element. These attach to the - // elements when FormAPI expands them. - foreach (_flag_link_type_descriptions() as $key => $description) { - $form['display']['link_type'][$key]['#description'] = $description; - } - - $form['display']['link_options_intro'] = array( - // This is a hack to allow a markup element to use FormAPI states. - // @see http://www.bywombats.com/blog/06-25-2011/using-containers-states-enabled-markup-form-elements - '#type' => 'container', - '#children' => '', - '#weight' => 20, - ); - - $form['display']['link_options_confirm'] = array( - '#type' => 'fieldset', - '#title' => t('Options for the "Confirmation form" link type'), - // Any "link type" provider module must put its settings fields inside - // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is - // the machine-name of the link type. This is necessary for the - // radiobutton's JavaScript dependency feature to work. - '#id' => 'link-options-confirm', - '#weight' => 21, - ); - - $form['display']['link_options_confirm']['flag_confirmation'] = array( - '#type' => 'textfield', - '#title' => t('Flag confirmation message'), - '#default_value' => isset($flag->flag_confirmation) ? $flag->flag_confirmation : '', - '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), - ); - - $form['display']['link_options_confirm']['unflag_confirmation'] = array( - '#type' => 'textfield', - '#title' => t('Unflag confirmation message'), - '#default_value' => isset($flag->unflag_confirmation) ? $flag->unflag_confirmation : '', - '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), - ); - - $form['actions'] = array( - '#type' => 'actions', - ); - - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save flag'), - // We put this button on the form before calling $flag->options_form() - // to give the flag handler a chance to remove it (e.g. flag_broken). - '#weight' => 999, - ); - - // Add our process handler to disable access to locked properties. - $form['#process'][] = 'flag_form_locked_process'; - - // Allow the flag handler to make additions and changes to the form. - // Note that the flag_broken handler will completely empty the form array! - $flag->options_form($form); - - return $form; -} -*/ /** * FormAPI after_build function set states on link type options fieldsets. * @@ -633,77 +227,6 @@ function flag_form_locked_process($element, &$form_state, $form) { return $element; } -/** - * Add/Edit flag form validate. - *//* -function flag_form_validate($form, &$form_state) { - $form_state['values']['title'] = trim($form_state['values']['title']); - $form_values = $form_state['values']; - - if ($form_values['link_type'] == 'confirm') { - if (empty($form_values['flag_confirmation'])) { - form_set_error('flag_confirmation', t('A flag confirmation message is required when using the confirmation link type.')); - } - if (empty($form_values['unflag_confirmation'])) { - form_set_error('unflag_confirmation', t('An unflag confirmation message is required when using the confirmation link type.')); - } - } - - - $flag = $form['#flag']; - $flag->form_input($form_values); - $errors = $flag->validate(); - foreach ($errors as $field => $field_errors) { - foreach ($field_errors as $error) { - form_set_error($field, $error['message']); - } - } -} -*/ -/** - * Add/Edit flag form submit. - *//* -function flag_form_submit($form, &$form_state) { - $flag = $form['#flag']; - - $form_state['values']['title'] = trim($form_state['values']['title']); - $flag->form_input($form_state['values']); - - $flag->save(); - $flag->enable(); - drupal_set_message(t('Flag @title has been saved.', array('@title' => $flag->get_title()))); - // We clear caches more vigorously if the flag was new. - _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); - - // Save permissions. - // This needs to be done after the flag cache has been cleared, so that - // the new permissions are picked up by hook_permission(). - // This may need to move to the flag class when we implement extra permissions - // for different flag types: http://drupal.org/node/879988 - - // If the flag machine name as changed, clean up all the obsolete permissions. - if ($flag->name != $form['#flag_name']) { - $old_name = $form['#flag_name']; - $permissions = array("flag $old_name", "unflag $old_name"); - foreach (array_keys(user_roles()) as $rid) { - user_role_revoke_permissions($rid, $permissions); - } - } - - foreach (array_keys(user_roles(!module_exists('session_api'))) as $rid) { - // Create an array of permissions, based on the checkboxes element name. - $permissions = array( - "flag $flag->name" => $flag->roles['flag'][$rid], - "unflag $flag->name" => $flag->roles['unflag'][$rid], - ); - user_role_change_permissions($rid, $permissions); - } - // @todo: when we add database caching for flags we'll have to clear the - // cache again here. - - $form_state['redirect'] = FLAG_ADMIN_PATH; -} -*/ /** * Output the access options for roles in a table. */ diff --git a/lib/Drupal/flag/Annotation/Flag.php b/lib/Drupal/flag/Annotation/Flag.php index d739ee3..604b4bd 100644 --- a/lib/Drupal/flag/Annotation/Flag.php +++ b/lib/Drupal/flag/Annotation/Flag.php @@ -12,7 +12,7 @@ /** - * Defines a Tip annotation object. + * Defines a Flag annotation object. * * @Annotation */ diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index d77173e..a71b70d 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -17,12 +17,27 @@ class FlagListController extends ConfigEntityListController { * Overrides Drupal\Core\Entity\EntityListController::buildHeader(). */ public function buildHeader() { - $header['id'] = t('ID'); - $header['label'] = t('Label'); +// $header['id'] = t('Flag'); + $header['label'] = t('Flag'); + $header['roles'] = t('Roles'); + $header['is_global'] = t('Global?'); return $header + parent::buildHeader(); } + /** + * Overrides Drupal\Core\Entity\EntityListController::buildRow(). + */ + public function buildRow(EntityInterface $entity) { + $row['label'] = $this->getLabel($entity); + + $row['roles'] = ' '; + + $row['is_global'] = $entity->is_global ? t('Yes') : t('No'); + + return $row + parent::buildRow($entity); + } + public function render() { $build['table'] = parent::render(); @@ -67,13 +82,4 @@ public function render() { return $build; } - /** - * Overrides Drupal\Core\Entity\EntityListController::buildRow(). - */ - public function buildRow(EntityInterface $entity) { - $row['label'] = $this->getLabel($entity); - - return $row + parent::buildRow($entity); - } - } \ No newline at end of file diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 141ebbe..6c31ebc 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -30,13 +30,16 @@ * "edit" = "Drupal\flag\Form\FlagAddForm", * "delete" = "Drupal\flag\Form\FlagAddForm" * } - * }, + * bundle_of = "flagging", * config_prefix = "flag.flag", * entity_keys = { * "id" = "id", * "label" = "label", * "uuid" = "uuid" + * }, + * links = { + * "edit-form" = "admin/structure/flags/manage/{flag_flag}" * } * ) * diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php new file mode 100644 index 0000000..1dd9507 --- /dev/null +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -0,0 +1,84 @@ +bundle; + } + + public static function baseFieldDefinitions($entity_type) { + $properties['id'] = array( + 'label' => t('Flagging ID'), + 'description' => t('The Flagging ID.'), + 'type' => 'integer_field', + 'read-only' => TRUE, + ); + $properties['type'] = array( + 'label' => t('Type'), + 'description' => t('The flag type.'), + 'type' => 'string_field', + 'read-only' => TRUE, + ); + $properties['uuid'] = array( + 'label' => t('UUID'), + 'description' => t('The node UUID.'), + 'type' => 'uuid_field', + 'read-only' => TRUE, + ); + $properties['uid'] = array( + 'label' => t('User ID'), + 'description' => t('The ID of the flagging user.'), + 'type' => 'entity_reference_field', + 'settings' => array( + 'target_type' => 'user', + 'default_value' => 0, + ), + ); + $properties['created'] = array( + 'label' => t('Created'), + 'description' => t('The time that the flagging was created.'), + 'type' => 'integer_field', + ); + + return $properties; + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/FlaggingInterface.php b/lib/Drupal/flag/FlaggingInterface.php new file mode 100644 index 0000000..c75bd44 --- /dev/null +++ b/lib/Drupal/flag/FlaggingInterface.php @@ -0,0 +1,16 @@ + Date: Sat, 26 Oct 2013 18:11:20 -0500 Subject: [PATCH 343/629] Repurposed Flag annotation and plugin for FlagType. --- flag.services.yml | 4 +- .../Annotation/{Flag.php => FlagType.php} | 0 ...nManager.php => FlagTypePluginManager.php} | 0 .../flag/Plugin/Derivative/FlagBase.php | 44 ------------------- .../Flag/{FlagBase.php => FlagTypeBase.php} | 0 5 files changed, 2 insertions(+), 46 deletions(-) rename lib/Drupal/flag/Annotation/{Flag.php => FlagType.php} (100%) rename lib/Drupal/flag/{FlagPluginManager.php => FlagTypePluginManager.php} (100%) delete mode 100644 lib/Drupal/flag/Plugin/Derivative/FlagBase.php rename lib/Drupal/flag/Plugin/Flag/{FlagBase.php => FlagTypeBase.php} (100%) diff --git a/flag.services.yml b/flag.services.yml index 191cf27..1ad7e6e 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -1,4 +1,4 @@ services: - plugin.manager.flag.flag: - class: Drupal\Flag\FlagPluginManager + plugin.manager.flag.flagtype: + class: Drupal\Flag\FlagTypePluginManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] diff --git a/lib/Drupal/flag/Annotation/Flag.php b/lib/Drupal/flag/Annotation/FlagType.php similarity index 100% rename from lib/Drupal/flag/Annotation/Flag.php rename to lib/Drupal/flag/Annotation/FlagType.php diff --git a/lib/Drupal/flag/FlagPluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php similarity index 100% rename from lib/Drupal/flag/FlagPluginManager.php rename to lib/Drupal/flag/FlagTypePluginManager.php diff --git a/lib/Drupal/flag/Plugin/Derivative/FlagBase.php b/lib/Drupal/flag/Plugin/Derivative/FlagBase.php deleted file mode 100644 index 7e3f134..0000000 --- a/lib/Drupal/flag/Plugin/Derivative/FlagBase.php +++ /dev/null @@ -1,44 +0,0 @@ -flagStorage = $flag_storage; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, $base_plugin_id) { - return new static( - $container->get('entity.manager')->getStorageController('flag') - ); - } - - /** - * {@inheritdoc} - */ - public function getDerivativeDefinitions(array $base_plugin_definition) { - foreach ($this->flagStorage->loadMultiple() as $flag => $entity) { - $this->derivatives[$flag] = $base_plugin_definition; - $this->derivatives[$flag]['admin_label'] = $entity->label(); - $this->derivatives[$flag]['cache'] = DRUPAL_NO_CACHE; - } - return $this->derivatives; - } -} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/FlagBase.php b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php similarity index 100% rename from lib/Drupal/flag/Plugin/Flag/FlagBase.php rename to lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php From 40c1f32cf4b2c64b88604ac8fa8183b3d8d229ee Mon Sep 17 00:00:00 2001 From: Tess Date: Sat, 26 Oct 2013 18:12:15 -0500 Subject: [PATCH 344/629] Initial FlagType plugin code. --- lib/Drupal/flag/Annotation/FlagType.php | 14 ++------------ lib/Drupal/flag/FlagTypePluginManager.php | 4 ++-- lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php | 9 ++++----- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/lib/Drupal/flag/Annotation/FlagType.php b/lib/Drupal/flag/Annotation/FlagType.php index 604b4bd..a1cba41 100644 --- a/lib/Drupal/flag/Annotation/FlagType.php +++ b/lib/Drupal/flag/Annotation/FlagType.php @@ -12,11 +12,11 @@ /** - * Defines a Flag annotation object. + * Defines a FlagType annotation object. * * @Annotation */ -class Flag extends Plugin { +class FlagType extends Plugin { /** * The plugin ID. @@ -34,14 +34,4 @@ class Flag extends Plugin { */ public $title; - - /** - * A class to make the plugin derivative aware. - * - * @var string - * - * @see \Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator - */ - public $derivative; - } diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php index 3313239..8221374 100644 --- a/lib/Drupal/flag/FlagTypePluginManager.php +++ b/lib/Drupal/flag/FlagTypePluginManager.php @@ -13,10 +13,10 @@ use Drupal\Core\Language\LanguageManager; use Drupal\Core\Plugin\DefaultPluginManager; -class FlagPluginManager extends DefaultPluginManager { +class FlagTypePluginManager extends DefaultPluginManager { /** - * Constructs a new FlagPluginManager. + * Constructs a new FlagTypePluginManager. * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths diff --git a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php index e3df92e..b38656f 100644 --- a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php +++ b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php @@ -11,16 +11,15 @@ use Drupal\core\Plugin\PluginBase; /** - * Class FlagBase + * Class FlagTypeBase * @package Drupal\flag\Plugin\Flag * * @Flag{ - * id = "flag_base", - * title = @Translation("Flag"), - * derivative = "Drupal\flag\Plugin\Derivative\FlagBase" + * id = "flagtype_base", + * title = @Translation("Flag Type"), * } */ -class FlagBase extends PluginBase{ +class FlagTypeBase extends PluginBase{ /** * {@inheritdoc} From ca0dee9adb30ebd3303535a9b40399a0953a9001 Mon Sep 17 00:00:00 2001 From: Tess Date: Sun, 27 Oct 2013 20:29:49 -0500 Subject: [PATCH 345/629] Fixed broken plugin manager definitions. --- flag.services.yml | 2 +- lib/Drupal/flag/Entity/Flag.php | 12 ++++++ lib/Drupal/flag/FlagTypePluginManager.php | 4 +- lib/Drupal/flag/Form/FlagAddPageForm.php | 2 +- lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php | 39 +++++++++++++++++++- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/flag.services.yml b/flag.services.yml index 1ad7e6e..23e248b 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -1,4 +1,4 @@ services: plugin.manager.flag.flagtype: - class: Drupal\Flag\FlagTypePluginManager + class: Drupal\flag\FlagTypePluginManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 6c31ebc..62395a1 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -8,6 +8,7 @@ namespace Drupal\flag\Entity; +use Drupal\Component\Plugin\DefaultSinglePluginBag; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageControllerInterface; use Drupal\Core\Entity\Annotation\EntityType; @@ -162,6 +163,17 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $weight = 0; + protected $typesBag; + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(); + */ + public function __construct(array $values, $entity_type) { + parent::__construct($values, $entity_type); + + $this->typesBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), $this->types, array()); + } + public function enable() { $this->enabled = TRUE; } diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php index 8221374..ffb8d9e 100644 --- a/lib/Drupal/flag/FlagTypePluginManager.php +++ b/lib/Drupal/flag/FlagTypePluginManager.php @@ -29,9 +29,9 @@ class FlagTypePluginManager extends DefaultPluginManager { * The module handler to invoke the alter hook with. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/Flag/FlagBase', $namespaces, 'Drupal\flag\Annotation\Flag'); + parent::__construct('Plugin/Flag/FlagTypeBase', $namespaces, 'Drupal\flag\Annotation\FlagType'); -// $this->alterInfo($module_handler, 'tour_tips_info'); +// $this->alterInfo($module_handler, 'flag_type_info'); $this->setCacheBackend($cache_backend, $language_manager, 'tour'); } diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index 31efe73..b883986 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -22,7 +22,7 @@ public function getFormID() { public function buildForm(array $form, array &$form_state) { $types = array(); - // @todo Convert to a Drupal service? + // @todo Use \Drupal::service() to get a list of FlagType plugins. foreach (flag_fetch_definition() as $type => $info) { $types[$type] = $info['title'] . '
' . $info['description'] . '
'; } diff --git a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php index b38656f..197aff9 100644 --- a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php +++ b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php @@ -19,7 +19,7 @@ * title = @Translation("Flag Type"), * } */ -class FlagTypeBase extends PluginBase{ +class FlagTypeBase extends PluginBase { /** * {@inheritdoc} @@ -27,4 +27,41 @@ class FlagTypeBase extends PluginBase{ public function __construct(array $configuration, $plugin_id, array $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); } + + public funciton flag() { + + } + + /** + * Declares the options this flag supports, and their default values. + * + * Derived classes should want to override this. + *//* + public function options() { + + }*/ + + /** + * Provides a form for setting options. + * + * Derived classes should want to override this. + */ + public function optionsForm(&$form) { + + } + + /** + * Implements access_multiple() implemented by each child class. + * + * @abstract + * + * @return + * An array keyed by entity ids, whose values represent the access to the + * corresponding entity. The access value may be FALSE if access should be + * denied, or NULL (or not set) if there is no restriction to be made. It + * should NOT be TRUE. + */ + public function type_access_multiple($entity_ids, $account) { + return array(); + } } \ No newline at end of file From a1d429d86a5a565670e5ae8dc6462b9b5cbad14a Mon Sep 17 00:00:00 2001 From: Tess Date: Mon, 28 Oct 2013 19:59:36 -0500 Subject: [PATCH 346/629] All FlagType plugins load. --- lib/Drupal/flag/FlagTypePluginManager.php | 2 +- lib/Drupal/flag/Form/FlagAddPageForm.php | 2 + .../flag/Plugin/Flag/BrokenFlagType.php | 31 +++++ .../flag/Plugin/Flag/CommentFlagType.php | 80 +++++++++++ .../flag/Plugin/Flag/EntityFlagType.php | 125 ++++++++++++++++++ lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php | 15 ++- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 96 ++++++++++++++ lib/Drupal/flag/Plugin/Flag/UserFlagType.php | 80 +++++++++++ 8 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 lib/Drupal/flag/Plugin/Flag/BrokenFlagType.php create mode 100644 lib/Drupal/flag/Plugin/Flag/CommentFlagType.php create mode 100644 lib/Drupal/flag/Plugin/Flag/EntityFlagType.php create mode 100644 lib/Drupal/flag/Plugin/Flag/NodeFlagType.php create mode 100644 lib/Drupal/flag/Plugin/Flag/UserFlagType.php diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php index ffb8d9e..a8ad403 100644 --- a/lib/Drupal/flag/FlagTypePluginManager.php +++ b/lib/Drupal/flag/FlagTypePluginManager.php @@ -29,7 +29,7 @@ class FlagTypePluginManager extends DefaultPluginManager { * The module handler to invoke the alter hook with. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/Flag/FlagTypeBase', $namespaces, 'Drupal\flag\Annotation\FlagType'); + parent::__construct('Plugin/Flag', $namespaces, 'Drupal\flag\Annotation\FlagType'); // $this->alterInfo($module_handler, 'flag_type_info'); $this->setCacheBackend($cache_backend, $language_manager, 'tour'); diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index b883986..532cdee 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -23,6 +23,8 @@ public function getFormID() { public function buildForm(array $form, array &$form_state) { $types = array(); // @todo Use \Drupal::service() to get a list of FlagType plugins. + // print_r(\Drupal::service('plugin.manager.flag.flagtype')->getDefinitions()); + foreach (flag_fetch_definition() as $type => $info) { $types[$type] = $info['title'] . '
' . $info['description'] . '
'; } diff --git a/lib/Drupal/flag/Plugin/Flag/BrokenFlagType.php b/lib/Drupal/flag/Plugin/Flag/BrokenFlagType.php new file mode 100644 index 0000000..d220e59 --- /dev/null +++ b/lib/Drupal/flag/Plugin/Flag/BrokenFlagType.php @@ -0,0 +1,31 @@ + $this->entity_type)), 'error'); + $form = array(); + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php new file mode 100644 index 0000000..0a76b88 --- /dev/null +++ b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php @@ -0,0 +1,80 @@ + '', + ); + return $options; + } + + /** + * Options form extras for comment flags. + */ + public function options_form(&$form) { + parent::options_form($form); + + $form['access']['access_author'] = array( + '#type' => 'radios', + '#title' => t('Flag access by content authorship'), + '#options' => array( + '' => t('No additional restrictions'), + 'comment_own' => t('Users may only flag own comments'), + 'comment_others' => t('Users may only flag comments by others'), + 'node_own' => t('Users may only flag comments of nodes they own'), + 'node_others' => t('Users may only flag comments of nodes by others'), + ), + '#default_value' => $this->access_author, + '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), + ); + } + + public function type_access_multiple($entity_ids, $account) { + $access = array(); + + // If all subtypes are allowed, we have nothing to say here. + if (empty($this->types)) { + return $access; + } + + // Ensure node types are granted access. This avoids a + // node_load() on every type, usually done by applies_to_entity_id(). + $query = db_select('comment', 'c'); + $query->innerJoin('node', 'n', 'c.nid = n.nid'); + $result = $query + ->fields('c', array('cid')) + ->condition('c.cid', $entity_ids, 'IN') + ->condition('n.type', $this->types, 'NOT IN') + ->execute(); + foreach ($result as $row) { + $access[$row->nid] = FALSE; + } + + return $access; + } +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php new file mode 100644 index 0000000..1900a91 --- /dev/null +++ b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php @@ -0,0 +1,125 @@ + array(), + // Output the flag as individual pseudofields. + 'show_as_field' => FALSE, + // Add a checkbox for the flag in the entity form. + // @see hook_field_attach_form(). + 'show_on_form' => FALSE, + 'access_author' => '', + 'show_contextual_link' => FALSE, + ); + return $options; + } + + /** + * Options form extras for the generic entity flag. + */ + function options_form(&$form) { + $bundles = array(); + $bundle_info = entity_get_bundles($this->entity_type); + foreach ($bundle_info as $bundle_key => $info) { + $bundles[$bundle_key] = $info['label']; + } + $form['access']['types'] = array( + '#type' => 'checkboxes', + '#title' => t('Bundles'), + '#options' => $bundles, + '#description' => t('Select the bundles that this flag may be used on. Leave blank to allow on all bundles for the entity type.'), + '#default_value' => $this->types, + ); + + // Add checkboxes to show flag link on each entity view mode. + $options = array(); + $defaults = array(); + $view_modes = entity_get_view_modes($this->entity_type); + foreach ($view_modes as $name => $view_mode) { + $options[$name] = t('Display on @name view mode', array('@name' => $view_mode['label'])); + $defaults[$name] = !empty($this->show_in_links[$name]) ? $name : 0; + } + + $form['display']['show_in_links'] = array( + '#type' => 'checkboxes', + '#title' => t('Display in entity links'), + '#description' => t('Show the flag link with the other links on the entity.'), + '#options' => $options, + '#default_value' => $defaults, + ); + + $form['display']['show_as_field'] = array( + '#type' => 'checkbox', + '#title' => t('Display link as field'), + '#description' => t('Show the flag link as a pseudofield, which can be ordered among other entity elements in the "Manage display" settings for the entity type.'), + '#default_value' => isset($this->show_as_field) ? $this->show_as_field : TRUE, + ); + if (empty($entity_info['fieldable'])) { + $form['display']['show_as_field']['#disabled'] = TRUE; + $form['display']['show_as_field']['#description'] = t("This entity type is not fieldable."); + } + + $form['display']['show_on_form'] = array( + '#type' => 'checkbox', + '#title' => t('Display checkbox on entity edit form'), + '#default_value' => $this->show_on_form, + '#weight' => 5, + ); + + // We use FieldAPI to put the flag checkbox on the entity form, so therefore + // require the entity to be fielable. Since this is a potential DX + // headscratcher for a developer wondering where this option has gone, + // we disable it and explain why. + if (empty($entity_info['fieldable'])) { + $form['display']['show_on_form']['#disabled'] = TRUE; + $form['display']['show_on_form']['#description'] = t('This is only possible on entities which are fieldable.'); + } + $form['display']['show_contextual_link'] = array( + '#type' => 'checkbox', + '#title' => t('Display in contextual links'), + '#default_value' => $this->show_contextual_link, + '#description' => t('Note that not all entity types support contextual links.'), + '#access' => module_exists('contextual'), + '#weight' => 10, + ); + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php index 197aff9..f2a818e 100644 --- a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php +++ b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php @@ -14,10 +14,10 @@ * Class FlagTypeBase * @package Drupal\flag\Plugin\Flag * - * @Flag{ + * @FlagType( * id = "flagtype_base", - * title = @Translation("Flag Type"), - * } + * title = @Translation("Flag Type Base") + * ) */ class FlagTypeBase extends PluginBase { @@ -25,6 +25,7 @@ class FlagTypeBase extends PluginBase { * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, array $plugin_definition) { + $configuration += $this->options(); parent::__construct($configuration, $plugin_id, $plugin_definition); } @@ -36,10 +37,12 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi * Declares the options this flag supports, and their default values. * * Derived classes should want to override this. - *//* + * + * @todo Rename to defaultConfiguration()? + */ public function options() { - - }*/ + return array(); + } /** * Provides a form for setting options. diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php new file mode 100644 index 0000000..2a27da9 --- /dev/null +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -0,0 +1,96 @@ + 0, + ); + return $options; + } + + /** + * Options form extras for node flags. + */ + public function options_form(&$form) { + parent::options_form($form); + + $form['access']['access_author'] = array( + '#type' => 'radios', + '#title' => t('Flag access by content authorship'), + '#options' => array( + '' => t('No additional restrictions'), + 'own' => t('Users may only flag content they own'), + 'others' => t('Users may only flag content of others'), + ), + '#default_value' => $this->access_author, + '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), + ); + + // Support for i18n flagging requires Translation helpers module. + $form['i18n'] = array( + '#type' => 'radios', + '#title' => t('Internationalization'), + '#options' => array( + '1' => t('Flag translations of content as a group'), + '0' => t('Flag each translation of content separately'), + ), + '#default_value' => $this->i18n, + '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), + '#access' => module_exists('translation_helpers'), + '#weight' => 5, + ); + + // Override the UI texts for nodes. + $form['display']['show_on_form'] = array( + '#title' => t('Display checkbox on node edit form'), + '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), + ) + $form['display']['show_on_form']; + } + + function type_access_multiple($entity_ids, $account) { + $access = array(); + + // If all subtypes are allowed, we have nothing to say here. + if (empty($this->types)) { + return $access; + } + + // Ensure that only flaggable node types are granted access. This avoids a + // node_load() on every type, usually done by applies_to_entity_id(). + $result = db_select('node', 'n')->fields('n', array('nid')) + ->condition('nid', array_keys($entity_ids), 'IN') + ->condition('type', $this->types, 'NOT IN') + ->execute(); + foreach ($result as $row) { + $access[$row->nid] = FALSE; + } + + return $access; + } +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php new file mode 100644 index 0000000..5ff0285 --- /dev/null +++ b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php @@ -0,0 +1,80 @@ + TRUE, + 'access_uid' => '', + ); + return $options; + } + + /** + * Options form extras for user flags. + */ + function options_form(&$form) { + parent::options_form($form); + $form['access']['types'] = array( + // A user flag doesn't support node types. + // TODO: Maybe support roles instead of node types. + '#type' => 'value', + '#value' => array(0 => 0), + ); + $form['access']['access_uid'] = array( + '#type' => 'checkbox', + '#title' => t('Users may flag themselves'), + '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themself does not make sense.'), + '#default_value' => $this->access_uid ? 0 : 1, + ); + $form['display']['show_on_profile'] = array( + '#type' => 'checkbox', + '#title' => t('Display link on user profile page'), + '#description' => t('Show the link formatted as a user profile element.'), + '#default_value' => $this->show_on_profile, + // Put this above 'show on entity'. + '#weight' => -1, + ); + } + + function type_access_multiple($entity_ids, $account) { + $access = array(); + + // Exclude anonymous. + if (array_key_exists(0, $entity_ids)) { + $access[0] = FALSE; + } + + // Prevent users from flagging themselves. + if ($this->access_uid == 'others' && array_key_exists($account->uid, $entity_ids)) { + $access[$account->uid] = FALSE; + } + + return $access; + } + +} \ No newline at end of file From fc5ca39d8a8d2a23eaef28ea42e488c7cdbb69f5 Mon Sep 17 00:00:00 2001 From: Tess Date: Tue, 19 Nov 2013 19:46:48 -0600 Subject: [PATCH 347/629] Fixed local action link on flag entity form, added initial action link plugin code. --- .idea/.name | 1 + flag.install | 4 +- flag.local_actions.yml | 5 ++ flag.module | 51 ++++++++++++----- flag.services.yml | 3 + lib/Drupal/flag/ActionLinkPluginManager.php | 29 ++++++++++ lib/Drupal/flag/ActionLinkTypeBase.php | 55 +++++++++++++++++++ .../flag/ActionLinkTypePluginInterface.php | 18 ++++++ lib/Drupal/flag/Annotation/ActionLinkType.php | 47 ++++++++++++++++ lib/Drupal/flag/Entity/Flag.php | 16 ++++++ lib/Drupal/flag/Entity/Flagging.php | 5 +- lib/Drupal/flag/Flag.php | 40 ++++++++++++++ lib/Drupal/flag/FlagTypePluginManager.php | 2 +- lib/Drupal/flag/Form/FlagAddForm.php | 2 +- lib/Drupal/flag/Plugin/ActionLink/Reload.php | 26 +++++++++ lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php | 12 +++- 16 files changed, 294 insertions(+), 22 deletions(-) create mode 100644 .idea/.name create mode 100644 flag.local_actions.yml create mode 100644 lib/Drupal/flag/ActionLinkPluginManager.php create mode 100644 lib/Drupal/flag/ActionLinkTypeBase.php create mode 100644 lib/Drupal/flag/ActionLinkTypePluginInterface.php create mode 100644 lib/Drupal/flag/Annotation/ActionLinkType.php create mode 100644 lib/Drupal/flag/Flag.php create mode 100644 lib/Drupal/flag/Plugin/ActionLink/Reload.php diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..551c90f --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +flag \ No newline at end of file diff --git a/flag.install b/flag.install index 3f07700..d7d20ba 100644 --- a/flag.install +++ b/flag.install @@ -64,7 +64,7 @@ function flag_schema() { $schema['flagging'] = array( 'description' => 'Objects that have been flagged.', 'fields' => array( - 'flagging_id' => array( + 'id' => array( 'description' => 'The unique ID for this particular tag.', 'type' => 'serial', 'unsigned' => TRUE, @@ -115,7 +115,7 @@ function flag_schema() { 'disp-size' => 11, ) ), - 'primary key' => array('flagging_id'), + 'primary key' => array('id'), 'unique keys' => array( 'fid_entity_id_uid_sid' => array('fid', 'entity_id', 'uid', 'sid'), ), diff --git a/flag.local_actions.yml b/flag.local_actions.yml new file mode 100644 index 0000000..b9b57dc --- /dev/null +++ b/flag.local_actions.yml @@ -0,0 +1,5 @@ +flag_add_page_action: + route_name: flag_add_page + title: 'Add New Flag' + appears_on: + - flag.flag_list \ No newline at end of file diff --git a/flag.module b/flag.module index cdc25b9..58bf883 100644 --- a/flag.module +++ b/flag.module @@ -193,7 +193,6 @@ function flag_menu() { 'weight' => -10, ); $items[FLAG_ADMIN_PATH . '/add'] = array( - 'title' => 'Add flag', 'route_name' => 'flag_add_page', 'type' => MENU_SIBLING_LOCAL_TASK, 'weight' => 1, @@ -693,9 +692,10 @@ function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { * @see flag_field_attach_submit(). */ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) { - list($id) = entity_extract_ids($entity_type, $entity); + $id = $entity->id; + // Some modules are being stupid here. Commerce! - if (empty($id)) { + if (empty($entity->id)) { $id = NULL; } @@ -846,6 +846,7 @@ function flag_field_attach_save($entity_type, $entity) { * Implements hook_contextual_links_view_alter(). */ function flag_contextual_links_view_alter(&$element, $items) { +/* if (isset($element['#element']['#entity_type'])) { $entity_type = $element['#element']['#entity_type']; @@ -884,7 +885,7 @@ function flag_contextual_links_view_alter(&$element, $items) { 'html' => TRUE, ); } - } + }*/ } /** @@ -897,9 +898,35 @@ function flag_contextual_links_view_alter(&$element, $items) { function flag_entity_view($entity, $type, $view_mode, $langcode) { // Get all possible flags for this entity type. $flags = flag_get_flags($type); + + foreach ($flags as $flag) { + + if($flag->isFlagged()) { + $action_link_url = "/unflag"; + } + else { + $action_link_url = "/flag"; + } + + $action_link_url .= "/" . $flag->id . "/" . $entity->id(); + + $entity->content['flag_' . $flag->id] = array( + '#markup' => '
' . l($flag->flag_short, $action_link_url) . '
', + '#weight' => 10, + ); +/* + $links = array( + '#prefix' => '
', + '#markup' => l($flag->flag_short, $action_link_url), + '#suffix' => '
', + ); +*/ + } + + /** foreach ($flags as $flag) { // Check if the flag outputs on entity view. - if (!($flag->show_as_field || $flag->shows_in_entity_links($view_mode))) { + if (!($flag->show_as_field)) { //} || $flag->shows_in_entity_links($view_mode))) { // Flag is not configured to output on entity view, so skip it to save on // calls to access checks. continue; @@ -928,7 +955,7 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { // The flag links are actually fully rendered theme functions. // The HTML attribute is set to TRUE to allow whatever the themer desires. $links['flag-' . $flag->name] = array( - 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), + 'title' => $flag->flag_short, //theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), 'html' => TRUE, ); } @@ -940,15 +967,11 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { ); } } - + */ // If any links were made, add them to the entity's links array. - if (isset($links)) { - $entity->content['links']['flag'] = array( - '#theme' => 'links', - '#links' => $links, - '#attributes' => array('class' => array('links', 'inline')), - ); - } +// if (isset($links)) { +// $entity->content['links']['flag'] = $links; + // } } /** diff --git a/flag.services.yml b/flag.services.yml index 23e248b..554fa2b 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -2,3 +2,6 @@ services: plugin.manager.flag.flagtype: class: Drupal\flag\FlagTypePluginManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] + plugin.manager.action_link: + class: Drupal\flag\ActionLinkPluginManager + arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] diff --git a/lib/Drupal/flag/ActionLinkPluginManager.php b/lib/Drupal/flag/ActionLinkPluginManager.php new file mode 100644 index 0000000..81ee91e --- /dev/null +++ b/lib/Drupal/flag/ActionLinkPluginManager.php @@ -0,0 +1,29 @@ +alterInfo($module_handler, 'flag_link_type_info'); + $this->setCacheBackend($cache_backend, $language_manager, 'flag_link_type_info'); + } + +} diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/lib/Drupal/flag/ActionLinkTypeBase.php new file mode 100644 index 0000000..4bde528 --- /dev/null +++ b/lib/Drupal/flag/ActionLinkTypeBase.php @@ -0,0 +1,55 @@ +setConfiguration($configuration); + } + + public function buildLink() { + return ""; + } + + public function buildConfigurationForm(array $form, array &$form_state) { + return $form; + } + + public function submitConfigurationForm(array &$form, array &$form_state) { + + } + + public function validateConfigurationForm(array &$form, array &$form_state) { + + } + + public function defaultConfiguration() { + return array(); + } + + public function getConfiguration() { + return $configuration; + } + + public function setConfiguration(array $configuration) { + $this->configuration = $configuration; + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/ActionLinkTypePluginInterface.php b/lib/Drupal/flag/ActionLinkTypePluginInterface.php new file mode 100644 index 0000000..e0d746f --- /dev/null +++ b/lib/Drupal/flag/ActionLinkTypePluginInterface.php @@ -0,0 +1,18 @@ +enabled = FALSE; } + public function isFlagged(AccountInterface $account = NULL) { + if($account == NULL) { + global $user; + $account = $user; + } + + $query = \Drupal::entityQuery('flagging'); + $query->condition('uid', $account->id()); + + $result = $query->execute(); + + if (isset($result['node'])) { + $flagging_ids = array_keys($result['flagging']); + } + } + } \ No newline at end of file diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index 1dd9507..f81fc20 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -23,10 +23,9 @@ * label = @Translation("Flagging"), * module = "flag", * controllers = { - * "storage" = "FieldableDatabaseStorageController", - * "form" = { - * } + * "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController", * }, + * base_table = "flagging", * fieldable = TRUE, * entity_keys = { * "id" = "id", diff --git a/lib/Drupal/flag/Flag.php b/lib/Drupal/flag/Flag.php new file mode 100644 index 0000000..9785935 --- /dev/null +++ b/lib/Drupal/flag/Flag.php @@ -0,0 +1,40 @@ +getDefinition($entity_type); + } + + return \Drupal::service('plugin.manager.flag.flagtype')->getDefinitions(); + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php index a8ad403..2b21305 100644 --- a/lib/Drupal/flag/FlagTypePluginManager.php +++ b/lib/Drupal/flag/FlagTypePluginManager.php @@ -32,7 +32,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac parent::__construct('Plugin/Flag', $namespaces, 'Drupal\flag\Annotation\FlagType'); // $this->alterInfo($module_handler, 'flag_type_info'); - $this->setCacheBackend($cache_backend, $language_manager, 'tour'); + $this->setCacheBackend($cache_backend, $language_manager, 'flag'); } } \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index 67b14ef..218a738 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -332,7 +332,7 @@ public function validate(array $form, array &$form_state) { public function save(array $form, array &$form_state) { $flag = $this->entity; - $form_state['values']['title'] = trim($form_state['values']['title']); + $form_state['values']['label'] = trim($form_state['values']['label']); $flag->enable(); $status = $flag->save(); diff --git a/lib/Drupal/flag/Plugin/ActionLink/Reload.php b/lib/Drupal/flag/Plugin/ActionLink/Reload.php new file mode 100644 index 0000000..bb9619e --- /dev/null +++ b/lib/Drupal/flag/Plugin/ActionLink/Reload.php @@ -0,0 +1,26 @@ + Date: Tue, 19 Nov 2013 22:36:23 -0600 Subject: [PATCH 348/629] Removed a bunch of D7 code. --- flag.flag.inc | 110 -- flag.info.inc | 98 -- flag.module | 8 +- flag.rules.inc | 582 ----------- flag_actions.info | 9 - flag_actions.install | 95 -- flag_actions.module | 692 ------------- includes/flag.actions.inc | 243 ----- includes/flag.admin.inc | 345 ------- includes/flag.cookie_storage.inc | 170 --- includes/flag.entity.inc | 24 - includes/flag.export.inc | 138 --- includes/flag.features.inc | 124 --- includes/flag.pages.inc | 165 --- includes/views/flag.views.inc | 272 ----- includes/views/flag.views_convert.inc | 235 ----- .../views/flag_handler_argument_entity_id.inc | 46 - includes/views/flag_handler_field_flagged.inc | 36 - includes/views/flag_handler_field_ops.inc | 163 --- .../views/flag_handler_filter_flagged.inc | 33 - includes/views/flag_handler_relationships.inc | 267 ----- includes/views/flag_handler_sort_flagged.inc | 47 - ..._plugin_argument_validate_flaggability.inc | 226 ---- .../flag_is_flagged/flag_is_flagged.inc | 96 -- plugins/content_types/flag_link/flag_link.inc | 115 --- tests/flag.test | 971 ------------------ tests/flagaccesstest/flagaccesstest.info | 6 - tests/flagaccesstest/flagaccesstest.module | 26 - 28 files changed, 4 insertions(+), 5338 deletions(-) delete mode 100644 flag.flag.inc delete mode 100644 flag.info.inc delete mode 100644 flag.rules.inc delete mode 100644 flag_actions.info delete mode 100644 flag_actions.install delete mode 100644 flag_actions.module delete mode 100644 includes/flag.actions.inc delete mode 100644 includes/flag.admin.inc delete mode 100644 includes/flag.cookie_storage.inc delete mode 100644 includes/flag.entity.inc delete mode 100644 includes/flag.export.inc delete mode 100644 includes/flag.features.inc delete mode 100644 includes/flag.pages.inc delete mode 100644 includes/views/flag.views.inc delete mode 100644 includes/views/flag.views_convert.inc delete mode 100644 includes/views/flag_handler_argument_entity_id.inc delete mode 100644 includes/views/flag_handler_field_flagged.inc delete mode 100644 includes/views/flag_handler_field_ops.inc delete mode 100644 includes/views/flag_handler_filter_flagged.inc delete mode 100644 includes/views/flag_handler_relationships.inc delete mode 100644 includes/views/flag_handler_sort_flagged.inc delete mode 100644 includes/views/flag_plugin_argument_validate_flaggability.inc delete mode 100644 plugins/access/flag_is_flagged/flag_is_flagged.inc delete mode 100644 plugins/content_types/flag_link/flag_link.inc delete mode 100644 tests/flag.test delete mode 100644 tests/flagaccesstest/flagaccesstest.info delete mode 100644 tests/flagaccesstest/flagaccesstest.module diff --git a/flag.flag.inc b/flag.flag.inc deleted file mode 100644 index 695a800..0000000 --- a/flag.flag.inc +++ /dev/null @@ -1,110 +0,0 @@ - array( - 'title' => t('Nodes'), - 'description' => t("Nodes are a Drupal site's primary content."), - 'handler' => '\Drupal\flag\Handlers\NodeFlag', - ), - 'user' => array( - 'title' => t('Users'), - 'description' => t('Users who have created accounts on your site.'), - 'handler' => '\Drupal\flag\Handlers\UserFlag', - ), - ); - - if (module_exists('comment')) { - $definitions['comment'] = array( - 'title' => t('Comments'), - 'description' => t('Comments are responses to node content.'), - 'handler' => '\Drupal\flag\Handlers\CommentFlag', - 'module' => 'comment', - ); - } - - if (module_exists('taxonomy')) { - $definitions['taxonomy_term'] = array( - 'title' => t('Taxonomy Terms'), - 'description' => t('Taxonomy terms are used to categorize content.'), - 'handler' => '\Drupal\flag\Handlers\Flag', - 'module' => 'taxonomy', - ); - } - - return $definitions; -} - -/** - * Implements hook_flag_type_info_alter(). - * - * Step in and add flag types for any entities not yet catered for, using the - * basic flag_entity handler. This allows other modules to provide more - * specialized handlers for entities in hook_flag_type_info() as normal. - */ -function flag_flag_type_info_alter(&$definitions) { - foreach (entity_get_info() as $entity_type => $entity_info) { - // Only add flag support for entities that don't yet have them, and which - // are non-config entities. - if (!isset($definitions[$entity_type]) && empty($entity_info['configuration'])) { - // We deliberately exclude taxonomy vocabularies from the list of - // supported entity types because they aren't fieldable or directly - // viewable, which makes them impossible to flag. - if ($entity_type === 'taxonomy_vocabulary') { - continue; - } - - $definitions[$entity_type] = array( - 'title' => $entity_info['label'], - 'description' => t('@entity-type entity', array('@entity-type' => $entity_info['label'])), - 'handler' => 'flag_entity', - ); - } - } -} - -/** - * Implements hook_flag_link_type_info(). - */ -function flag_flag_link_type_info() { - return array( - 'toggle' => array( - 'title' => t('JavaScript toggle'), - 'description' => t('An AJAX request will be made and degrades to type "Normal link" if JavaScript is not available.'), - 'uses standard js' => TRUE, - 'uses standard css' => TRUE, - ), - 'normal' => array( - 'title' => t('Normal link'), - 'description' => t('A normal non-JavaScript request will be made and the current page will be reloaded.'), - 'uses standard js' => FALSE, - 'uses standard css' => FALSE, - ), - 'confirm' => array( - 'title' => t('Confirmation form'), - 'description' => t('The user will be taken to a confirmation form on a separate page to confirm the flag.'), - 'options' => array( - 'flag_confirmation' => '', - 'unflag_confirmation' => '', - ), - 'uses standard js' => FALSE, - 'uses standard css' => FALSE, - 'provides form' => TRUE, - ), - ); -} diff --git a/flag.info.inc b/flag.info.inc deleted file mode 100644 index 69bbb5c..0000000 --- a/flag.info.inc +++ /dev/null @@ -1,98 +0,0 @@ -flag_FLAGNAME, boolean. - * - per-user flags: - * - entity->flag_FLAGNAME_users, list of users. - * - user->flag_FLAGNAME_flagged, list of user's flagged entities. - */ -function flag_entity_property_info_alter(&$info) { - foreach (flag_get_flags() as $flag) { - if ($flag->global) { - // Global flags. - // Boolean property on entity type. - // This can go on either the entity as a whole, or on bundles, depending - // on whether the flag is limited by bundle. - $property_definition = array( - 'label' => t('Whether the entity is flagged with flag @flag', array( - '@flag' => $flag->name, - )), - 'description' => t('Whether the entity is flagged with flag @flag.', array( - '@flag' => $flag->name, - )), - 'type' => 'boolean', - 'getter callback' => 'flag_properties_get_flagging_boolean', - 'computed' => TRUE, - 'flag_name' => $flag->name, - ); - if (count($flag->types)) { - // Bundle specific property. - foreach ($flag->types as $type) { - $info[$flag->entity_type]['bundles'][$type]['properties']['flag_' . $flag->name] = $property_definition; - } - } - else { - // Generic property, applies for all bundles. - $info[$flag->entity_type]['properties']['flag_' . $flag->name] = $property_definition; - } - } - else { - // Per-user flags. - // User property: list of flagged entities by the user. - $info['user']['properties']['flag_' . $flag->name . '_flagged'] = array( - 'label' => t('Flagged @entity-type with flag @flag', array( - '@entity-type' => $flag->entity_type, - '@flag' => $flag->name, - )), - 'description' => t('Returns a list of entities a user flagged with flag @flag.', array( - '@flag' => $flag->name, - )), - 'type' => 'list<' . $flag->entity_type . '>', - 'getter callback' => 'flag_properties_get_flagged_entities', - 'computed' => TRUE, - 'flag_name' => $flag->name, - 'flag_entity_type' => $flag->entity_type, - ); - $info['user']['properties']['flag_sid'] = array( - 'label' => t('Flag user session identifier'), - 'description' => t('Returns the sessions id used to distinguish anonymous users from each other.'), - 'type' => 'text', - 'getter callback' => 'flag_properties_get_user_sid', - 'computed' => TRUE, - ); - // Entity property: list of users who have flagged this entity. - // This can go on either the entity as a whole, or on bundles, depending - // on whether the flag is limited by bundle. - $property_definition = array( - 'label' => t('Users who flagged the entity with flag @flag', array( - '@flag' => $flag->name, - )), - 'description' => t('Returns a list of users who flagged an entity with flag @flag.', array( - '@flag' => $flag->name, - )), - 'type' => 'list', - 'getter callback' => 'flag_properties_get_flagging_users', - 'computed' => TRUE, - 'flag_name' => $flag->name, - ); - if (count($flag->types)) { - // Bundle specific property. - foreach ($flag->types as $type) { - $info[$flag->entity_type]['bundles'][$type]['properties']['flag_' . $flag->name . '_user'] = $property_definition; - } - } - else { - // Generic property, applies for all bundles. - $info[$flag->entity_type]['properties']['flag_' . $flag->name . '_user'] = $property_definition; - } - } - } -} diff --git a/flag.module b/flag.module index 58bf883..612a3a2 100644 --- a/flag.module +++ b/flag.module @@ -217,7 +217,7 @@ function flag_menu() { 'type' => MENU_LOCAL_TASK, 'weight' => 3, ); - +/* $items[FLAG_ADMIN_PATH . '/manage/%flag'] = array( 'load arguments' => array(TRUE), // Allow for disabled flags. 'page callback' => 'drupal_get_form', @@ -263,7 +263,7 @@ function flag_menu() { 'file' => 'includes/flag.export.inc', 'type' => MENU_CALLBACK, ); - +*/ $items['flag/%/%flag/%'] = array( 'title' => 'Flag', 'page callback' => 'flag_page', @@ -1463,7 +1463,7 @@ function flag_flag_access_multiple($flag, $entity_ids, $account) { /** * Implements hook_theme(). - */ + *//* function flag_theme() { $path = drupal_get_path('module', 'flag') . '/theme'; @@ -1513,7 +1513,7 @@ function flag_theme() { ), ); } - +*/ /** * A preprocess function for our theme('flag'). It generates the * variables needed there. diff --git a/flag.rules.inc b/flag.rules.inc deleted file mode 100644 index 23cefcc..0000000 --- a/flag.rules.inc +++ /dev/null @@ -1,582 +0,0 @@ - array( - 'label' => t('flag'), - 'ui class' => 'FlagRulesUIClass', - 'wrapper class' => 'FlagRulesDataWrapper', - 'wrap' => TRUE, - ), - 'flagging' => array( - 'label' => t('flagging'), - 'parent' => 'entity', - 'group' => t('flag'), - ), - ); -} - -/** - * A custom wrapper class for flags to be used with Rules. - * @ingroup rules - */ -class FlagRulesDataWrapper extends RulesIdentifiableDataWrapper implements RulesDataWrapperSavableInterface { - - protected function extractIdentifier($flag) { - return $flag->name; - } - - protected function load($name) { - return flag_get_flag($name); - } - - public function save() { - $flag = $this->value(); - $flag->save(); - } - - public function validate($value) { - if (isset($value) && is_string($value)) { - return TRUE; - } - elseif (isset($value) && is_object($value) && $value instanceof flag_flag) { - return TRUE; - } - return parent::validate($value); - } -} - -/** - * UI for inputing flags. - * @ingroup rules - */ -class FlagRulesUIClass extends RulesDataUI implements RulesDataDirectInputFormInterface { - - public static function getDefaultMode() { - return 'input'; - } - - public static function inputForm($name, $info, $settings, RulesPlugin $element) { - $options = _flag_rules_flags_options(isset($info['flag_type']) ? $info['flag_type'] : NULL); - $header = array( - 'title' => t('Flag:'), - 'type' => t('The flag type'), - 'global' => t('Is the flag global?'), - ); - $settings += array($name => isset($info['default value']) ? $info['default value'] : ''); - - $form[$name] = array( - '#type' => 'tableselect', - '#header' => $header, - '#options' => $options, - '#required' => empty($info['optional']), - '#multiple' => FALSE, - '#default_value' => $settings[$name], - '#empty' => t('There is no suiting flag available.') - ); - return $form; - } - - public static function render($value) { - $flag = flag_get_flag($value); - - if ($flag === FALSE) { - return array(); - } - - return array( - 'content' => array('#markup' => check_plain($flag->get_title())), - '#attributes' => array('class' => array('rules-parameter-flag')), - ); - } -} - -function _flag_rules_flags_options($flag_type = NULL) { - $flags = flag_get_flags(); - $options = array(); - foreach ($flags as $flag) { - if (!isset($flag_type) || $flag->entity_type == $flag_type) { - $options[$flag->name] = array( - 'title' => $flag->get_title(), - 'type' => $flag->entity_type, - 'global' => $flag->global ? t('Yes') : t('No'), - ); - } - } - return $options; -} - -/** - * Implements hook_rules_event_info(). - */ -function flag_rules_event_info() { - $items = array(); - - $flags = flag_get_flags(); - foreach ($flags as $flag) { - // We only support flags on entities. - if ($info = entity_get_info($flag->entity_type)) { - $variables = array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('flag'), - 'flag_type' => $flag->entity_type, - ), - 'flagged_' . $flag->entity_type => array( - 'type' => $flag->entity_type, - 'label' => $info['label'], - ), - 'flagging_user' => array( - 'type' => 'user', - 'label' => t('flagging user'), - ), - 'flagging' => array( - 'type' => 'flagging', - 'label' => t('flagging'), - ), - ); - - // For each flag we define two events. - $items['flag_flagged_' . $flag->name] = array( - 'group' => t('Flag'), - 'label' => t('A @flag-type has been flagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->entity_type))), - 'variables' => $variables, - 'access callback' => 'flag_rules_integration_access', - ); - $items['flag_unflagged_' . $flag->name] = array( - 'group' => t('Flag'), - 'label' => t('A @flag-type has been unflagged, under "@flag-title"', array('@flag-title' => $flag->get_title(), '@flag-type' => t($flag->entity_type))), - 'variables' => $variables, - 'access callback' => 'flag_rules_integration_access', - ); - } - } - return $items; -} - -/** - * Implements hook_rules_action_info(). - */ -function flag_rules_action_info() { - $param_defaults = array( - 'flagging_user' => array( - 'type' => 'user', - 'label' => t('User on whose behalf to flag'), - 'description' => t('For non-global flags, this is the user on whose behalf to flag the object. In addition, if checked below, the access permissions to the flag are checked against this user.'), - ), - 'permission_check' => array( - 'type' => 'boolean', - 'label' => t('Skip permission check'), - 'description' => t('Whether to ignore permissions of the user on whose behalf to flag.'), - 'restriction' => 'input', - ), - ); - $items = array( - 'flag_trim' => array( - 'label' => t('Trim a flag'), - 'base' => 'flag_rules_action_trim', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - ), - 'flagging_user' => array( - 'type' => 'user', - 'label' => t('User whose flag to trim'), - 'description' => t('For non-global flags, this is the user whose flag to trim. (For global flags, this argument is ignored.)'), - ), - 'cutoff_size' => array( - 'type' => 'integer', - 'label' => t('Flag queue size'), - 'description' => t('The maximum number of objects to keep in the queue. Newly flagged objects will be kept; older ones will be removed. Tip: by typing "1" here you implement a singleton.'), - ), - 'trim_newest' => array( - 'type' => 'boolean', - 'label' => t('Trim newest flags'), - 'description' => t('Checking this will trim the newest flags. This will prevent new flags once a limit is reached.'), - ), - 'permission_check' => $param_defaults['permission_check'], - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - 'fetch_overall_flag_count' => array( - 'label' => t('Fetch overall flag count'), - 'base' => 'flag_rules_action_fetch_overall_flag_count', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - ), - ), - 'provides' => array( - 'overall_flag_count' => array( - 'label' => t('Overall flag count'), - 'type' => 'integer', - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - 'fetch_entity_flag_count' => array( - 'label' => t('Fetch entity flag count'), - 'base' => 'flag_rules_action_fetch_entity_flag_count', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - ), - 'entity_type' => array( - 'type' => 'text', - 'label' => t('Entity type'), - 'options list' => 'flag_rules_get_flag_types', - 'restriction' => 'input', - ), - ), - 'provides' => array( - 'entity_flag_count' => array( - 'label' => t('Entity flag count'), - 'type' => 'integer', - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - 'fetch_user_flag_count' => array( - 'label' => t('Fetch user flag count'), - 'base' => 'flag_rules_action_fetch_user_flag_count', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - ), - 'user' => array( - 'type' => 'user', - 'label' => t('User'), - ), - ), - 'provides' => array( - 'user_flag_count' => array( - 'label' => t('User flag count'), - 'type' => 'integer', - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - ); - foreach (flag_get_types() as $type) { - $entity_info = entity_get_info($type); - $label = $entity_info['label']; - $items += array( - 'flag_fetch_' . $type . '_by_user' => array( - 'label' => t('Fetch @label flagged by user', array('@label' => $label)), - 'base' => 'flag_rules_action_fetch_entity_by_user', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - 'flag_type' => $type, - 'description' => t('The flag to check for.'), - ), - 'flagging_user' => array( - 'type' => 'user', - 'label' => t('User who flagged the @label', array('@label' => $label)), - 'description' => t('For non-global flags, this is the user who flagged the @label. (For global flags, this argument is ignored.)', array('@label' => $label)), - ), - ), - 'provides' => array( - 'content_flagged_by_user' => array( - 'label' => t('Content flagged by user'), - 'type' => 'list<' . $type . '>', - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - 'flag_flag' . $type => array( - 'label' => t('Flag a @label', array('@label' => $label)), - 'base' => 'flag_rules_action_flag', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - 'flag_type' => $type, - 'description' => t('The flag to check for.'), - ), - $type => array( - 'type' => $type, - 'label' => $label, - ), - ) + $param_defaults, - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - 'flag_unflag' . $type => array( - 'label' => t('Unflag a @label', array('@label' => $label)), - 'base' => 'flag_rules_action_unflag', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - 'flag_type' => $type, - 'description' => t('The flag to check for.'), - ), - $type => array( - 'type' => $type, - 'label' => $label, - ), - ) + $param_defaults, - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - ); - $items['flag_fetch_users_' . $type] = array( - 'label' => t('Fetch users who have flagged a @label', array('@label' => $label)), - 'base' => 'flag_rules_action_fetch_users', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - 'flag_type' => $type, - 'description' => t('Choose the flag for which to fetch the users.'), - ), - $type => array( - 'type' => $type, - 'label' => $label, - ), - ), - 'provides' => array( - 'users' => array( - 'label' => t('Users who flagged'), - 'type' => 'list', - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ); - } - // For backward compatibility sake. This was the original name of the 'fetch node by user'. - $items['flag_fetch_entity_by_user'] = $items['flag_fetch_node_by_user']; - $items['flag_fetch_entity_by_user']['label'] .= ' '. t('(Legacy)'); - return $items; -} - -/** - * Base action implementation: Flag. - */ -function flag_rules_action_flag($flag, $entity, $flagging_user, $permissions_check) { - $flag->flag('flag', $flag->get_entity_id($entity), $flagging_user, $permissions_check); -} - -/** - * Base action implementation: Unflag. - */ -function flag_rules_action_unflag($flag, $entity, $flagging_user, $permissions_check) { - $flag->flag('unflag', $flag->get_entity_id($entity), $flagging_user, $permissions_check); -} - -/** - * Base action implementation: Trim flag. - */ -function flag_rules_action_trim($flag, $flagging_user, $cutoff_size, $trim_newest, $permissions_check) { - // For some reason, when this action fires in response to a flagging event, - // as an anonymous user, then the $flagging_user is sent through as FALSE. - // Not sure why. This workaround fixes the problem in this specific case. - if ($flagging_user === FALSE) { - $flagging_user = $GLOBALS['user']; - } - flag_trim_flag($flag, $flagging_user, $cutoff_size, $trim_newest, $permissions_check); -} - -/** - * Base action implementation: Fetch users who flagged an entity. - */ -function flag_rules_action_fetch_users($flag, $entity) { - $result = db_select('flagging', 'fc') - ->fields('fc', array('uid')) - ->condition('entity_type', $flag->entity_type) - ->condition('entity_id', $flag->get_entity_id($entity)) - ->condition('fid', $flag->fid) - ->execute(); - $uids = $result->fetchCol(); - // Filter out anonymous users. - return array('users' => array_filter($uids)); -} - -/** - * Base action implementation: Fetch entities who were flagged a user. - */ -function flag_rules_action_fetch_entity_by_user($flag, $entity) { - $user = entity_metadata_wrapper('user', $entity); - $sid = $user->flag_sid->value(); - $query = db_select('flagging', 'fc') - ->fields('fc', array('entity_id')) - ->condition('entity_type', $flag->entity_type) - ->condition('uid', $user->uid->value()) - ->condition('fid', $flag->fid); - // Filter out any bad session ids and any users that aren't anonymous. - if (!empty($sid) && $sid != -1) { - $query->condition('sid', $sid); - } - $result = $query->execute(); - $flagged = $result->fetchCol(); - return array('content_flagged_by_user' => $flagged); -} - -/** - * Base action implementation: Fetch overall count for a particular flag. - */ -function flag_rules_action_fetch_overall_flag_count($flag) { - $count = flag_get_flag_counts($flag->name); - return array('overall_flag_count' => $count); -} - -/** - * Helper function which will return all the available flag types. - * - * @return - * An array of flag type names keyed by the type name. - */ -function flag_rules_get_flag_types() { - $types = array(); - foreach (flag_get_types() as $type) { - $types[$type] = $type; - } - return $types; -} - -/** - * Base action implementation: Fetch count of flags for a particular entity. - */ -function flag_rules_action_fetch_entity_flag_count($flag, $entity_type) { - $count = flag_get_entity_flag_counts($flag, $entity_type); - return array('entity_flag_count' => $count); -} - -/** - * Base action implementation: Fetch user's flag count. - */ -function flag_rules_action_fetch_user_flag_count($flag, $user) { - $count = flag_get_user_flag_counts($flag, $user); - return array('user_flag_count' => $count); -} - -/** - * Implements hook_rules_condition_info(). - */ -function flag_rules_condition_info() { - $items = array(); - foreach (flag_get_types() as $type) { - $entity_info = entity_get_info($type); - $label = isset($entity_info[$type]['label']) ? $entity_info[$type]['label'] : $type; - $items += array( - 'flag_threshold_' . $type => array( - 'label' => drupal_ucfirst(t('@type has flagging count', array('@type' => $label))), - 'base' => 'flag_rules_condition_threshold', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - 'flag_type' => $type, - 'description' => t('The flag to check for.') - ), - $type => array( - 'type' => $type, - 'label' => $label, - ), - 'number' => array( - 'type' => 'integer', - 'label' => t('Number'), - 'description' => t('The number against which to test the number of times the object is flagged. For example, if you type "3" here, and choose "Greater than" for the operator, then this condition will return TRUE if the object is flagged more than three times.'), - ), - 'operator' => array( - 'type' => 'text', - 'label' => t('Comparison operator'), - 'options list' => 'flag_rules_condition_threshold_operator_options', - 'restriction' => 'input', - 'default value' => '=', - 'optional' => TRUE, - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - 'flag_flagged_' . $type => array( - 'label' => drupal_ucfirst(t('@type is flagged', array('@type' => $label))), - 'base' => 'flag_rules_condition_flagged', - 'parameter' => array( - 'flag' => array( - 'type' => 'flag', - 'label' => t('Flag'), - 'flag_type' => $type, - 'description' => t('The flag to check for.') - ), - $type => array( - 'type' => $type, - 'label' => $label, - ), - 'flagging_user' => array( - 'type' => 'user', - 'label' => t('User on whose behalf to check'), - 'description' => t('For non-global flags, this is the user on whose behalf the flag is checked.'), - ), - ), - 'group' => t('Flag'), - 'access callback' => 'flag_rules_integration_access', - ), - ); - } - return $items; -} - -/** - * Options list callback for the operator parameter of the flagging threshold condition. - */ -function flag_rules_condition_threshold_operator_options() { - return array( - '>' => t('Greater than'), - '>=' => t('Greater than or equal'), - '=' => t('Equal to'), - '<=' => t('Less than or equal'), - '<' => t('Less than'), - ); -} - -/** - * Condition: Check flagging count. - */ -function flag_rules_condition_threshold($flag, $entity, $number, $operator = '=') { - $count = $flag->get_count($flag->get_entity_id($entity)); - - switch ($operator) { - case '>' : return $count > $number; - case '>=': return $count >= $number; - case '=' : return $count == $number; - case '<' : return $count < $number; - case '<=': return $count <= $number; - } -} - -/** - * Condition: Flag is flagged. - */ -function flag_rules_condition_flagged($flag, $entity, $account) { - return $flag->is_flagged($flag->get_entity_id($entity), $account->uid); -} - -/** - * Rules integration access callback. - */ -function flag_rules_integration_access($type, $name) { - return user_access('administer flags'); -} diff --git a/flag_actions.info b/flag_actions.info deleted file mode 100644 index 9f1403b..0000000 --- a/flag_actions.info +++ /dev/null @@ -1,9 +0,0 @@ -name = Flag actions -description = Execute actions on Flag events. -core = 7.x -dependencies[] = flag -package = Flags -configure = admin/structure/flags/actions - -files[] = flag.install -files[] = flag_actions.module \ No newline at end of file diff --git a/flag_actions.install b/flag_actions.install deleted file mode 100644 index a41286d..0000000 --- a/flag_actions.install +++ /dev/null @@ -1,95 +0,0 @@ - array( - 'aid' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'disp-width' => '5', - ), - 'fid' => array( - 'type' => 'int', - 'size' => 'small', - 'not null' => FALSE, - 'disp-width' => '5', - ), - 'event' => array( - 'type' => 'varchar', - 'length' => '255', - 'not null' => FALSE, - ), - 'threshold' => array( - 'type' => 'int', - 'size' => 'small', - 'not null' => TRUE, - 'default' => 0, - 'disp-width' => '5', - ), - 'repeat_threshold' => array( - 'type' => 'int', - 'size' => 'small', - 'not null' => TRUE, - 'default' => 0, - 'disp-width' => '5', - ), - 'callback' => array( - 'type' => 'varchar', - 'length' => '255', - 'not null' => TRUE, - 'default' => '', - ), - 'parameters' => array( - 'type' => 'text', - 'size' => 'big', - 'not null' => TRUE, - ), - ), - 'primary key' => array('aid'), - ); - - return $schema; -} - -/** - * Add a "repeat_threshold" value to all existing Flag actions. - */ -function flag_actions_update_6200() { - // Add the new repeat_threshold column. - if (!db_field_exists('flag_actions', 'repeat_threshold')) { - $column = array( - 'type' => 'int', - 'size' => 'small', - 'not null' => TRUE, - 'default' => 0, - 'disp-width' => '5', - ); - db_add_field('flag_actions', 'repeat_threshold', $column); - } - - // Update the normal threshold column to default to 0. - $column = array( - 'type' => 'int', - 'size' => 'small', - 'not null' => TRUE, - 'default' => 0, - 'disp-width' => '5', - ); - db_change_field('flag_actions', 'threshold', 'threshold', $column); -} diff --git a/flag_actions.module b/flag_actions.module deleted file mode 100644 index f4c3aed..0000000 --- a/flag_actions.module +++ /dev/null @@ -1,692 +0,0 @@ - 'Actions', - 'page callback' => 'flag_actions_page', - 'access callback' => 'user_access', - 'access arguments' => array('administer actions'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 1, - ); - $items[FLAG_ADMIN_PATH . '/actions/add'] = array( - 'title' => 'Add action', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_actions_form', NULL, 5), - 'access callback' => 'user_access', - 'access arguments' => array('administer actions'), - 'type' => MENU_CALLBACK, - ); - $items[FLAG_ADMIN_PATH . '/actions/delete'] = array( - 'title' => 'Delete action', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_actions_delete_form', 5), - 'access callback' => 'user_access', - 'access arguments' => array('administer actions'), - 'type' => MENU_CALLBACK, - ); - $items[FLAG_ADMIN_PATH . '/actions/configure'] = array( - 'title' => 'Edit action', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_actions_form', 5), - 'access callback' => 'user_access', - 'access arguments' => array('administer actions'), - 'type' => MENU_CALLBACK, - ); - - return $items; -} - -/** - * Implements hook_theme(). - */ -function flag_actions_theme() { - return array( - 'flag_actions_page' => array( - 'variables' => array('actions' => NULL, 'form' => NULL), - ), - 'flag_actions_add_form' => array( - 'render element' => 'form', - ), - 'flag_actions_flag_form' => array( - 'render element' => 'form', - ), - ); -} - -function flag_actions_get_action($aid) { - $actions = flag_actions_get_actions(); - return $actions[$aid]; -} - -function flag_actions_get_actions($flag_name = NULL, $reset = FALSE) { - $flag_actions = &drupal_static(__FUNCTION__); - module_load_include('inc', 'flag', 'includes/flag.actions'); - - // Get a list of all possible actions defined by modules. - $actions = module_invoke_all('action_info'); - - // Retrieve the list of user-defined flag actions. - if (!isset($flag_actions) || $reset) { - $flag_actions = array(); - $query = db_select('flag_actions', 'a'); - $query->innerJoin('flag', 'f', 'a.fid = f.fid'); - $query->addField('f', 'name', 'flag'); - $result = $query - ->fields('a') - ->execute(); - foreach ($result as $action) { - if (!isset($actions[$action->callback])) { - $actions[$action->callback] = array( - 'description' => t('Missing action "@action-callback". Module providing it was either uninstalled or disabled.', array('@action-callback' => $action->callback)), - 'configurable' => FALSE, - 'type' => 'node', - 'missing' => TRUE, - ); - } - $action->parameters = unserialize($action->parameters); - $action->label = $actions[$action->callback]['label']; - $action->configurable = $actions[$action->callback]['configurable']; - $action->behavior = isset($actions[$action->callback]['behavior']) ? $actions[$action->callback]['behavior'] : array(); - $action->type = $actions[$action->callback]['type']; - $action->missing = !empty($actions[$action->callback]['missing']); - - $flag_actions[$action->aid] = $action; - } - } - - // Filter actions to a specified flag. - if (isset($flag_name)) { - $specific_flag_actions = array(); - foreach ($flag_actions as $aid => $action) { - if ($action->flag == $flag_name) { - $specific_flag_actions[$aid] = $action; - } - } - return $specific_flag_actions; - } - - return $flag_actions; -} - -/** - * Insert a new flag action. - * - * @param $fid - * The flag object ID. - * @param $event - * The flag event, such as "flag" or "unflag". - * @param $threshold - * The flagging threshold at which this action will be executed. - * @param $repeat_threshold - * The number of additional flaggings after which the action will be repeated. - * @param $callback - * The action callback to be executed. - * @param $parameters - * The action parameters. - */ -function flag_actions_insert_action($fid, $event, $threshold, $repeat_threshold, $callback, $parameters) { - return db_insert('flag_actions') - ->fields(array( - 'fid' => $fid, - 'event' => $event, - 'threshold' => $threshold, - 'repeat_threshold' => $repeat_threshold, - 'callback' => $callback, - 'parameters' => serialize($parameters), - )) - ->execute(); -} - -/** - * Update an existing flag action. - * - * @param $aid - * The flag action ID to update. - * @param $event - * The flag event, such as "flag" or "unflag". - * @param $threshold - * The flagging threshold at which this action will be executed. - * @param $repeat_threshold - * The number of additional flaggings after which the action will be repeated. - * @param $parameters - * The action parameters. - */ -function flag_actions_update_action($aid, $event, $threshold, $repeat_threshold, $parameters) { - return db_update('flag_actions') - ->fields(array( - 'event' => $event, - 'threshold' => $threshold, - 'repeat_threshold' => $repeat_threshold, - 'parameters' => serialize($parameters), - )) - ->condition('aid', $aid) - ->execute(); -} - -/** - * Delete a flag action. - * - * @param $aid - * The flag action ID to delete. - */ -function flag_actions_delete_action($aid) { - return db_delete('flag_actions', array('return' => Database::RETURN_AFFECTED)) - ->condition('aid', $aid) - ->execute(); -} - -/** - * Perform flag actions. - */ -function flag_actions_do($event, $flag, $entity_id, $account) { - $actions = flag_actions_get_actions($flag->name); - if (!$actions) { - return; - } - - $flag_action = $flag->get_flag_action($entity_id); - $flag_action->action = $event; - $flag_action->count = $count = $flag->get_count($entity_id); - $relevant_objects = $flag->get_relevant_action_objects($entity_id); - $object_changed = FALSE; - foreach ($actions as $aid => $action) { - if ($action->event == 'flag') { - $at_threshold = ($count == $action->threshold); - $repeat = $action->repeat_threshold ? (($count > $action->threshold) && (($count - $action->threshold) % $action->repeat_threshold == 0)) : FALSE; - } - elseif ($action->event == 'unflag') { - $at_threshold = ($count == $action->threshold - 1); - $repeat = $action->repeat_threshold ? (($count < $action->threshold - 1) && (($count - $action->threshold - 1) % $action->repeat_threshold == 0)) : FALSE; - } - if (($at_threshold || $repeat) && $action->event == $event && !$action->missing) { - $context = $action->parameters; - $context['callback'] = $action->callback; - // We're setting 'hook' to something, to prevent PHP warnings by actions - // who read it. Maybe we should set it to nodeapi/comment/user, depending - // on the flag, because these three are among the only hooks some actions - // in system.module "know" to work with. - $context['hook'] = 'flag'; - $context['type'] = $action->type; - $context['account'] = $account; - $context['flag'] = $flag; - $context['flag-action'] = $flag_action; - // We add to the $context all the objects we know about: - $context = array_merge($relevant_objects, $context); - $callback = $action->callback; - - if (isset($relevant_objects[$action->type])) { - $callback($relevant_objects[$action->type], $context); - } - else { - // What object shall we send as last resort? Let's send a node, or - // the flag's object. - if (isset($relevant_objects['node'])) { - $callback($relevant_objects['node'], $context); - } - else { - $callback($relevant_objects[$flag->entity_type], $context); - } - } - - if (is_array($action->behavior) && in_array('changes_property', $action->behavior)) { - $object_changed = TRUE; - } - } - } - - // Actions by default do not save elements unless the save action is - // explicitly added. We run it automatically upon flagging. - if ($object_changed) { - $save_action = $action->type . '_save_action'; - if (function_exists($save_action)) { - $save_action($relevant_objects[$action->type]); - } - } -} - -/** - * Menu callback for FLAG_ADMIN_PATH/actions. - */ -function flag_actions_page() { - $actions = flag_actions_get_actions(); - $add_action_form = drupal_get_form('flag_actions_add_form'); - - return theme('flag_actions_page', array('actions' => $actions, 'form' => $add_action_form)); -} - -/** - * Theme the list of actions currently in place for flags. - */ -function theme_flag_actions_page($variables) { - $actions = $variables['actions']; - $add_action_form = $variables['form']; - - $rows = array(); - foreach ($actions as $action) { - $flag = flag_get_flag($action->flag); - - // Build a sample string representing repeating actions. - if ($action->repeat_threshold) { - $repeat_count = 3; - $repeat_subtract = ($action->event == 'flag') ? 1 : -1; - $repeat_samples = array(); - for ($n = 1; $n < $repeat_count + 2; $n++) { - $sample = $action->threshold + (($n * $action->repeat_threshold) * $repeat_subtract); - if ($sample > 0) { - $repeat_samples[] = $sample; - } - } - if (count($repeat_samples) > $repeat_count) { - $repeat_samples[$repeat_count] = '…'; - } - $repeat_string = implode(', ', $repeat_samples); - } - else { - $repeat_string = '-'; - } - - $row = array(); - $row[] = $flag->get_title(); - $row[] = ($action->event == 'flag' ? '≥ ' : '< ') . $action->threshold; - $row[] = $repeat_string; - $row[] = empty($action->missing) ? $action->label : '
' . $action->label . '
'; - $row[] = l(t('edit'), FLAG_ADMIN_PATH . '/actions/configure/' . $action->aid); - $row[] = l(t('delete'), FLAG_ADMIN_PATH . '/actions/delete/' . $action->aid); - $rows[] = $row; - } - - if (empty($rows)) { - $rows[] = array(array('data' => t('Currently no flag actions. Use the Add new flag action form to add an action.'), 'colspan' => 6)); - } - - $header = array( - t('Flag'), - t('Threshold'), - t('Repeats'), - t('Action'), - array('data' => t('Operations'), 'colspan' => 2), - ); - - $output = ''; - $output .= theme('table', array('header' => $header, 'rows' => $rows)); - $output .= drupal_render($add_action_form); - return $output; -} - -/** - * Modified version of the Add action form that redirects back to the flag list. - */ -function flag_actions_add_form($form, &$form_state) { - $flags = flag_get_flags(); - $options = array(); - foreach ($flags as $flag) { - $options[$flag->name] = $flag->get_title(); - } - - if (empty($options)) { - $options[] = t('No flag available'); - } - - $form['flag'] = array( - '#type' => 'select', - '#options' => empty($options) ? array(t('No flag available')) : $options, - '#disabled' => empty($options), - '#title' => t('Select a flag'), - ); - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Add action'), - ); - - return $form; -} - -function flag_actions_add_form_submit($form, &$form_state) { - if ($form_state['values']['flag']) { - $form_state['redirect'] = array(FLAG_ADMIN_PATH . '/actions/add/' . $form_state['values']['flag']); - } -} - -function theme_flag_actions_add_form($variables) { - $form = $variables['form']; - - $fieldset = array( - '#type' => 'fieldset', - '#title' => t('Add a new flag action'), - '#children' => '
'. drupal_render($form['flag']) . drupal_render($form['submit']) .'
', - '#parents' => array('add_action'), - '#attributes' => array(), - '#groups' => array('add_action' => array()), - ); - - return drupal_render($fieldset) . drupal_render_children($form); -} - -/** - * Generic configuration form for configuration of flag actions. - * - * @param $form_state - * The form state. - * @param $aid - * If editing an action, an action ID must be passed in. - * @param $flag_name - * If adding a new action to a flag, a flag name must be specified. - * - */ -function flag_actions_form($form, &$form_state, $aid = NULL, $flag_name = NULL) { - // This is a multistep form. Get the callback value if set and continue. - if (isset($form_state['storage']['callback'])) { - $callback = $form_state['storage']['callback']; - unset($form_state['storage']['callback']); - } - - if (isset($aid)) { - $action = flag_actions_get_action($aid); - $callback = $action->callback; - $flag = flag_get_flag($action->flag); - drupal_set_title(t('Edit the "@action" action for the @title flag', array('@action' => $action->label, '@title' => $flag->get_title()))); - } - elseif (isset($flag_name)) { - $flag = flag_get_flag($flag_name); - } - - if (empty($flag)) { - drupal_not_found(); - } - - $form['new'] = array( - '#type' => 'value', - '#value' => isset($callback) ? FALSE: TRUE, - ); - - if (!isset($callback)) { - drupal_set_title(t('Add an action to the @title flag', array('@title' => $flag->get_title()))); - - $actions = $flag->get_valid_actions(); - $options = array(); - foreach($actions as $key => $action) { - $options[$key] = $action['label']; - } - - $form['callback'] = array( - '#title' => t('Select an action'), - '#type' => 'select', - '#options' => $options, - ); - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Continue'), - ); - - return $form; - } - elseif (!isset($action)) { - $actions = $flag->get_valid_actions(); - $action = (object)$actions[$callback]; - $action->parameters = array(); - $action->event = 'flag'; - $action->threshold = 10; - $action->repeat_threshold = 0; - drupal_set_title(t('Add "@action" action to the @title flag', array('@action' => $action->label, '@title' => $flag->get_title()))); - } - - $form['flag'] = array( - '#tree' => TRUE, - '#weight' => -9, - '#theme' => 'flag_actions_flag_form', - '#action' => $action, - '#flag' => $flag, - ); - - $form['flag']['flag'] = array( - '#type' => 'value', - '#value' => $flag, - ); - - $form['flag']['callback'] = array( - '#type' => 'value', - '#value' => $callback, - ); - - $form['flag']['aid'] = array( - '#type' => 'value', - '#value' => $aid, - ); - - $form['flag']['event'] = array( - '#type' => 'select', - '#options' => array( - 'flag' => t('reaches'), - 'unflag' => t('falls below'), - ), - '#default_value' => $action->event, - ); - - $form['flag']['threshold'] = array( - '#type' => 'textfield', - '#size' => 6, - '#maxlength' => 6, - '#default_value' => $action->threshold, - '#required' => TRUE, - ); - - $form['flag']['repeat_threshold'] = array( - '#type' => 'textfield', - '#size' => 6, - '#maxlength' => 6, - '#default_value' => $action->repeat_threshold, - ); - - if ($flag->global) { - $form['flag']['threshold']['#disabled'] = 1; - $form['flag']['threshold']['#value'] = 1; - $form['flag']['repeat_threshold']['#access'] = FALSE; - $form['flag']['repeat_threshold']['#value'] = 0; - } - - // Merge in the standard flag action form. - $action_form = $callback .'_form'; - $edit = array(); - if (function_exists($action_form)) { - $edit += $action->parameters; - $edit['actions_label'] = $action->label; - $edit['actions_type'] = $action->type; - $edit['actions_flag'] = $flag->name; - $additions = flag_actions_form_additions($action_form, $edit); - $form = array_merge($form, $additions); - } - - // Add a few customizations to existing flag actions. - $flag_actions_form = 'flag_actions_'. $callback .'_form'; - if (function_exists($flag_actions_form)) { - $flag_actions_form($form, $flag, $edit); - } - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit'), - ); - - return $form; -} - -/** - * Execute an action form callback to retrieve form additions. - * - * This function prevents the form callback from modifying local variables. - */ -function flag_actions_form_additions($callback, $edit) { - return $callback($edit); -} - -/** - * Generic submit handler for validating flag actions. - */ -function flag_actions_form_validate($form, &$form_state) { - // Special validation handlers may be needed to save this form properly. - // Try to load the action's validation routine if needed. - if (isset($form_state['values']['flag']['callback'])) { - $callback = $form_state['values']['flag']['callback']; - $validate_function = $callback . '_validate'; - if (function_exists($validate_function)) { - $validate_function($form, $form_state); - } - } -} - -/** - * Generic submit handler for saving flag actions. - */ -function flag_actions_form_submit($form, &$form_state) { - // If simply gathering the callback, save it to form state storage and - // rebuild the form to gather the complete information. - if ($form_state['values']['new']) { - $form_state['storage']['callback'] = $form_state['values']['callback']; - $form_state['rebuild'] = TRUE; - return; - } - - $aid = $form_state['values']['flag']['aid']; - $flag = $form_state['values']['flag']['flag']; - $event = $form_state['values']['flag']['event']; - $threshold = $form_state['values']['flag']['threshold']; - $repeat_threshold = $form_state['values']['flag']['repeat_threshold']; - $callback = $form_state['values']['flag']['callback']; - - // Specialized forms may need to execute their own submit handlers on save. - $submit_function = $callback . '_submit'; - $parameters = function_exists($submit_function) ? $submit_function($form, $form_state) : array(); - - if (empty($aid)) { - $aid = flag_actions_insert_action($flag->fid, $event, $threshold, $repeat_threshold, $callback, $parameters); - $form_state['values']['flag']['aid'] = $aid; - $form_state['values']['flag']['is_new'] = TRUE; - } - else { - flag_actions_update_action($aid, $event, $threshold, $repeat_threshold, $parameters); - } - - $action = flag_actions_get_action($aid); - - drupal_set_message(t('The "@action" action for the @title flag has been saved.', array('@action' => $action->label, '@title' => $flag->get_title()))); - $form_state['redirect'] = FLAG_ADMIN_PATH . '/actions'; -} - -function theme_flag_actions_flag_form($variables) { - $form = $variables['form']; - - $event = drupal_render($form['event']); - $threshold = drupal_render($form['threshold']); - $repeat_threshold = drupal_render($form['repeat_threshold']); - $action = $form['#action']->label; - - $output = ''; - $output .= '
'; - $output .= t('Perform action when content !event !threshold flags', array('!event' => $event, '!threshold' => $threshold)); - if ($form['#flag']->global) { - $output .= ' ' . t('(global flags always have a threshold of 1)'); - } - $output .= '
'; - $output .= '
'; - if (!$form['#flag']->global) { - $output .= t('Repeat this action every !repeat_threshold additional flags after the threshold is reached', array('!repeat_threshold' => $repeat_threshold)); - } - $output .= '
'; - - $element = array( - '#title' => t('Flagging threshold'), - '#required' => TRUE, - ); - - return $output . drupal_render_children($form); -} - -function flag_actions_delete_form($form, &$form_state, $aid) { - $action = flag_actions_get_action($aid); - $flag = flag_get_flag($action->flag); - - $form['action'] = array( - '#type' => 'value', - '#value' => $action, - ); - - $form['flag'] = array( - '#type' => 'value', - '#value' => $flag, - ); - - $question = t('Delete the "@action" action for the @title flag?', array('@action' => $action->label, '@title' => $flag->get_title())); - $path = FLAG_ADMIN_PATH . '/actions'; - - return confirm_form($form, $question, $path, NULL, t('Delete')); -} - -function flag_actions_delete_form_submit(&$form, &$form_state) { - flag_actions_delete_action($form_state['values']['action']->aid); - drupal_set_message(t('The "@action" action for the @title flag has been deleted.', array('@action' => $form_state['values']['action']->label, '@title' => $form_state['values']['flag']->get_title()))); - $form_state['redirect'] = FLAG_ADMIN_PATH . '/actions'; -} - -/** - * Make modifications to the "Send e-mail" action form. - */ -function flag_actions_system_send_email_action_form(&$form, &$flag, $context) { - if (!isset($context['recipient'])) { - $form['recipient']['#default_value'] = '[site:mail]'; - } - - if (!isset($context['subject'])) { - $form['subject']['#default_value'] = t('Content Flagged @flag_title', array('@flag_title' => $flag->get_title())); - } - - if (!isset($context['message'])) { - $form['message']['#default_value'] = t("The @flag_entity_type [flag-action:content-title] has been flagged [flag-action:count] times with the @flag_title flag.\n\nView this @flag_entity_type at [flag-action:content-url].", array('@flag_entity_type' => $flag->entity_type, '@flag_title' => $flag->get_title())); - } - - $form['help'] = array( - '#type' => 'fieldset', - '#title' => t('Tokens'), - '#description' => t('The following tokens can be used in the recipient, subject, or message.'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['help']['basic'] = array( - '#markup' => theme('flag_tokens_browser', array('types' => array('flag', 'flag-action'))), - ); - - $form['help']['tokens'] = array( - '#type' => 'fieldset', - '#title' => t('More tokens'), - '#description' => t("Depending on the type of the content being flagged, the following tokens can be used in the recipients, subject, or message. For example, if the content being flagged is a node, you can use any of the node tokens --but you can't use the comment tokens: they won't be recognized. Similarly, if the content being flagged is a user, you can use only the user tokens."), - '#value' => theme('flag_tokens_browser', array('types' => $flag->get_labels_token_types(), 'global_types' => FALSE)), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); -} diff --git a/includes/flag.actions.inc b/includes/flag.actions.inc deleted file mode 100644 index f414431..0000000 --- a/includes/flag.actions.inc +++ /dev/null @@ -1,243 +0,0 @@ - array( - 'flag_flag' => array( - 'label' => t('Object has been flagged with any flag'), - ), - 'flag_unflag' => array( - 'label' => t('Object has been unflagged with any flag') - ), - ), - ); - - foreach (flag_get_flags() as $flag) { - $hooks['flag']['flag_flag_' . $flag->name]['label'] = t('A %type has been flagged with %name', array('%type' => $flag->entity_type, '%name' => $flag->name)); - $hooks['flag']['flag_unflag_' . $flag->name]['label'] = t('A %type has been unflagged with %name', array('%type' => $flag->entity_type, '%name' => $flag->name)); - } - - return $hooks; -} - -/** - * Implements hook_action_info(). - */ -function flag_action_info() { - return array( - 'flag_node_action' => array( - 'type' => 'node', - 'label' => t('Flag (or unflag) a node'), - 'configurable' => TRUE, - 'triggers' => array( - 'node_presave', 'node_insert', 'node_update', 'node_delete', 'node_view', - 'comment_insert', 'comment_update', 'comment_delete', 'comment_view', - ), - ), - 'flag_comment_action' => array( - 'type' => 'comment', - 'label' => t('Flag (or unflag) a comment'), - 'configurable' => TRUE, - 'triggers' => array( - 'comment_insert', 'comment_update', 'comment_delete', 'comment_view', - ), - ), - 'flag_user_action' => array( - 'type' => 'user', - 'label' => t('Flag (or unflag) a user'), - 'configurable' => TRUE, - 'triggers' => array( - 'user_insert', 'user_update', 'user_delete', 'user_login', 'user_logout', 'user_view', - ), - ), - ); -} - -/** - * Implements hook_action_info_alter(). - * - * Enable Flag actions on Node, Comment, and User hooks without - * the trigger_unlock.module. - */ -function flag_action_info_alter(&$actions) { - $node_flags = flag_get_flags('node'); - $comment_flags = flag_get_flags('comment'); - $user_flags = flag_get_flags('user'); - - foreach ($actions as $name => $action) { - if (strpos($name, 'node') === 0) { - $actions[$name]['triggers'][] = 'flag_flag'; - $actions[$name]['triggers'][] = 'flag_unflag'; - foreach ($node_flags as $flag) { - $actions[$name]['triggers'][] = 'flag_flag_' . $flag->name; - $actions[$name]['triggers'][] = 'flag_unflag_' . $flag->name; - } - } - if (strpos($name, 'comment') === 0) { - $actions[$name]['triggers'][] = 'flag_flag'; - $actions[$name]['triggers'][] = 'flag_unflag'; - foreach ($comment_flags as $flag) { - $actions[$name]['triggers'][] = 'flag_flag_' . $flag->name; - $actions[$name]['triggers'][] = 'flag_unflag_' . $flag->name; - } - } - if (strpos($name, 'user') === 0) { - $actions[$name]['triggers'][] = 'flag_flag'; - $actions[$name]['triggers'][] = 'flag_unflag'; - foreach ($user_flags as $flag) { - $actions[$name]['triggers'][] = 'flag_flag_' . $flag->name; - $actions[$name]['triggers'][] = 'flag_unflag_' . $flag->name; - } - } - } -} - -/** - * Implements Drupal action. Flags a node. - * - * Note the first parameter is "object" because it may be a comment or a node. - */ -function flag_node_action(&$object, $context = array()) { - if ($flag = flag_get_flag($context['flag_action']['flag'])) { - $account = isset($context['account']) ? $context['account'] : $GLOBALS['user']; - $flag->flag($context['flag_action']['op'], $object->nid, $account, TRUE); - } -} - -/** - * Form for configuring the Flag node action. - */ -function flag_node_action_form($context = array()) { - return flag_action_form($context, 'node'); -} - -/** - * Submit function for the Flag node action form. - */ -function flag_node_action_submit($form, $form_state) { - return flag_action_submit($form, $form_state); -} - -/** - * Implements Drupal action. Flags a comment. - */ -function flag_comment_action(&$comment, $context = array()) { - if ($flag = flag_get_flag($context['flag_action']['flag'])) { - $account = isset($context['account']) ? $context['account'] : $GLOBALS['user']; - $flag->flag($context['flag_action']['op'], $comment->cid, $account, TRUE); - } -} - -/** - * Form for configuring the Flag comment action. - */ -function flag_comment_action_form($context) { - return flag_action_form($context, 'comment'); -} - -/** - * Submit function for the Flag comment action form. - */ -function flag_comment_action_submit($form, $form_state) { - return flag_action_submit($form, $form_state); -} - -/** - * Implements Drupal action. Flags a user. - */ -function flag_user_action(&$user, $context = array()) { - if ($flag = flag_get_flag($context['flag_action']['flag'])) { - $account = isset($context['account']) ? $context['account'] : $GLOBALS['user']; - $flag->flag($context['flag_action']['op'], $user->uid, $account, TRUE); - } -} - -/** - * Form for configuring the Flag user action. - */ -function flag_user_action_form($context) { - return flag_action_form($context, 'user'); -} - -/** - * Submit function for the Flag user action form. - */ -function flag_user_action_submit($form, $form_state) { - return flag_action_submit($form, $form_state); -} - -/** - * Generic form for configuring Flag actions. - * - * @param $context - * The current action context. - * @param $entity_type - * The entity type applicable to this action, such as "node" or "comment". - */ -function flag_action_form($context, $entity_type) { - $form = array(); - - $flags = flag_get_flags($entity_type); - // If this is a flag_action action, do not allow the triggering flag. - if (isset($context['actions_flag'])) { - unset($flags[$context['actions_flag']]); - } - $options = drupal_map_assoc(array_keys($flags)); - - $form['flag_action']['#tree'] = TRUE; - $form['flag_action']['warning'] = array( - '#markup' => '
' . t("Note when setting a flag through actions, the selected flag will be flagged regardless of the user's permissions.") . '
', - ); - $form['flag_action']['flag'] = array( - '#title' => t('Flag to affect'), - '#type' => 'radios', - '#options' => $options, - '#required' => TRUE, - '#description' => t('When this action is fired, which flag should be flagged (or unflagged)?'), - '#default_value' => isset($context['flag_action']['flag']) ? $context['flag_action']['flag'] : reset($options), - ); - - $form['flag_action']['op'] = array( - '#title' => t('Flag operation'), - '#type' => 'radios', - '#options' => array('flag' => t('Flag'), 'unflag' => t('Unflag')), - '#description' => t('When this action is fired, which operation should be performed on the flag?'), - '#default_value' => isset($context['flag_action']['op']) ? $context['flag_action']['op'] : 'flag', - ); - - if (empty($options)) { - $error = t('There are no available %type flags. Before you can create an action of this type, you need to create a %type flag.', array('%type' => $entity_type, '!url' => url(FLAG_ADMIN_PATH . '/add'))); - $form['flag_action']['flag']['#type'] = 'item'; - $form['flag_action']['flag']['#markup'] = $error; - $form['flag_action']['flag']['#element_validate'][] = 'flag_action_validate_flag'; - $form['flag_action']['flag']['#flag_error'] = $error; - } - - return $form; -} - -/** - * Generic validation handler for validating Flag action configuration. - */ -function flag_action_validate_flag($element) { - if (isset($element['#flag_error'])) { - form_error($element, $element['#flag_error']); - } -} - -/** - * Generic submission handler for saving Flag action configuration. - */ -function flag_action_submit($form, $form_state) { - return array( - 'flag_action' => $form_state['values']['flag_action'], - ); -} diff --git a/includes/flag.admin.inc b/includes/flag.admin.inc deleted file mode 100644 index 555e5d4..0000000 --- a/includes/flag.admin.inc +++ /dev/null @@ -1,345 +0,0 @@ -name]['weight'] = array( - '#type' => 'weight', - '#delta' => count($flags) + 5, - '#default_value' => $flag->weight, - '#attributes' => array('class' => array('flag-weight')), - ); - } - - $form['actions'] = array( - '#type' => 'actions', - ); - - if (count($flags) == 1) { - // Don't show weights with only one flag. - unset($form['flags'][$flag->name]['weight']); - } - elseif (count($flags) > 1) { - // Only show the form button if there are several flags. - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save flag order'), - ); - } - - return $form; -} - -/** - * Submit handler for the flag_admin_listing form. Save flag weight ordering. - */ -function flag_admin_listing_submit($form, &$form_state) { - foreach ($form['#flags'] as $flag) { - if ($flag->weight != $form_state['values']['flags'][$flag->name]['weight']) { - $flag->weight = $form_state['values']['flags'][$flag->name]['weight']; - $flag->save(); - } - } -} - -/** - * Theme the output of the normal, database flags into a table. - */ -function theme_flag_admin_listing($variables) { - $form = $variables['form']; - $flags = $form['#flags']; - - $output = ''; - - foreach ($flags as $flag) { - $ops = array( - 'flags_edit' => array('title' => t('edit'), 'href' => $flag->admin_path('edit')), - 'flags_fields' => array('title' => t('manage fields'), 'href' => $flag->admin_path('fields')), - 'flags_delete' => array('title' => t('delete'), 'href' => $flag->admin_path('delete')), - 'flags_export' => array('title' => t('export'), 'href' => $flag->admin_path('export')), - ); - if (!module_exists('field_ui')) { - unset($ops['flags_fields']); - } - $permission = "flag $flag->name"; - $roles = user_roles(FALSE, $permission); - $row = array(); - $row[] = check_plain($flag->title) . ' (' . t('Machine name: @name', array('@name' => $flag->name)) . ')'; - if (count($flags) > 1) { - $row[] = drupal_render($form['flags'][$flag->name]['weight']); - } - $row[] = $flag->entity_type; - $row[] = empty($roles) ? '' . t('No roles') . '' : implode(', ', $roles); - $row[] = $flag->types ? implode(', ', $flag->types) : '-'; - $row[] = $flag->global ? t('Yes') : t('No'); - $row[] = theme('links', array('links' => $ops)); - - $rows[] = array( - 'data' => $row, - 'class' => array('draggable'), - ); - } - if (!$flags) { - $rows[] = array( - array('data' => t('No flags are currently defined.'), 'colspan' => 7), - ); - } - elseif (count($flags) > 1) { - drupal_add_tabledrag('flag-admin-listing-table', 'order', 'sibling', 'flag-weight'); - } - - $header = array(t('Flag')); - if (count($flags) > 1) { - $header[] = t('Weight'); - } - $header = array_merge($header, array(t('Flag type'), t('Roles'), t('Entity bundles'), t('Global?'), t('Operations'))); - $output .= theme('table', array( - 'header' => $header, - 'rows' => $rows, - 'attributes' => array('id' => 'flag-admin-listing-table'), - )); - $output .= drupal_render_children($form); - - return $output; -} - -/** - * Theme the list of disabled flags into a table. - */ -function theme_flag_admin_listing_disabled($variables) { - $flags = $variables['flags']; - $default_flags = $variables['default_flags']; - $output = ''; - - // Build a list of disabled, module-based flags. - $rows = array(); - foreach ($default_flags as $name => $flag) { - if (!isset($flags[$name])) { - $ops = array(); - if (!$flag->is_compatible()) { - $flag_updates_needed = TRUE; - $ops['flags_update'] = array('title' => '' . t('update code') . '', 'href' => $flag->admin_path('update'), 'html' => TRUE); - } - else { - $ops['flags_enable'] = array('title' => t('enable'), 'href' => $flag->admin_path('edit')); - } - // $flag->roles['flag'] not exist on older flags. - $roles = array_flip(array_intersect(array_flip(user_roles()), !empty($flag->roles['flag']) ? $flag->roles['flag'] : array())); - $rows[] = array( - $flag->name, - $flag->module, - $flag->entity_type ? $flag->entity_type : t('Unknown'), - theme('links', array('links' => $ops)), - ); - } - } - - if (isset($flag_updates_needed)) { - drupal_set_message(t('Some flags provided by modules need to be updated to a new format before they can be used with this version of Flag. See the disabled flags for a list of flags that need updating.'), 'warning'); - } - - if (!empty($rows)) { - $header = array(t('Disabled Flags'), t('Module'), t('Flag type'), t('Operations')); - $output .= theme('table', array('header' => $header, 'rows' => $rows)); - } - - return $output; -} - -/** - * FormAPI after_build function set states on link type options fieldsets. - * - * We do this in an after build so we handle further link types fieldsets from - * other modules that provide link types. - * - * This expects a link type's fieldset to be $form['display'][link_options_TYPE] - * so that can be matched up with the radio button value. - */ -function flag_link_type_options_states($element) { - $intro_element_values_array = array(); - foreach (element_children($element) as $key) { - if (isset($element[$key]['#type']) && $element[$key]['#type'] == 'fieldset' && substr($key, 0, 12) == 'link_options') { - // Trim the radio value from the fieldset key. This assumed the fieldset - // key is 'link_options_TYPE'. - $radio_value = substr($key, 13); - $element[$key]['#states'] = array( - 'visible' => array( - ':input[name="link_type"]' => array('value' => $radio_value), - ), - ); - // Gather up the radio values for the format we need for a multiple - // value state. - $intro_element_values_array[] = array('value' => $radio_value); - } - } - - $element['link_options_intro']['#states'] = array( - 'visible' => array( - ':input[name="link_type"]' => $intro_element_values_array, - ), - ); - - return $element; -} - -/** - * Form process handler for locking flag properties. - * - * Flags defined in code may define an array of properties in $flag->locked that - * are to be locked and may not be edited by the user. - */ -function flag_form_locked_process($element, &$form_state, $form) { - $flag = $form['#flag']; - - // Disable access to a form element whose name matches a locked flag property. - if (isset($element['#name']) && !empty($flag->locked[$element['#name']])) { - $element['#access'] = FALSE; - } - - // Recurse into the form array. - foreach (element_children($element) as $key) { - // Workaround for Core inconvenience: setting #process here prevents an - // element's essential #process handlers from its hook_element_info() - // definition from being set in form_builder(). - // @see http://drupal.org/node/1779496 - if (isset($element[$key]['#type']) && ($info = element_info($element[$key]['#type']))) { - if (isset($info['#process'])) { - $element[$key]['#process'] = $info['#process']; - } - } - - $element[$key]['#process'][] = 'flag_form_locked_process'; - } - - return $element; -} - -/** - * Output the access options for roles in a table. - */ -function theme_flag_form_roles($variables) { - $element = $variables['element']; - - $header = array( - array('class' => array('checkbox'), 'data' => t('Flag')), - array('class' => array('checkbox'), 'data' => t('Unflag')), - t('Role'), - ); - $rows = array(); - foreach (element_children($element['flag']) as $role) { - $row = array(); - $role_name = $element['flag'][$role]['#title']; - unset($element['flag'][$role]['#title']); - unset($element['unflag'][$role]['#title']); - $element['flag'][$role]['#attributes']['class'] = array('flag-access'); - $element['unflag'][$role]['#attributes']['class'] = array('unflag-access'); - $row[] = array('class' => array('checkbox'), 'data' => drupal_render($element['flag'][$role])); - $row[] = array('class' => array('checkbox'), 'data' => drupal_render($element['unflag'][$role])); - $row[] = $role_name; - $rows[] = $row; - } - - return theme('table', array( - 'header' => $header, - 'rows' => $rows, - 'attributes' => array( - 'class' => array('flag-admin-table'), - 'id' => 'flag-roles', - ), - )); -} - -/** - * Delete flag page. - */ -function flag_delete_confirm($form, &$form_state, $flag) { - $form['#flag'] = $flag; - - return confirm_form($form, - t('Are you sure you want to delete %title?', array('%title' => $flag->get_title())), - !empty($_GET['destination']) ? $_GET['destination'] : FLAG_ADMIN_PATH, - isset($flag->module) ? t('This flag is provided by the %module module. It will lose any customizations and be disabled.', array('%module' => $flag->module)) : t('This action cannot be undone.'), - t('Delete'), t('Cancel') - ); -} - -function flag_delete_confirm_submit($form, &$form_state) { - $flag = $form['#flag']; - if ($form_state['values']['confirm']) { - $flag->delete(); - $flag->disable(); - _flag_clear_cache($flag->entity_type, TRUE); - } - drupal_set_message(t('Flag @name has been deleted.', array('@name' => $flag->get_title()))); - $form_state['redirect'] = FLAG_ADMIN_PATH; -} - -/** - * FormAPI after_build function to check that the link type exists. - */ -function flag_check_link_types($element) { - $link_types = flag_get_link_types(); - if (!isset($link_types[$element['#value']])) { - drupal_set_message(t('This flag uses a link type of %type, which does not exist.', array('%type' => $element['#value'])), 'error'); - } - return $element; -} - -/** - * Clears various caches when one or more flags are modified. - * - * @param $entity_types - * The entity types for the flags. May be a single value or an array. - * @param $is_insert_or_delete - * Whether the modified flag is being inserted (saved for the first time) or - * deleted. This results in a more vigorous clearing of caches. In - * particular, when no flags exist yet, no Field admin UI paths exist and these - * need to be created. - */ -function _flag_clear_cache($entity_types, $is_insert_or_delete = FALSE) { - if (!is_array($entity_types)) { - $entity_types = array($entity_types); - } - - // Reset our flags cache, thereby making the following code aware of the - // modifications. - drupal_static_reset('flag_get_flags'); - - if ($is_insert_or_delete) { - // A new or deleted flag means we are changing bundles on the Flagging - // entity, and thus need to clear the entity info cache. - entity_info_cache_clear(); - } - - // Clear FieldAPI's field_extra cache, so our changes to pseudofields are - // noticed. It's rather too much effort to both a) check whether the - // pseudofield setting has changed either way, and b) specifically clear just - // the bundles that are (or were!!) affected, so we just clear for all bundles - // on our entity type regardlesss. - foreach ($entity_types as $entity_type) { - cache_clear_all("field_info:bundle_extra:$entity_type:", 'cache_field', TRUE); - } - - if (module_exists('views')) { - views_invalidate_cache(); - } - - // The title of a flag may appear in the menu (indirectly, via our "default - // views"), so we need to clear the menu cache. This call also clears the - // page cache, which is desirable too because the flag labels may have - // changed. - menu_rebuild(); -} diff --git a/includes/flag.cookie_storage.inc b/includes/flag.cookie_storage.inc deleted file mode 100644 index 856f582..0000000 --- a/includes/flag.cookie_storage.inc +++ /dev/null @@ -1,170 +0,0 @@ -flag(145); - * $storage->unflag(17); - * @endcode - * - * You may delete all the cookies with FlagCookieStorage::drop(). - */ -abstract class FlagCookieStorage { - - /** - * Returns the actual storage object compatible with the flag. - */ - static function factory($flag) { - if ($flag->global) { - return new FlagGlobalCookieStorage($flag); - } - else { - return new FlagNonGlobalCookieStorage($flag); - } - } - - function __construct($flag) { - $this->flag = $flag; - } - - /** - * "Flags" an item. - * - * It just records this fact in a cookie. - */ - abstract function flag($entity_id); - - /** - * "Unflags" an item. - * - * It just records this fact in a cookie. - */ - abstract function unflag($entity_id); - - /** - * Deletes all the cookies. - * - * (Etymology: "drop" as in "drop database".) - */ - static function drop() { - FlagGlobalCookieStorage::drop(); - FlagNonGlobalCookieStorage::drop(); - } -} - -/** - * Storage handler for global flags. - */ -class FlagGlobalCookieStorage extends FlagCookieStorage { - - function flag($entity_id) { - $cookie_key = $this->cookie_key($entity_id); - setcookie($cookie_key, 1, REQUEST_TIME + $this->get_lifetime(), base_path()); - $_COOKIE[$cookie_key] = 1; - } - - function unflag($entity_id) { - $cookie_key = $this->cookie_key($entity_id); - setcookie($cookie_key, 0, REQUEST_TIME + $this->get_lifetime(), base_path()); - $_COOKIE[$cookie_key] = 0; - } - - // Global flags persist for the length of the minimum cache lifetime. - protected function get_lifetime() { - $cookie_lifetime = variable_get('cache', 0) ? variable_get('cache_lifetime', 0) : -1; - // Do not let the cookie lifetime be 0 (which is the no cache limit on - // anonymous page caching), since it would expire immediately. Usually - // the no cache limit means caches are cleared on cron, which usually runs - // at least once an hour. - if ($cookie_lifetime == 0) { - $cookie_lifetime = 3600; - } - return $cookie_lifetime; - } - - protected function cookie_key($entity_id) { - return 'flag_global_' . $this->flag->name . '_' . $entity_id; - } - - /** - * Deletes all the global cookies. - */ - static function drop() { - foreach ($_COOKIE as $key => $value) { - if (strpos($key, 'flag_global_') === 0) { - setcookie($key, FALSE, 0, base_path()); - unset($_COOKIE[$key]); - } - } - } -} - -/** - * Storage handler for non-global flags. - */ -class FlagNonGlobalCookieStorage extends FlagCookieStorage { - - // The anonymous per-user flaggings are stored in a single cookie, so that - // all of them persist as long as the Drupal cookie lifetime. - - function __construct($flag) { - parent::__construct($flag); - $this->flaggings = isset($_COOKIE['flags']) ? explode(' ', $_COOKIE['flags']) : array(); - } - - function flag($entity_id) { - if (!$this->is_flagged($entity_id)) { - $this->flaggings[] = $this->cookie_key($entity_id); - $this->write(); - } - } - - function unflag($entity_id) { - if (($index = $this->index_of($entity_id)) !== FALSE) { - unset($this->flaggings[$index]); - $this->write(); - } - } - - protected function get_lifetime() { - return min((int) ini_get('session.cookie_lifetime'), (int) ini_get('session.gc_maxlifetime')); - } - - protected function cookie_key($entity_id) { - return $this->flag->name . '_' . $entity_id; - } - - protected function write() { - $serialized = implode(' ', array_filter($this->flaggings)); - setcookie('flags', $serialized, REQUEST_TIME + $this->get_lifetime(), base_path()); - $_COOKIE['flags'] = $serialized; - } - - protected function is_flagged($entity_id) { - return $this->index_of($entity_id) !== FALSE; - } - - protected function index_of($entity_id) { - return array_search($this->cookie_key($entity_id), $this->flaggings); - } - - /** - * Deletes the cookie. - */ - static function drop() { - if (isset($_COOKIE['flags'])) { - setcookie('flags', FALSE, 0, base_path()); - unset($_COOKIE['flags']); - } - } -} diff --git a/includes/flag.entity.inc b/includes/flag.entity.inc deleted file mode 100644 index 55dba6a..0000000 --- a/includes/flag.entity.inc +++ /dev/null @@ -1,24 +0,0 @@ -flaggings fieldable, not the flags. - * (In the same way that Drupal makes nodes fieldable, not node - * types). - */ - -/** - * Controller class for flaggings. - */ -class FlaggingController extends DrupalDefaultEntityController { - - protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) { - $query = parent::buildQuery($ids, $conditions, $revision_id); - // Add the flag name, which determines the bundle. - $query->innerJoin('flag', 'flag', 'base.fid = flag.fid'); - $query->addField('flag', 'name', 'flag_name'); - return $query; - } -} diff --git a/includes/flag.export.inc b/includes/flag.export.inc deleted file mode 100644 index 9285722..0000000 --- a/includes/flag.export.inc +++ /dev/null @@ -1,138 +0,0 @@ -is_compatible()) { - drupal_set_message(t('Could not export flag %flag-name: Your flag was created by a different version of the Flag module than is now being used.', array('%flag-name' => $flag->name)), 'error'); - continue; - } - - $flag->api_version = FLAG_API_VERSION; - $new_flag = (array) $flag; - - if (!empty($module)) { - // Even though Flag adds the module name itself later, we add the module - // name here for reference by other modules (such as Features). - $new_flag['module'] = $module; - // Lock the flag name, as is normally desired by modules using - // hook_flag_default_flags(), and needed by Features. - $new_flag['locked'] = array('name'); - } - // Allow other modules to change the exported flag. - drupal_alter('flag_export', $new_flag); - - // Remove properties we don't export. - $unset_properties = array( - // Remove the flag ID. - 'fid', - // The name is emitted as the key for the array. - 'name', - // The entity info is just used as helper data. - 'entity_info', - // Remove roles. - 'roles', - // Remove errors. - 'errors', - ); - foreach ($unset_properties as $property) { - unset($new_flag[$property]); - } - - $output .= $indent . '// Exported flag: "' . check_plain($flag->get_title()) . '"' . ".\n"; - $output .= $indent . '$flags[\'' . $flag->name . '\'] = ' . (function_exists('features_var_export') ? features_var_export($new_flag, $indent) : var_export($new_flag, TRUE)) . ";\n"; - } - $output .= $indent . 'return $flags;' . "\n"; - return $output; -} - -/** - * Page for displaying an upgrade message and export form for Flag 1.x flags. - */ -function flag_update_page($flag) { - if ($flag->is_compatible()) { - drupal_set_message(t('The flag %name is already up-to-date with the latest Flag API and does not need upgrading.', array('%name' => $flag->name))); - drupal_goto(FLAG_ADMIN_PATH); - } - - drupal_set_message(t('The flag %name is currently using the Flag API version @version, which is not compatible with the current version of Flag. You can upgrade this flag by pasting the below code into @module_flag_default_flags() function in the @module.module file.', array('%name' => $flag->name, '@version' => $flag->api_version, '@module' => $flag->module)), 'warning'); - - flag_update_export($flag); - - return drupal_get_form('flag_export_form', $flag); -} - -/** - * Update a flag before export. - * - * @param $flag - * The flag object passed by reference. - */ -function flag_update_export(&$flag) { - // Set the API version to 1 by default: version 1 did not explicitly define - // the API version. - if (empty($flag->api_version)) { - $flag->api_version = 1; - } - - // Get all our update classes. - // This is not terribly graceful, but the alternative is declaring our classes - // explicitly, or registering them with the Drupal autoloader and then running - // a database query, which seems a waste of space given we only ever need - // these here. - $classes = get_declared_classes(); - $update_handlers = array(); - foreach ($classes as $class) { - // Any class whose name is of the form 'FlagUpdate_foo' is one of ours, we - // assume. Should this prove problematic, we can add use of reflection here. - if (substr($class, 0, 11) == 'FlagUpdate_') { - // @todo: change this to work with the static class when we drop support - // for PHP 5.2: see commit d5b517. - $update_handler = new $class; - // Cast to string, as decimals as array keys seem to be rounded down to - // ints, WTF PHP? - $version = (string) $update_handler->old_api_version; - - $update_handlers[$version] = $update_handler; - } - } - // Sort the classes by old version number. - uksort($update_handlers, 'version_compare'); - - // Work through each update handler. - foreach ($update_handlers as $old_api_version => $update_handler) { - // Skip update classes that are older than our current flag. - if (version_compare($old_api_version, $flag->api_version, '<')) { - continue; - } - - // Run the update and change the API version on the flag. - $update_handler->update($flag); - $flag->api_version = $update_handler->new_api_version; - } -} diff --git a/includes/flag.features.inc b/includes/flag.features.inc deleted file mode 100644 index 9374930..0000000 --- a/includes/flag.features.inc +++ /dev/null @@ -1,124 +0,0 @@ - $flag) { - $module = ''; - if ($flag = flag_load($flag, TRUE)) { - // Try to get the module that provides the entity this flag is on. - // First pass: check whether there's a module that implements - // hook_flag_type_info() for this entity. - if (array_key_exists($flag->entity_type, $modules)) { - $module = $modules[$flag->entity_type]; - } - else { - // Second pass: check whether this entity is defined using Entity API - // and therefore has an extra 'module' property in its information. - if ($entity_info = entity_get_info($flag->entity_type)) { - if (isset($entity_info['module'])) { - $module = $entity_info['module']; - } - } - } - - if (!empty($module)) { - $export['dependencies'][$module] = $module; - } - - $export['features']['flag'][$flag->name] = $flag->name; - } - } - - return $pipe; -} - -/** - * Implements hook_features_export_options(). - */ -function flag_features_export_options() { - $options = array(); - // Get all flags, including disabled defaults. - $flags = flag_get_flags() + flag_get_default_flags(TRUE); - foreach ($flags as $name => $flag) { - $options[$name] = drupal_ucfirst(check_plain($flag->entity_type)) . ': ' . check_plain($flag->title); - } - return $options; -} - -/** - * Implements hook_features_export_render(). - */ -function flag_features_export_render($module, $data) { - module_load_include('inc', 'flag', '/includes/flag.export'); - $code = flag_export_flags($data, $module, ' '); - return array('flag_default_flags' => $code); -} - -/** - * Implements hook_features_revert(). - * - * @param $module - * The name of module for which to revert content. - */ -function flag_features_revert($module = NULL) { - // Get default flags from features. - if (module_hook($module, 'flag_default_flags')) { - module_load_include('inc', 'flag', '/includes/flag.admin'); - $default_flags = module_invoke($module, 'flag_default_flags'); - - // Build up values for the cache clear. - $entity_types = array(); - - // Revert flags that are defined in code. - foreach ($default_flags as $flag_name => $flag_info) { - if (is_numeric($flag_name)) { - // Backward compatibility. - $flag_name = $flag_info['name']; - } - $flag = flag_load($flag_name, TRUE); - if ($flag && $flag->revert() === FALSE) { - drupal_set_message(t('Could not revert flag %flag-name to the state described in your code: Your flag was created by a different version of the Flag module than is now being used.', array('%flag-name' => $flag->name)), 'error'); - } - - $entity_types[] = $flag->entity_type; - } - _flag_clear_cache($entity_types); - } -} - -/** - * Helper function; Retrieve the providing modules defining the flags. - */ -function flag_features_providing_module() { - $modules = array(); - $hook = 'flag_type_info'; - foreach (module_implements($hook) as $module) { - foreach (module_invoke($module, $hook) as $key => $value) { - $modules[$key] = isset($value['module']) ? $value['module'] : $module; - } - } - - // Any entity type without a flag providing module will be provided by the - // flag module. - foreach (entity_get_info() as $entity_type => $entity) { - if (!isset($modules[$entity_type]) && empty($entity['configuration']) && $entity_type !== 'taxonomy_vocabulary') { - $modules[$entity_type] = 'flag'; - } - } - - return $modules; -} diff --git a/includes/flag.pages.inc b/includes/flag.pages.inc deleted file mode 100644 index cfb91ba..0000000 --- a/includes/flag.pages.inc +++ /dev/null @@ -1,165 +0,0 @@ -errors['token'] = t('Bad token. You seem to have followed an invalid link.'); - } - elseif ($user->uid == 0 && !$has_js) { - $flag->errors['javascript'] = t('You must have JavaScript and cookies enabled in your browser to flag content.'); - } - - // If no errors have been detected thus far, perform the flagging. - // Further errors may still be detected during validation and prevent - // the operation from succeeding. - if (!$flag->errors) { - $flag->flag($action, $entity_id); - } - - // If successful, return data according to the request type. - if ($js) { - drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); - $flag->link_type = 'toggle'; - // Any errors that have been set will be output below - // the flag link with javascript. - print drupal_json_encode(flag_build_javascript_info($flag, $entity_id)); - drupal_exit(); - } - else { - $errors = $flag->get_errors(); - if ($errors) { - // If an error was received, set a message and exit. - foreach ($errors as $error) { - drupal_set_message($error, 'error'); - } - if (isset($errors['access-denied'])) { - return MENU_ACCESS_DENIED; - } - else { - drupal_goto(); - } - } - else { - drupal_set_message($flag->get_label($action . '_message', $entity_id)); - drupal_goto(); - } - } -} - -/** - * Form for confirming the (un)flagging of an entity. - * - * @param $action - * Either 'flag' or 'unflag'. - * @param $flag - * A loaded flag object. - * @param $entity_id - * The id of the entity to operate on. The type is implicit in the flag. - * - * @see flag_confirm_submit() - */ -function flag_confirm($form, &$form_state, $action, $flag, $entity_id) { - $form['#flag'] = $flag; - $form['action'] = array( - '#type' => 'value', - '#value' => $action, - ); - $form['entity_id'] = array( - '#type' => 'value', - '#value' => $entity_id, - ); - - $question = $flag->get_label($action . '_confirmation', $entity_id); - $path = isset($_GET['destination']) ? $_GET['destination'] : ''; - $yes = $flag->get_label($action . '_short', $entity_id); - - if ($action == 'flag') { - // If the action 'flag', we're potentially about to create a new - // flagging entity. We need an empty new entity to pass to FieldAPI. - $flagging = $flag->new_flagging($entity_id); - field_attach_form('flagging', $flagging, $form, $form_state); - $form['#flagging'] = $flagging; - } - - return confirm_form($form, $question, $path, '', $yes); -} - -/** - * Submit handler for the flag confirm form. - * - * Note that validating whether the user may perform the action is done here, - * rather than in a form validation handler. - * - * @see flag_confirm() - */ -function flag_confirm_submit(&$form, &$form_state) { - $flag = $form['#flag']; - $action = $form_state['values']['action']; - $entity_id = $form_state['values']['entity_id']; - - if ($action == 'flag') { - // If the action 'flag', further build up the new entity from form values. - $flagging = $form['#flagging']; - entity_form_submit_build_entity('flagging', $flagging, $form, $form_state); - - $result = $flag->flag($action, $entity_id, NULL, FALSE, $flagging); - } - else { - $result = $flag->flag($action, $entity_id, NULL, FALSE); - } - - if (!$result) { - if ($errors = $flag->get_errors()) { - foreach ($errors as $error) { - drupal_set_message($error, 'error'); - } - } - } - else { - drupal_set_message($flag->get_label($action . '_message', $entity_id)); - } -} - -/** - * Builds the JavaScript structure describing the flagging operation. - */ -function flag_build_javascript_info($flag, $entity_id) { - $errors = $flag->get_errors(); - $info = array( - 'status' => TRUE, - 'newLink' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array( - 'after_flagging' => TRUE, - 'errors' => $errors, - )), - // Further information for the benefit of custom JavaScript event handlers: - 'flagSuccess' => !$errors, - 'contentId' => $entity_id, - 'entityType' => $flag->entity_type, - 'flagName' => $flag->name, - 'flagStatus' => $flag->is_flagged($entity_id) ? 'flagged' : 'unflagged', - ); - drupal_alter('flag_javascript_info', $info); - return $info; -} diff --git a/includes/views/flag.views.inc b/includes/views/flag.views.inc deleted file mode 100644 index 4d3c216..0000000 --- a/includes/views/flag.views.inc +++ /dev/null @@ -1,272 +0,0 @@ - array( - 'flag_flaggable_node' => array( - 'title' => t('Flaggable node'), - 'flag type' => 'node', - 'handler' => 'flag_plugin_argument_validate_flaggability', - 'path' => drupal_get_path('module', 'flag') . '/includes', - ), - 'flag_flaggable_user' => array( - 'title' => t('Flaggable user'), - 'flag type' => 'user', - 'handler' => 'flag_plugin_argument_validate_flaggability', - 'path' => drupal_get_path('module', 'flag') . '/includes', - ), - // A comment validator won't be very useful. Moreover, having it will - // contribute to the argument object's $options polution, so let's skip - // it. - ), - ); -} -/** - * Implements hook_views_data(). - */ -function flag_views_data() { - $data = array(); - - $data['flagging']['table']['group'] = t('Flags'); - $data['flag_counts']['table']['group'] = t('Flags'); - - // Notify views from flag 2.x of our changes to views data. - // @see flag_update_7301(). - $data['flag_content']['moved to'] = 'flagging'; - // @see flag_update_7303(). - $data['flag_content']['content_id']['moved to'] = array('flagging', 'entity_id'); - - $data['flagging']['uid'] = array( - 'title' => t('User uid'), - 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), - 'relationship' => array( - 'base' => 'users', - 'title' => t('User'), - 'help' => t('Relate an item to the user that flagged it.'), - 'handler' => 'views_handler_relationship', - 'label' => t('Flag user'), - ), - 'filter' => array( - 'handler' => 'views_handler_filter_user_name', - ), - 'argument' => array( - 'handler' => 'views_handler_argument_numeric', - ), - 'field' => array( - 'handler' => 'views_handler_field_user', - ), - ); - - $data['flagging']['timestamp'] = array( - 'title' => t('Flagged time'), - 'help' => t('Display the time the content was flagged by a user.'), - 'field' => array( - 'handler' => 'views_handler_field_date', - 'click sortable' => TRUE, - ), - 'sort' => array( - 'handler' => 'views_handler_sort_date', - ), - 'filter' => array( - 'handler' => 'views_handler_filter_date', - ), - 'argument' => array( - 'handler' => 'views_handler_argument_date', - ), - ); - - // Argument for content ID, used for "Who's flagged this" views. - $data['flagging']['entity_id'] = array( - 'title' => t('Content ID'), - 'help' => t('The unique ID of the object that has been flagged.'), - 'argument' => array( - 'handler' => 'flag_handler_argument_entity_id', - ), - ); - - // Specialized is null/is not null filter. - $data['flagging']['flagged'] = array( - 'title' => t('Flagged'), - 'real field' => 'uid', - 'field' => array( - 'handler' => 'flag_handler_field_flagged', - 'label' => t('Flagged'), - 'help' => t('A boolean field to show whether the flag is set or not.'), - ), - 'filter' => array( - 'handler' => 'flag_handler_filter_flagged', - 'label' => t('Flagged'), - 'help' => t('Filter to ensure content has or has not been flagged.'), - ), - 'sort' => array( - 'handler' => 'flag_handler_sort_flagged', - 'label' => t('Flagged'), - 'help' => t('Sort by whether entities have or have not been flagged.'), - ), - ); - - // Flag content links. - $data['flagging']['ops'] = array( - 'title' => t('Flag link'), - 'help' => t('Display flag/unflag link.'), - 'field' => array( - 'handler' => 'flag_handler_field_ops', - ), - ); - - $data['flag_counts']['count'] = array( - 'title' => t('Flag counter'), - 'help' => t('The number of times a piece of content is flagged by any user.'), - 'field' => array( - 'handler' => 'views_handler_field_numeric', - 'click sortable' => TRUE, - ), - 'sort' => array( - 'handler' => 'views_handler_sort', - ), - 'filter' => array( - 'handler' => 'views_handler_filter_numeric', - ), - 'argument' => array( - 'handler' => 'views_handler_argument_numeric', - ), - ); - - $data['flag_counts']['last_updated'] = array( - 'title' => t('Time last flagged'), - 'help' => t('The time a piece of content was most recently flagged by any user.'), - 'field' => array( - 'handler' => 'views_handler_field_date', - 'click sortable' => TRUE, - ), - 'sort' => array( - 'handler' => 'views_handler_sort_date', - ), - 'filter' => array( - 'handler' => 'views_handler_filter_date', - ), - 'argument' => array( - 'handler' => 'views_handler_argument_date', - ), - ); - - return $data; -} - -/** - * Implements hook_views_data_alter(). - */ -function flag_views_data_alter(&$data) { - - foreach (array_keys(flag_fetch_definition()) as $flag_type) { - $flag = flag_flag::factory_by_entity_type($flag_type); - $info = $flag->get_views_info(); - - if (!isset($info)) { - continue; - } - - if (!empty($info['join field'])) { - // Add the flag relationship. - $data[$info['views table']]['flag_content_rel'] = array( - 'group' => t('Flags'), - 'title' => $info['title'], - 'help' => $info['help'], - 'relationship' => array( - 'flag type' => $flag_type, - 'handler' => 'flag_handler_relationship_content', - 'label' => t('flag'), - 'base' => 'flagging', - 'base field' => 'entity_id', - 'relationship field' => $info['join field'], - ), - ); - - // Add the flag counter relationship. - $data[$info['views table']]['flag_count_rel'] = array( - 'group' => t('Flags'), - 'title' => $info['counter title'], - 'help' => $info['counter help'], - 'relationship' => array( - 'flag type' => $flag_type, - 'handler' => 'flag_handler_relationship_counts', - 'label' => t('counter'), - 'base' => 'flag_counts', - 'base field' => 'entity_id', - 'relationship field' => $info['join field'], - ), - ); - } - } - - // Add a relationship for the user that flagged any type of content. - $data['users']['flag_user_content_rel'] = array( - 'group' => t('Flags'), - 'title' => t("User's flaggings"), - 'help' => t('Relate users to the flaggings they have made on objects, using a particular flag.'), - 'relationship' => array( - 'base' => 'flagging', - 'base field' => 'uid', - 'relationship field' => 'uid', - 'handler' => 'flag_handler_relationship_user_content', - 'label' => t('user flagged content'), - ), - ); -} - -/** - * Implements hook_views_query_substitutions(). - * - * Allow replacement of current user's session id so we can cache these queries. - */ -function flag_views_query_substitutions() { - return array( - '***FLAG_CURRENT_USER_SID***' => flag_get_sid(), - ); -} -/** - * A helper function that creates a radio list of available flags. - * - * This function is used to select the desired flag when setting up flag - * relationships and fields. - */ -function flag_views_flag_config_form($form_type, $entity_type, $current_flag) { - $flags = flag_get_flags($entity_type); - - $options = array(); - foreach ($flags as $flag) { - $options[$flag->name] = $flag->get_title(); - } - - $form = array( - '#type' => $form_type, - '#title' => t('Flag'), - '#options' => $options, - '#default_value' => $current_flag, - '#required' => TRUE, - ); - - return $form; -} - -/** - * Helper function that gets the first defined flag and returns its name. - */ -function flag_views_flag_default($entity_type) { - $default_flag = &drupal_static(__FUNCTION__, array()); - - if (!array_key_exists($entity_type, $default_flag)) { - $flag = array_shift(flag_get_flags($entity_type)); - $default_flag[$entity_type] = $flag ? $flag->name : NULL; - } - - return $default_flag[$entity_type]; -} diff --git a/includes/views/flag.views_convert.inc b/includes/views/flag.views_convert.inc deleted file mode 100644 index ed8910d..0000000 --- a/includes/views/flag.views_convert.inc +++ /dev/null @@ -1,235 +0,0 @@ -add_item() won't produce - * the right results, usually needed to set field options or values. - */ -function flag_views_convert($display, $type, &$view, $field, $id) { - static $flag_name; - - // First, replace any sign of views_bookmark with flag's Views 1 equivelant. - $key_search = array( - '^views_bookmark_ops_([0-9]+)' => 'flag_ops_', - '^views_bookmark_nodes_([0-9]+)' => 'flag_content_', - '^views_bookmark_users_([0-9]+)' => 'flag_users_', - '^views_bookmark_node_count_([0-9]+)' => 'flag_counts_', - ); - foreach ($field as $property => $value) { - foreach ($key_search as $search => $replace) { - if (!empty($value) && is_string($value) && preg_match('/' . $search . '/', $value, $matches)) { - $flag = flag_get_flag(NULL, $matches[1]); - $replace = $replace . $flag->name; - $field[$property] = preg_replace('/' . $search . '/', $replace, $value); - } - } - } - - // Create a table/field identifier for this field. - foreach (array('flag_ops_', 'flag_content_', 'flag_users_', 'flag_counts_') as $table) { - if (strpos($field['tablename'], $table) === 0) { - $name = str_replace($table, '', $field['tablename']); - if (!empty($name) && !isset($flag_name)) { - $flag_name = $name; - } - } - } - - // Now update values, options, etc. to those selected in the imported view. - switch ($type) { - case 'field': - switch ($id) { - case 'ops': - $new_field = array( - 'label' => $field['label'], - 'id' => 'ops', - 'table' => 'flagging', - 'field' => 'ops', - 'relationship' => 'flag_content_rel', - ); - $new_rel = 'flag_content_rel'; - $flag_content_rel_user = 'current'; - break; - case 'count': - $new_field = array( - 'label' => $field['label'], - 'id' => 'count', - 'table' => 'flag_counts', - 'field' => 'count', - 'relationship' => 'flag_counts_rel', - ); - $new_rel = 'flag_counts_rel'; - break; - case 'name': - $new_field = array( - 'label' => $field['label'], - 'link_to_user' => 1, - 'id' => 'name', - 'table' => 'users', - 'field' => 'name', - 'relationship' => 'uid', - ); - $new_rel = 'uid'; - break; - } - break; - - case 'filter': - case 'exposed_filter': - switch ($id) { - case 'uid': - // The flagging uid filter means "Include content only flagged by - // the current user". In D6, this is no longer a filter, but instead - // part of the relationship. Make the relationship join on the uid. - if ($field['value'] == '***CURRENT_USER***') { - $new_rel = 'flag_content_rel'; - $flag_content_rel_user = 'current'; - } - // Remove the old filter. - $view->set_item('default', $type, $id, NULL); - break; - case 'timestamp': - $new_field = array( - 'operator' => $field['operator'], - 'value' => flag_views_convert_timestamp_value($field['value']), - 'group' => 0, - 'id' => 'timestamp', - 'table' => 'flagging', - 'field' => 'timestamp', - 'relationship' => 'flag_content_rel', - 'exposed' => $type == 'exposed_filter' ? 1 : 0, - ); - $new_rel = 'flag_content_rel'; - drupal_set_message(t('Flag is not able to convert the Flagged time filter. It\'s value is currently empty, but needs to be populated to work properly.'), 'warning'); - break; - case 'count': - $new_field = array( - 'operator' => $field['operator'], - 'value' => array('value' => $field['value']), - 'group' => 0, - 'id' => 'count', - 'table' => 'flag_counts', - 'field' => 'count', - 'relationship' => 'flag_counts_rel', - 'exposed' => $type == 'exposed_filter' ? 1 : 0, - ); - $new_rel = 'flag_counts_rel'; - break; - } - break; - - case 'argument': - // Flag in Drupal 5 only provides one argument, and in Views 1 arguments - // weren't given and ID, so we use the field type. - if (strpos($field['type'], 'flag_content_') === 0) { - $new_field = array( - 'id' => 'uid', - 'table' => 'users', - 'field' => 'uid', - 'relationship' => 'uid', - ); - $new_rel = 'uid'; - } - break; - - case 'sort': - switch ($id) { - case 'count': - $new_field = array( - 'order' => $field['sortorder'], - 'id' => 'count', - 'table' => 'flag_counts', - 'field' => 'count', - 'relationship' => 'flag_counts_rel', - ); - $new_rel = 'flag_counts_rel'; - break; - case 'timestamp': - $new_field = array( - 'order' => $field['sortorder'], - 'id' => 'timestamp', - 'table' => 'flagging', - 'field' => 'timestamp', - 'relationship' => 'flag_content_rel', - ); - $new_rel = 'flag_content_rel'; - break; - } - break; - } - - // Add any new fields. - if (isset($new_field)) { - // Exposed filters are now wrapped into filters. - $type = $type == 'exposed_filter' ? 'filter' : $type; - // Update the type in the view options. - $view->set_item('default', $type, $id, $new_field); - } - - // Add any new relationships (but only once per view). - if (isset($new_rel) && !isset($view->display[$display]->display_options['relationships'][$new_rel])) { - if ($new_rel == 'flag_content_rel') { - $view->display[$display]->display_options['relationships'][$new_rel] = array( - 'label' => $flag_name, - 'required' => 1, - 'flag' => $flag_name, - 'user_scope' => 'any', - 'id' => 'flag_content_rel', - 'table' => 'node', - 'field' => 'flag_content_rel', - 'relationship' => 'none', - ); - } - elseif ($new_rel == 'flag_counts_rel') { - $view->display[$display]->display_options['relationships'][$new_rel] = array( - 'label' => $flag_name . ' counts', - 'required' => 0, - 'flag' => $flag_name, - 'id' => 'flag_counts_rel', - 'table' => 'node', - 'field' => 'flag_counts_rel', - 'relationship' => 'none', - ); - } - elseif ($new_rel == 'uid') { - $view->display[$display]->display_options['relationships'][$new_rel] = array( - 'label' => isset($flag_name) ? $flag_name . ' user' : 'user', - 'required' => 0, - 'id' => 'uid', - 'table' => 'flagging', - 'field' => 'uid', - 'relationship' => 'flag_content_rel', - ); - } - } - - // Modify relationships if needed. - if (isset($flag_content_rel_user) && isset($view->display[$display]->display_options['relationships']['flag_content_rel'])) { - $view->display[$display]->display_options['relationships']['flag_content_rel']['user_scope'] = 'current'; - } -} - -/** - * In Views 1, dates were simply stored as a single string. In Views 2, the - * value is stored as an array of options. - */ -function flag_views_convert_timestamp_value($value) { - $type = 'date'; - if (stripos($value, 'now') !== FALSE) { - $type = 'offset'; - $value = trim(str_ireplace('now', '', $value)); - } - return array( - 'type' => $type, - 'value' => $value, - 'min' => '', - 'max' => '', - ); -} diff --git a/includes/views/flag_handler_argument_entity_id.inc b/includes/views/flag_handler_argument_entity_id.inc deleted file mode 100644 index f5d3b1a..0000000 --- a/includes/views/flag_handler_argument_entity_id.inc +++ /dev/null @@ -1,46 +0,0 @@ -view->relationship[$this->options['relationship']]->get_flag(); - } - - /** - * Override the behavior of title(). Get the title of the appropriate objects. - */ - function title_query() { - if (!($flag = $this->get_flag())) { - return array(); // Error message is printed by get_flag(). - } - $views_info = $flag->get_views_info(); - - $titles = array(); - $placeholders = implode(', ', array_fill(0, sizeof($this->value), '%d')); - - $result = db_select($views_info['views table'], 'o') - ->fields('o', array($views_info['title field'])) - ->condition('o.' . $views_info['join field'], $this->value, 'IN') - ->execute(); - foreach ($result as $title) { - $titles[] = check_plain($title->$views_info['title field']); - } - return $titles; - } -} diff --git a/includes/views/flag_handler_field_flagged.inc b/includes/views/flag_handler_field_flagged.inc deleted file mode 100644 index 660f91d..0000000 --- a/includes/views/flag_handler_field_flagged.inc +++ /dev/null @@ -1,36 +0,0 @@ -formats['flag'] = array(t('Flagged'), t('Not flagged')); - // TODO: We could probably lift the '(Un)Flagged message' strings from the - // flag object, but a) we need to lift that from the relationship we're on - // and b) they will not necessarily make sense in a static context. - } - - /** - * Called to add the field to a query. - */ - function query() { - $this->ensure_my_table(); - // Add the formula. - $this->field_alias = $this->query->add_field(NULL, "($this->table_alias.uid IS NOT NULL)", 'flagging_flagged'); - - $this->add_additional_fields(); - } - -} diff --git a/includes/views/flag_handler_field_ops.inc b/includes/views/flag_handler_field_ops.inc deleted file mode 100644 index 58830f1..0000000 --- a/includes/views/flag_handler_field_ops.inc +++ /dev/null @@ -1,163 +0,0 @@ -view->relationship[$this->options['relationship']])) { - return $this->view->relationship[$this->options['relationship']]->get_flag(); - } - } - - /** - * Return the the relationship we're linked to. That is, the alias for its - * table (which is suitbale for use with the various methods of the 'query' - * object). - */ - function get_parent_relationship() { - $parent = $this->view->relationship[$this->options['relationship']]->options['relationship']; - if (!$parent || $parent == 'none') { - return NULL; // Base query table. - } - else { - return $this->view->relationship[$parent]->alias; - } - } - - function option_definition() { - $options = parent::option_definition(); - $options['link_type'] = array('default' => ''); - return $options; - } - - function options_form(&$form, &$form_state) { - parent::options_form($form, $form_state); - - $form['link_type'] = array( - '#type' => 'radios', - '#title' => t('Link type'), - '#options' => array('' => t('Use flag link settings')) + _flag_link_type_options(), - '#default_value' => $this->options['link_type'], - ); - } - - /** - * Override base ::query(). The purpose here is to make it possible for the - * render() method to know two things: what's the content ID, and whether - * it's flagged. - */ - function query() { - if (!($flag = $this->get_flag())) { - return; // Error message is printed in render(). - } - $info = $flag->get_views_info(); - $parent = $this->get_parent_relationship(); - - // Find out if the content is flagged. We can't just peek at some field in - // our loaded table because it doesn't always reflect the user browsing the - // page. So we explicitly add the flagging table to find this out. - // If the relationship is created with 'Current User' checked, we probably - // already have the appropriate join. We just need the appropriate table - // alias for that join. We look in the relationship settings to see if - // user_scope is set to 'current' to determine this. - $relationship = $this->view->relationship[$this->options['relationship']]; - if (isset($relationship->options['user_scope']) && $relationship->options['user_scope'] == 'current') { - $table_alias = $relationship->alias; - } - // Otherwise, let's set up the alias, keeping it unique for this flag in - // case there are multiple flag relationships in a single view. - else { - $table_alias = 'flagging_current_user_' . $flag->fid; - } - // Now that we have the table alias, let's see if it's already been joined - // to. If it hasn't, we'll set up a join. - if (!isset($this->query->table_queue[$table_alias])) { - $join = new views_join(); - $join->construct('flagging', $info['views table'], $info['join field'], 'entity_id'); - $join->extra[] = array( - 'field' => 'fid', - 'value' => $flag->fid, - 'numeric' => TRUE, - ); - if (!$flag->global) { - $join->extra[] = array( - 'field' => 'uid', - 'value' => '***CURRENT_USER***', - 'numeric' => TRUE, - ); - $join->extra[] = array( - 'field' => 'sid', - 'value' => '***FLAG_CURRENT_USER_SID***', - 'numeric' => TRUE, - ); - } - $table_alias = $this->query->add_table($table_alias, $parent, $join); - } - $this->aliases['is_flagged'] = $this->query->add_field($table_alias, 'entity_id'); - - // Next, find out the content ID. We can't add_field() on this table - // (flagging), because its entity_id may be NULL (in case no user has - // flagged this content, and it's a LEFT JOIN). So we reach to the parent - // relationship and add_field() *its* content ID column. - $left_table = $this->view->relationship[$this->options['relationship']]->table_alias; - $this->aliases['entity_id'] = $this->query->add_field($left_table, $info['join field']); - } - - /** - * Find out if the flag applies to each item seen on the page. It's done in a - * separate DB query to to avoid complexity and to make 'many to one' tests - * (e.g. checking user roles) possible without causing duplicate rows. - */ - function pre_render(&$values) { - if (!($flag = $this->get_flag())) { - return; // Error message is printed in render(). - } - - $ids = array(); - foreach ($values as $row) { - $entity_id = $row->{$this->aliases['entity_id']}; - $is_flagged = $row->{$this->aliases['is_flagged']}; - if (isset($entity_id)) { - $ids[$entity_id] = $is_flagged ? 'unflag' : 'flag'; - } - } - $this->flag_applies = $ids ? $flag->access_multiple($ids) : array(); - } - - function render($values) { - if (!($flag = $this->get_flag())) { - return t('Missing flag'); // get_flag() itself will print a more detailed message. - } - - $entity_id = $values->{$this->aliases['entity_id']}; - $is_flagged = $values->{$this->aliases['is_flagged']}; - - if (empty($this->flag_applies[$entity_id])) { - // Flag does not apply to this content. - return; - } - - if (!empty($this->options['link_type'])) { - $flag->link_type = $this->options['link_type']; - } - return $flag->theme($is_flagged ? 'unflag' : 'flag', $entity_id); - } -} diff --git a/includes/views/flag_handler_filter_flagged.inc b/includes/views/flag_handler_filter_flagged.inc deleted file mode 100644 index d22c40b..0000000 --- a/includes/views/flag_handler_filter_flagged.inc +++ /dev/null @@ -1,33 +0,0 @@ - 1); - return $options; - } - - function options_form(&$form, &$form_state) { - parent::options_form($form, $form_state); - $form['value']['#type'] = 'radios'; - $form['value']['#title'] = t('Status'); - $form['value']['#options'] = array(1 => t('Flagged'), 0 => t('Not flagged'), 'All' => t('All')); - $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; - $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; - } - - function query() { - $operator = $this->value ? 'IS NOT' : 'IS'; - $this->query->add_where($this->options['group'], $this->relationship . '.uid', NULL, $operator . ' NULL'); - } -} diff --git a/includes/views/flag_handler_relationships.inc b/includes/views/flag_handler_relationships.inc deleted file mode 100644 index 9a7c964..0000000 --- a/includes/views/flag_handler_relationships.inc +++ /dev/null @@ -1,267 +0,0 @@ - NULL); - $options['required'] = array('default' => 1); - return $options; - } - - /** - * Make sure the flag exists. - * - * When importing views, or when deleting flags, inconsistent views may - * result. This validator is called by Views before saving or previewing a - * view. - */ - function validate() { - $errors = array(); - $tokens = array( - '@relationship-name' => $this->ui_name() . ' ' . $this->admin_summary(), - '@flag-name' => $this->options['flag'], - ); - if (!$this->options['flag']) { - $errors[] = t('You must pick a flag to use for the relationship "@relationship-name".', $tokens); - } - elseif (!flag_get_flag($this->options['flag'])) { - $errors[] = t('This view is looking for a flag by the name "@flag-name", but there is no such flag. Perhaps it was deleted. Please update the relationship "@relationship-name" in this view to use an existing flag.', $tokens); - } - return $errors; - } - - function get_flag_type() { - return isset($this->definition['flag type']) ? $this->definition['flag type'] : NULL; - } - - /** - * Returns the flag object. - */ - function get_flag() { - - // Backward compatibility: There may exist old views on the system whose - // 'flag' option isn't set. (This happens if the admin had skippped - // clicking the 'Update' button.) When run, these views should behave as - // if the first flag was selected. - if (!isset($this->options['flag'])) { - $this->options['flag'] = flag_views_flag_default($this->get_flag_type()); - } - - // Validation: Since validate() is called only when in Views's - // administrative UI, we need to do validation at "run time" ourselves. - if (($errors = $this->validate())) { - foreach ($errors as $error) { - drupal_set_message($error, 'error'); - } - } - - return flag_get_flag($this->options['flag']); - } - - // @todo: It's logical that this class should also implement options_form(), - // to show the flag selector, and query(), to filter on the flag. -} - -/** - * Specialized relationship handler associating flags and content. - * - * @ingroup views - */ -class flag_handler_relationship_content extends flag_handler_relationship { - - function option_definition() { - $options = parent::option_definition(); - $options['user_scope'] = array('default' => 'current'); - return $options; - } - - function options_form(&$form, &$form_state) { - parent::options_form($form, $form_state); - $entity_type = $this->definition['flag type']; - $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); - $form['flag'] = flag_views_flag_config_form('radios', $entity_type, $this->options['flag']); - - $form['user_scope'] = array( - '#type' => 'radios', - '#title' => t('By'), - '#options' => array('current' => t('Current user'), 'any' => t('Any user')), - '#default_value' => $this->options['user_scope'], - ); - - $form['required']['#title'] = t('Include only flagged content'); - $form['required']['#description'] = t('If checked, only content that has this flag will be included. Leave unchecked to include all content; or, in combination with the Flagged filter, to limit the results to specifically unflagged content.', array('@unflagged-url' => 'http://drupal.org/node/299335')); - - if (!$form['flag']['#options']) { - $form = array( - 'error' => array( - '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', array('%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH))) . '

', - ), - ); - $form_state['no flags exist'] = TRUE; - } - if (module_exists('session_api')) { - $form['session_warning'] = array( - '#markup' => '

' . t('Warning: Adding this relationship for any flag that contains anonymous flagging access will disable page caching for anonymous users when this view is executed. (But this is only true when the relationship is constrained to "Current user", not to "Any user".) It is recommended to create a dedicated page for views containing anonymous user data.') . '

', - ); - } - } - - function options_validate(&$form, &$form_state) { - if (!empty($form_state['no flags exist'])) { - form_error($form, t('You must first create a flag')); - } - } - - function admin_summary() { - return $this->options['user_scope'] == 'current' ? t('by current user') : t('by any user'); - } - - function ui_name($short = FALSE) { - // We put the bookmark name in the UI string to save space. - return t('!group: !title', array('!group' => $this->definition['group'], '!title' => empty($this->options['flag']) ? t('(Please select a flag)') : $this->options['flag'])); - } - - /** - * Called to implement a relationship in a query. - */ - function query() { - if (!($flag = $this->get_flag())) { - return; - } - - $this->definition['extra'][] = array( - 'field' => 'fid', - 'value' => $flag->fid, - 'numeric' => TRUE, - ); - if ($this->options['user_scope'] == 'current' && !$flag->global) { - $this->definition['extra'][] = array( - 'field' => 'uid', - 'value' => '***CURRENT_USER***', - 'numeric' => TRUE, - ); - $flag_roles = user_roles(FALSE, "flag $flag->name"); - if (isset($flag_roles[DRUPAL_ANONYMOUS_RID])) { - // Disable page caching for anonymous users. - drupal_page_is_cacheable(FALSE); - - // Add in the SID from Session API for anonymous users. - $this->definition['extra'][] = array( - 'field' => 'sid', - 'value' => '***FLAG_CURRENT_USER_SID***', - 'numeric' => TRUE, - ); - } - } - parent::query(); - } -} - -/** - * Specialized relationship handler associating flag counts and content. - * - * @ingroup views - */ -class flag_handler_relationship_counts extends flag_handler_relationship { - - function options_form(&$form, &$form_state) { - parent::options_form($form, $form_state); - $entity_type = $this->definition['flag type']; - $form['flag'] = flag_views_flag_config_form('radios', $entity_type, $this->options['flag']); - - $form['required']['#title'] = t('Include only flagged content'); - $form['required']['#description'] = t('If checked, only content that is flagged will be included.'); - } - - function admin_summary() { - // Nothing to show. - } - - function ui_name($short = FALSE) { - // We put the bookmark name in the UI string to save space. - return t('!group: !title counter', array('!group' => $this->definition['group'], '!title' => $this->options['flag'])); - } - - /** - * Called to implement a relationship in a query. - */ - function query() { - if (!($flag = $this->get_flag())) { - return; - } - - $this->definition['extra'][] = array( - 'field' => 'fid', - 'value' => $flag->fid, - 'numeric' => TRUE, - ); - if (!empty($this->options['required'])) { - // Unfortunately, we may have zeros in our table, so having - // parent::query() do INNER JOIN doesn't suffice. We need to filter these - // zeros out. - // @todo Make sure zero records aren't written in the first place, and - // remove this code. - $this->definition['extra'][] = array( - 'field' => 'count', - 'operator' => '>', - 'value' => '0', - 'numeric' => TRUE, - ); - } - parent::query(); - } -} - -/** - * Specialized relationship handler associating flags and users. - * - * @ingroup views - */ -class flag_handler_relationship_user_content extends flag_handler_relationship { - - function options_form(&$form, &$form_state) { - parent::options_form($form, $form_state); - $form['label']['#description'] .= ' ' . t('Including name of the selected flag helps identify this relationship.'); - - $form['flag'] = flag_views_flag_config_form('radios', NULL, $this->options['flag']); - $form['flag']['#title'] = t('Flagged'); - - $form['required']['#title'] = t('Include only users who have flagged content.'); - $form['required']['#description'] = t('If checked, only users that have flagged any content with this flag will be included.'); - } - - function admin_summary() { - return $this->options['flag']; - } - - /** - * Called to implement a relationship in a query. - */ - function query() { - if (!($flag = $this->get_flag())) { - return; - } - - $this->definition['extra'][] = array( - 'field' => 'fid', - 'value' => $flag->fid, - 'numeric' => TRUE, - ); - parent::query(); - } -} - diff --git a/includes/views/flag_handler_sort_flagged.inc b/includes/views/flag_handler_sort_flagged.inc deleted file mode 100644 index 63c2787..0000000 --- a/includes/views/flag_handler_sort_flagged.inc +++ /dev/null @@ -1,47 +0,0 @@ - t('Unflagged first'), - 'DESC' => t('Flagged first'), - ); - } - - /** - * Display whether or not the sort order is ascending or descending - */ - function admin_summary() { - if (!empty($this->options['exposed'])) { - return t('Exposed'); - } - - // Get the labels defined in sort_options(). - $sort_options = $this->sort_options(); - return $sort_options[strtoupper($this->options['order'])]; - } - - function query() { - $this->ensure_my_table(); - // Add the ordering. - // Using IS NOT NULL means that the ASC/DESC ordering work in the same - // direction as sorting by flagging date: empty results come first. - $this->query->add_orderby(NULL, "($this->table_alias.uid IS NOT NULL)", $this->options['order']); - } - -} diff --git a/includes/views/flag_plugin_argument_validate_flaggability.inc b/includes/views/flag_plugin_argument_validate_flaggability.inc deleted file mode 100644 index f653412..0000000 --- a/includes/views/flag_plugin_argument_validate_flaggability.inc +++ /dev/null @@ -1,226 +0,0 @@ -flag_type = $this->definition['flag type']; - } - - function option_definition() { - $options = parent::option_definition(); - $options['flag_name'] = array('default' => '*relationship*'); - $options['flag_test'] = array('default' => 'flaggable'); - $options['flag_id_type'] = array('default' => 'id'); - return $options; - } - - function options_form(&$form, &$form_state) { - // If there are no flag relationships set, skip this form of validation. - $flags = flag_get_flags($this->flag_type); - if (!$flags) { - return array(); - } - $options = $this->flags_options(); - - $form['flag_name'] = array( - '#type' => 'radios', - '#title' => t('Flag'), - '#options' => $options, - '#default_value' => $this->options['flag_name'], - '#description' => t('Select the flag to validate against.'), - ); - if (!$options) { - $form['flag_name']['#description'] = '

' . t('No %type flags exist. You must first create a %type flag before being able to use one.', array('%type' => $this->flag_type, '@create-url' => FLAG_ADMIN_PATH)) . '

'; - } - - $form['flag_test'] = array( - '#type' => 'select', - '#title' => t('Validate the @type only if', array('@type' => $this->flag_type)), - '#options' => $this->tests_options(), - '#default_value' => $this->options['flag_test'], - ); - - // This validator supports the "multiple IDs" syntax. It may not be - // extremely useful, but similar validators do support this and it's a good - // thing to be compatible. - $form['flag_id_type'] = array( - '#type' => 'select', - '#title' => t('Argument type'), - '#options' => array( - 'id' => t('ID'), - 'ids' => t('IDs separated by , or +'), - ), - '#default_value' => $this->options['flag_id_type'], - ); - } - - /** - * Returns form #options for the flags. Returns empty array if no flags were - * found. - */ - function flags_options() { - $flags = flag_get_flags($this->flag_type); - if (!$flags) { - return array(); - } - else { - foreach ($flags as $flag) { - $options[$flag->name] = $flag->get_title(); - } - $options['*relationship*'] = t('Pick the first flag mentioned in the relationships.'); - return $options; - } - } - - /** - * Migrate existing Views 2 options to Views 3. - */ - function convert_options(&$options) { - $prefix = 'validate_argument_' . $this->flag_type . '_'; - if (!isset($options['flag_name']) && !empty($this->argument->options[$prefix . 'flag_name'])) { - $options['flag_name'] = $this->argument->options[$prefix . 'flag_name']; - $options['flag_test'] = $this->argument->options[$prefix . 'flag_test']; - $options['flag_id_type'] = $this->argument->options[$prefix . 'flag_id_type']; - } - } - - /** - * Declares all tests. This scheme makes it easy for derived classes to add - * and remove tests. - */ - function tests_info($which = NULL) { - return array( - 'flaggable' => array( - 'title' => t('It is flaggable'), - 'callback' => 'test_flaggable', - ), - 'flagged' => array( - 'title' => t('It is flagged at least once'), - 'callback' => 'test_flagged', - ), - 'flagged_by_current_user' => array( - 'title' => t('It is flagged by the current user'), - 'callback' => 'test_flagged_by_current_user', - ), - ); - } - - function tests_options() { - $options = array(); - foreach ($this->tests_info() as $id => $info) { - $options[$id] = $info['title']; - } - return $options; - } - - function get_flag() { - $flag_name = $this->options['flag_name']; - - if ($flag_name == '*relationship*') { - // Pick the first flag mentioned in the relationships. - foreach ($this->view->relationship as $id => $handler) { - // Note: we can't do $handler->field, because the relationship handler's init() may overwrite it. - if (strpos($handler->options['field'], 'flag') !== FALSE && !empty($handler->options['flag'])) { - $flag = flag_get_flag($handler->options['flag']); - if ($flag && $flag->entity_type == $this->flag_type) { - return $flag; - } - } - } - } - - return flag_get_flag($flag_name); - } - - /** - * Tests whether the argument is flaggable, or flagged, or flagged by current - * user. These are three possible tests, and which of the three to actually - * carry out is determined by 'flag_test'. - */ - function validate_argument($argument) { - $flag_test = $this->options['flag_test']; - $id_type = $this->options['flag_id_type']; - - $flag = $this->get_flag(); - if (!$flag) { - // Validator is misconfigured somehow. - return TRUE; - } - - if ($id_type == 'id') { - if (!is_numeric($argument)) { - // If a user is being smart and types several IDs where only one is - // expected, we invalidate this. - return FALSE; - } - } - - $ids = views_break_phrase($argument, $this); - if ($ids->value == array(-1)) { - // Malformed argument syntax. Invalidate. - return FALSE; - } - $ids = $ids->value; - - // Delegate the testing to the particual test method. $passed then - // holds the IDs that passed the test. - $tests_info = $this->tests_info(); - $method = $tests_info[$flag_test]['callback']; - if (method_exists($this, $method)) { - $passed = $this->$method($ids, $flag); - } - else { - $passed = array(); - } - - // If some IDs exist that haven't $passed our test then validation fails. - $failed = array_diff($ids, $passed); - return empty($failed); - } - - // - // The actual tests. They return the IDs that passed. - // - - function test_flaggable($ids, $flag) { - return array_filter($ids, array($flag, 'applies_to_entity_id')); - } - - function test_flagged($ids, $flag) { - // view_break_phrase() is guaranteed to return only integers, so this is SQL safe. - $flattened_ids = implode(',', $ids); - return $this->_test_by_sql("SELECT entity_id FROM {flag_counts} WHERE fid = :fid AND entity_id IN ($flattened_ids) AND count > 0", array(':fid' => $flag->fid)); - } - - function test_flagged_by_current_user($ids, $flag) { - global $user; - if (!$user->uid) { - // Anonymous user - return array(); - } - $flattened_ids = implode(',', $ids); - return $this->_test_by_sql("SELECT entity_id FROM {flagging} WHERE fid = :fid AND entity_id IN ($flattened_ids) AND uid = :uid", array(':fid' => $flag->fid, ':uid' => $user->uid)); - } - - // Helper: executes an SQL query and returns all the entity_id's. - function _test_by_sql($sql, $args) { - $passed = array(); - $result = db_query($sql, $args); - foreach ($result as $row) { - $passed[] = $row->entity_id; - } - return $passed; - } -} - diff --git a/plugins/access/flag_is_flagged/flag_is_flagged.inc b/plugins/access/flag_is_flagged/flag_is_flagged.inc deleted file mode 100644 index 68e1021..0000000 --- a/plugins/access/flag_is_flagged/flag_is_flagged.inc +++ /dev/null @@ -1,96 +0,0 @@ - t("Entity is flagged"), - 'description' => t('Control access by whether or not an entity is flagged.'), - 'callback' => 'flag_flag_is_flagged_access_check', - 'default' => array('flag_name' => ''), - 'settings form' => 'flag_flag_is_flagged_access_settings', - 'summary' => 'flag_flag_is_flagged_access_summary', - 'get child' => 'flag_flag_is_flagged_access_get_child', - 'get children' => 'flag_flag_is_flagged_access_get_children', -); - -/* - * Implements plugin get_child callback. - */ -function flag_flag_is_flagged_access_get_child($plugin, $parent, $child) { - $plugins = flag_flag_is_flagged_access_get_children($plugin, $parent); - return $plugins[$parent . ':' . $child]; -} - -/* - * Implements plugin get_children callback. - */ -function flag_flag_is_flagged_access_get_children($plugin, $parent) { - $plugins = array(); - $entities = entity_get_info(); - - foreach ($entities as $entity_type => $info) { - if (entity_type_supports($entity_type, 'view')) { - $plugin['title'] = t('@entity_type is flagged', array('@entity_type' => $info['label'])); - $plugin['keyword'] = $entity_type; - $plugin['name'] = $parent . ':' . $entity_type; - $plugin['required context'] = new ctools_context_required(t('Entity'), $entity_type); - $plugins[$parent . ':' . $entity_type] = $plugin; - } - } - - return $plugins; -} - -/** - * Settings form. - */ -function flag_flag_is_flagged_access_settings(&$form, &$form_state, $conf) { - $options = array(); - - $plugin = $form_state['plugin']; - $entity_type = explode(':', $plugin['name']); - $entity_type = $entity_type[1]; - - foreach (flag_get_flags($entity_type) as $flag) { - $options[$flag->name] = check_plain($flag->title); - } - - $form['settings']['flag_name'] = array( - '#title' => t('Flag name'), - '#type' => 'radios', - '#options' => $options, - '#description' => t('Include only flagged content.'), - '#default_value' => $conf['flag_name'], - ); - return $form; -} - -/** - * Check for access. - */ -function flag_flag_is_flagged_access_check($conf, $context) { - $flag = flag_get_flag($conf['flag_name']); - if (!$flag || empty($context->data)) { - return FALSE; - } - - // Get the ID of the entity. - list($id) = entity_extract_ids($flag->entity_type, $context->data); - - return $flag->is_flagged($id); -} - -/** - * Provide a summary description based upon the specified context - */ -function flag_flag_is_flagged_access_summary($conf, $context) { - $flag = flag_get_flag($conf['flag_name']); - - if ($flag) { - return t('@identifier is flagged with "@flag"', array('@flag' => check_plain($flag->title), '@identifier' => $context->identifier)); - } - else { - return t('Missing/ deleted flag "@flag"', array('@flag' => $conf['flag_name'])); - } -} diff --git a/plugins/content_types/flag_link/flag_link.inc b/plugins/content_types/flag_link/flag_link.inc deleted file mode 100644 index 33de132..0000000 --- a/plugins/content_types/flag_link/flag_link.inc +++ /dev/null @@ -1,115 +0,0 @@ - t('Flag link'), - 'description' => t('Add a flag link of a certain flag type for entities.'), - 'defaults' => array('flag_name' => ''), - 'content type' => 'flag_flag_link_content_type_info', -); - -/** - * Get the entity content type info. - */ -function flag_flag_link_content_type_info($entity_type) { - $types = flag_flag_link_content_type_content_types(); - if (isset($types[$entity_type])) { - return $types[$entity_type]; - } -} - -/** - * Implements hook_PLUGIN_content_type_content_types(). - */ -function flag_flag_link_content_type_content_types() { - $types = array(); - $entities = entity_get_info(); - - foreach ($entities as $entity_type => $info) { - if (entity_type_supports($entity_type, 'view')) { - $types[$entity_type] = array( - 'title' => t('Flag for @entity_type', array('@entity_type' => $info['label'])), - 'category' => t('Entity'), - 'required context' => new ctools_context_required(t('Entity'), $entity_type), - ); - } - } - - return $types; -} - -/** - * Render callback. - */ -function flag_flag_link_content_type_render($subtype, $conf, $args, $context) { - $flag = flag_get_flag($conf['flag_name']); - if (!$flag) { - return; - } - - if (empty($context->data)) { - return; - } - - // Get the ID of the entity. - list($id,,) = entity_extract_ids($flag->entity_type, $context->data); - $link = flag_create_link($flag->name, $id); - - if (!$link) { - return; - } - - $block = new stdClass(); - $block->module = 'flag'; - $block->title = t('Flag link'); - $block->delta = $flag->name; - - $block->content = $link; - return $block; -} - -/** - * Form callback. - */ -function flag_flag_link_content_type_edit_form($form, &$form_state) { - $conf = $form_state['conf']; - $entity_type = $form_state['subtype_name']; - $options = array(); - - foreach (flag_get_flags($entity_type) as $flag) { - $options[$flag->name] = $flag->title; - } - - $form['flag_name'] = array( - '#type' => 'select', - '#title' => t('Flag name'), - '#default_value' => $conf['flag_name'], - '#options' => $options, - '#description' => t('Select a flag.'), - '#required' => TRUE, - '#disabled' => !$options, - ); - - return $form; -} - -/** - * Form submit. - */ -function flag_flag_link_content_type_edit_form_submit($form, &$form_state) { - // Copy everything from our defaults. - foreach (array_keys($form_state['plugin']['defaults']) as $key) { - $form_state['conf'][$key] = $form_state['values'][$key]; - } -} - -/** - * Returns the administrative title for a flag link. - */ -function flag_flag_link_content_type_admin_title($subtype, $conf) { - if ($flag = flag_get_flag($conf['flag_name'])) { - return t('Flag link of @flag', array('@flag' => $flag->title)); - } -} diff --git a/tests/flag.test b/tests/flag.test deleted file mode 100644 index 8d67758..0000000 --- a/tests/flag.test +++ /dev/null @@ -1,971 +0,0 @@ -save(); - // Reset our cache so our permissions show up. - drupal_static_reset('flag_get_flags'); - - // Reset permissions so that permissions for this flag are available. - $this->checkPermissions(array(), TRUE); - - return $flag; - } - -} - -/** - * Test CRUD operations on Flagging entities. - */ -class FlagFlaggingCRUDTestCase extends FlagTestCaseBase { - - /** - * Implements getInfo(). - */ - public static function getInfo() { - return array( - 'name' => 'Flagging CRUD', - 'description' => 'Basic CRUD operations on flagging entities.', - 'group' => 'Flag', - ); - } - - /** - * Implements setUp(). - */ - function setUp() { - parent::setUp('flag'); - - $flag_data = array( - 'entity_type' => 'node', - 'name' => 'test_flag', - 'title' => 'Test Flag', - 'global' => 0, - 'types' => array( - 0 => 'article', - ), - 'flag_short' => 'Flag this item', - 'flag_long' => '', - 'flag_message' => '', - 'unflag_short' => 'Unflag this item', - 'unflag_long' => '', - 'unflag_message' => '', - 'unflag_denied_text' => 'You may not unflag this item', - 'link_type' => 'normal', - 'weight' => 0, - 'show_on_form' => 0, - 'access_author' => '', - 'show_contextual_link' => 0, - 'show_in_links' => array( - 'full' => 1, - 'teaser' => 1, - ), - 'i18n' => 0, - 'api_version' => 3, - ); - $this->flag = $this->createFlag($flag_data); - - // Create test user who can flag and unflag. - $this->flag_unflag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); - $this->drupalLogin($this->flag_unflag_user); - } - - /** - * Test creation of a flagging entity with flagging_save(). - */ - function testFlaggingCreate() { - // Create an article node that we try to create a flagging entity for. - $title = $this->randomName(8); - $node = array( - 'title' => $title, - 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), - 'uid' => 1, - 'type' => 'article', - 'is_new' => TRUE, - ); - $node = node_submit((object) $node); - node_save($node); - - // Create a flagging entity and save it. - $flagging = array( - 'fid' => $this->flag->fid, - 'entity_type' => 'node', - 'entity_id' => $node->nid, - 'uid' => $this->flag_unflag_user->uid, - ); - - $flagging = (object) $flagging; - flagging_save($flagging); - - // Test flagging has a flagging_id - $this->assertTrue(!empty($flagging->flagging_id), 'The flagging entity has an entity id.'); - - // Test the database record exists. - $result = db_query("SELECT * FROM {flagging} WHERE fid = :fid AND entity_id = :nid AND uid = :uid", array( - ':fid' => $this->flag->fid, - ':nid' => $node->nid, - ':uid' => $this->flag_unflag_user->uid, - )); - $records = $result->fetchAll(); - $this->assertTrue(count($records), 'The flagging record exists in the database.'); - - // Test node is flagged. - // The current user is not the same as the user logged into the internal - // browser, so we have to pass the UID param explicitly. - $this->assertTrue($this->flag->is_flagged($node->nid, $this->flag_unflag_user->uid), 'The node has been flagged by creating the flagging.'); - } - - /** - * Test throwing of exceptions with flagging_save(). - */ - function testFlaggingCreateException() { - // Create an article node that we try to create a flagging entity for. - $title = $this->randomName(8); - $node = array( - 'title' => $title, - 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), - 'uid' => 1, - 'type' => 'article', - 'is_new' => TRUE, - ); - $node = node_submit((object) $node); - node_save($node); - - // Create test user who can't use this flag. - $no_flag_user = $this->drupalCreateUser(array()); - - // Create a flagging entity with that tries to perform an flagging action - // that is not permitted. - $flagging = array( - 'fid' => $this->flag->fid, - 'entity_type' => 'node', - 'entity_id' => $node->nid, - 'uid' => $no_flag_user->uid, - ); - - $flagging = (object) $flagging; - try { - flagging_save($flagging); - $this->fail(t('Expected exception has not been thrown.')); - } - catch (Exception $e) { - $this->pass(t('Expected exception has been thrown.')); - } - } - - /** - * Test creation of a flagging entity with flagging_save(). - */ - function testFlaggingUpdate() { - // Create an article node that we try to create a flagging entity for. - $title = $this->randomName(8); - $node = array( - 'title' => $title, - 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), - 'uid' => 1, - 'type' => 'article', - 'is_new' => TRUE, - ); - $node = node_submit((object) $node); - node_save($node); - - // Flag the node as the user. - $flag = flag_get_flag('test_flag'); - $flag->flag('flag', $node->nid, $this->flag_unflag_user); - - // Get the flagging record back from the database. - $result = db_query("SELECT * FROM {flagging} WHERE fid = :fid AND entity_id = :nid AND uid = :uid", array( - ':fid' => $this->flag->fid, - ':nid' => $node->nid, - ':uid' => $this->flag_unflag_user->uid, - )); - $record = $result->fetchObject(); - - // Load the flagging entity we just created. - $flagging = flagging_load($record->flagging_id); - - // Save it, as if we were updating field values. - flagging_save($flagging); - - // This should have no effect: the node should still be flagged. - $this->assertTrue($this->flag->is_flagged($node->nid, $this->flag_unflag_user->uid), 'The node is still flagged after updating the flagging.'); - } - -} - -/** - * Test Flag admin UI. - */ -class FlagAdminTestCase extends FlagTestCaseBase { - var $_flag = FALSE; - - /** - * Implements getInfo(). - */ - public static function getInfo() { - return array( - 'name' => 'Flag admin tests', - 'description' => 'Add, edit and delete flags.', - 'group' => 'Flag', - ); - } - - /** - * Implements setUp(). - */ - function setUp() { - parent::setUp('flag'); - - // Create and login user - $admin_user = $this->drupalCreateUser(array('access administration pages', 'administer flags')); - $this->drupalLogin($admin_user); - } - - /** - * Create a flag through the UI and ensure that it is saved properly. - */ - function testFlagAdmin() { - // Add a new flag using the UI. - $edit = array( - 'name' => drupal_strtolower($this->randomName()), - 'title' => $this->randomName(), - 'flag_short' => 'flag short [node:nid]', - 'flag_long' => 'flag long [node:nid]', - 'flag_message' => 'flag message [node:nid]', - 'unflag_short' => 'unflag short [node:nid]', - 'unflag_long' => 'unflag long [node:nid]', - 'unflag_message' => 'unflag message [node:nid]', - 'roles[flag][2]' => TRUE, - 'roles[unflag][2]' => TRUE, - 'types[article]' => FALSE, - 'types[page]' => TRUE, - 'show_in_links[full]' => FALSE, - 'show_in_links[teaser]' => FALSE, - 'show_in_links[rss]' => FALSE, - 'show_in_links[search_index]' => FALSE, - 'show_in_links[search_result]' => FALSE, - 'show_on_form' => FALSE, - 'link_type' => 'toggle', - ); - $saved = $edit; - $saved['roles'] = array('flag' => array(2), 'unflag' => array(2)); - $saved['types'] = array('page'); - $saved['show_in_links'] = array('full' => 0, 'teaser' => 0, 'rss' => 0, 'search_index' => 0, 'search_result' => 0); - unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]'], $saved['show_in_links[full]'], $saved['show_in_links[teaser]'], $saved['show_in_links[rss]'], $saved['show_in_links[search_index]'], $saved['show_in_links[search_result]']); - - $this->drupalPost(FLAG_ADMIN_PATH . '/add/node', $edit, t('Save flag')); - - drupal_static_reset('flag_get_flags'); - $flag = flag_get_flag($edit['name']); - // Load the roles array for checking it matches. - $flag->fetch_roles(); - - // Check that the flag object is in the database. - $this->assertTrue($flag != FALSE, t('Flag object found in database')); - - // Check each individual property of the flag and make sure it was set. - foreach ($saved as $property => $value) { - $this->assertEqual($flag->$property, $value, t('Flag property %property properly saved.', array('%property' => $property))); - } - - // Check permissions. - $permissions = user_role_permissions(user_roles()); - foreach ($saved['roles'] as $action => $rids) { - foreach ($rids as $rid) { - $permission_string = "$action ". $saved['name']; - $this->assertTrue(isset($permissions[$rid][$permission_string]), t('Permission %perm set for flag.', array( - '%perm' => $permission_string, - ))); - } - } - - // Edit the flag through the UI. - $edit = array( - 'name' => drupal_strtolower($this->randomName()), - 'title' => $this->randomName(), - 'flag_short' => 'flag 2 short [node:nid]', - 'flag_long' => 'flag 2 long [node:nid]', - 'flag_message' => 'flag 2 message [node:nid]', - 'unflag_short' => 'unflag 2 short [node:nid]', - 'unflag_long' => 'unflag 2 long [node:nid]', - 'unflag_message' => 'unflag 2 message [node:nid]', - 'roles[flag][2]' => TRUE, - 'roles[unflag][2]' => TRUE, - 'types[article]' => TRUE, - 'types[page]' => FALSE, - 'show_in_links[full]' => TRUE, - 'show_in_links[teaser]' => TRUE, - 'show_in_links[rss]' => FALSE, - 'show_in_links[search_index]' => FALSE, - 'show_in_links[search_result]' => FALSE, - 'show_on_form' => TRUE, - 'link_type' => 'normal', - ); - $saved = $edit; - $saved['roles'] = array('flag' => array(2), 'unflag' => array(2)); - $saved['types'] = array('article'); - $saved['show_in_links'] = array('full' => TRUE, 'teaser' => TRUE, 'rss' => 0, 'search_index' => 0, 'search_result' => 0); - unset($saved['roles[flag][2]'], $saved['roles[unflag][2]'], $saved['types[article]'], $saved['types[page]'], $saved['show_in_links[full]'], $saved['show_in_links[teaser]'], $saved['show_in_links[rss]'], $saved['show_in_links[search_index]'], $saved['show_in_links[search_result]']); - - $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name, $edit, t('Save flag')); - - drupal_static_reset('flag_get_flags'); - $flag = flag_get_flag($edit['name']); - // Load the roles array for checking it matches. - $flag->fetch_roles(); - - // Check that the flag object is in the database. - $this->assertTrue($flag != FALSE, t('Flag object found in database')); - - // Check each individual property of the flag and make sure it was set. - foreach ($saved as $property => $value) { - $this->assertEqual($flag->$property, $value, t('Flag property %property properly saved.', array('%property' => $property))); - } - - // Clear the user access cache so our changes to permissions are noticed. - drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); - - // Check permissions. - $permissions = user_role_permissions(user_roles()); - - foreach ($saved['roles'] as $action => $rids) { - foreach ($rids as $rid) { - $permission_string = "$action ". $saved['name']; - $this->assertTrue(isset($permissions[$rid][$permission_string]), t('Permission %perm set for flag.', array( - '%perm' => $permission_string, - ))); - } - } - - // Delete the flag through the UI. - $this->drupalPost(FLAG_ADMIN_PATH . '/manage/' . $flag->name . '/delete', array(), t('Delete')); - drupal_static_reset('flag_get_flags'); - $this->assertFalse(flag_get_flag($flag->name), t('Flag successfully deleted.')); - } - -} - -/** - * Access to flags using the entity forms. - * - * @todo: complete this test class. - */ -class FlagAccessFormTestCase extends FlagTestCaseBase { - - /** - * Implements getInfo(). - */ - public static function getInfo() { - return array( - 'name' => 'Flag access: entity forms', - 'description' => 'Access to flag and unflag entities via entity forms.', - 'group' => 'Flag', - ); - } - - /** - * Implements setUp(). - */ - function setUp() { - parent::setUp('flag'); - } - - /** - * Test scenarios with no access to a global flag. - */ - function testFlagAccessGlobalNone() { - // Create a global flag on article nodes. - $flag_data = array( - 'entity_type' => 'node', - 'name' => 'global_flag', - 'title' => 'Global Flag', - 'global' => 1, - 'types' => array( - 0 => 'article', - ), - 'flag_short' => 'Flag this item', - 'flag_long' => '', - 'flag_message' => '', - 'unflag_short' => 'Unflag this item', - 'unflag_long' => '', - 'unflag_message' => '', - 'unflag_denied_text' => 'You may not unflag this item', - 'link_type' => 'normal', - 'weight' => 0, - // Show the flag on the form. - 'show_on_form' => 1, - 'access_author' => '', - 'show_contextual_link' => 0, - 'show_in_links' => array( - 'full' => 1, - 'teaser' => 1, - ), - 'i18n' => 0, - 'api_version' => 3, - ); - $flag = $this->createFlag($flag_data); - - // Create test user who can't us this flag, but can create nodes. - $no_flag_user = $this->drupalCreateUser(array('create article content')); - $this->drupalLogin($no_flag_user); - - $this->drupalGet('node/add/article'); - - // Check that the flag form element cannot be seen - $this->assertNoText('Flag this item', t('Flag form element was not found.')); - - // Have the user create a node. - $edit = array( - 'title' => 'node 1', - ); - $this->drupalPost('node/add/article', $edit, t('Save')); - - $node = $this->drupalGetNodeByTitle($edit["title"]); - - // Check the new node has not been flagged. - $this->assertFalse($flag->is_flagged($node->nid), t('New node is not flagged.')); - - // Now set the variable so that the flag is set by default on new nodes. - variable_set('flag_' . $flag->name . '_default_' . 'article', 1); - - // Create another new node. - $edit = array( - 'title' => 'node 2', - ); - $this->drupalPost('node/add/article', $edit, t('Save')); - - $node = $this->drupalGetNodeByTitle($edit["title"]); - - // Check the new node has been flagged, despite the user not having access - // to the flag. - $this->assertTrue($flag->is_flagged($node->nid), t('New node is flagged.')); - } - -} - -/** - * Access to flags using the basic flag link. - */ -class FlagAccessLinkTestCase extends FlagTestCaseBase { - - /** - * Implements getInfo(). - */ - public static function getInfo() { - return array( - 'name' => 'Flag access tests', - 'description' => 'Access to flag and unflag entities using the basic link.', - 'group' => 'Flag', - ); - } - - /** - * Implements setUp(). - */ - function setUp() { - parent::setUp('flag'); - - // Create a test flag on article nodes. - $flag_data = array( - 'entity_type' => 'node', - 'name' => 'test_flag', - 'title' => 'Test Flag', - 'global' => 0, - 'types' => array( - 0 => 'article', - ), - 'flag_short' => 'Flag this item', - 'flag_long' => '', - 'flag_message' => '', - 'unflag_short' => 'Unflag this item', - 'unflag_long' => '', - 'unflag_message' => '', - 'unflag_denied_text' => 'You may not unflag this item', - // Use the normal link type as it involves no intermediary page loads. - 'link_type' => 'normal', - 'weight' => 0, - 'show_on_form' => 0, - 'access_author' => '', - 'show_contextual_link' => 0, - 'show_in_links' => array( - 'full' => 1, - 'teaser' => 1, - ), - 'i18n' => 0, - 'api_version' => 3, - ); - $flag = $this->createFlag($flag_data); - - // Create an article node that various users will try to flag. - $title = $this->randomName(8); - $node = array( - 'title' => $title, - 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), - 'uid' => 1, - 'type' => 'article', - 'is_new' => TRUE, - ); - $node = node_submit((object) $node); - node_save($node); - $this->nid = $node->nid; - } - - /** - * Test that a user without flag access can't see the flag. - */ - function testFlagAccessNone() { - // Create test user who can't flag at all. - $no_flag_user = $this->drupalCreateUser(array()); - $this->drupalLogin($no_flag_user); - - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertNoLink('Flag this item', 0, 'The flag link does not appear on the page'); - } - - /** - * Test that a user with only flag access can flag but not unflag. - */ - function testFlagAccessFlagOnly() { - // Create test user who can flag but not unflag. - $flag_user = $this->drupalCreateUser(array('flag test_flag',)); - $this->drupalLogin($flag_user); - - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); - - // Click the link to flag the node. - $this->clickLink(t('Flag this item')); - - $this->assertText('You may not unflag this item', 0, 'The unflag denied text appears on the page after flagging.'); - } - - /** - * Test that a user with flag access can flag and unflag. - */ - function testFlagAccessFlagUnflag() { - // Create test user who can flag and unflag. - $flag_unflag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); - $this->drupalLogin($flag_unflag_user); - - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); - - // Click the link to flag the node. - $this->clickLink(t('Flag this item')); - - $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); - - // Click the link to unflag the node. - $this->clickLink(t('Unflag this item')); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); - } - -} - -/** - * Test the 'confirm form' link type. - */ -class FlagLinkTypeConfirmTestCase extends DrupalWebTestCase { - - /** - * Implements getInfo(). - */ - public static function getInfo() { - return array( - 'name' => 'Flag confirm link tests', - 'description' => 'Flag confirm form link type.', - 'group' => 'Flag', - ); - } - - /** - * Implements setUp(). - */ - function setUp() { - parent::setUp('flag'); - - // Create a test flag on article nodes. - // Keep the original data so we can compare strings. - $this->flag_data = array( - 'entity_type' => 'node', - 'name' => 'test_flag', - 'title' => 'Test Flag', - 'global' => 0, - 'types' => array( - 0 => 'article', - ), - 'flag_short' => 'Flag this item', - 'flag_long' => '', - 'flag_message' => 'You have flagged this item.', - 'unflag_short' => 'Unflag this item', - 'unflag_long' => '', - 'unflag_message' => 'You have unflagged this item', - 'unflag_denied_text' => 'You may not unflag this item', - 'link_type' => 'confirm', - 'flag_confirmation' => 'Are you sure you want to flag this item?', - 'unflag_confirmation' => 'Are you sure you want to unflag this item?', - 'weight' => 0, - 'show_on_form' => 0, - 'access_author' => '', - 'show_contextual_link' => 0, - 'show_in_links' => array( - 'full' => 1, - 'teaser' => 1, - ), - 'i18n' => 0, - 'api_version' => 3, - ); - $flag = flag_flag::factory_by_array($this->flag_data); - $flag->save(); - // Reset our cache so our permissions show up. - drupal_static_reset('flag_get_flags'); - - // Reset permissions so that permissions for this flag are available. - $this->checkPermissions(array(), TRUE); - - // Create test user who can flag and unflag. - $flag_unflag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); - $this->drupalLogin($flag_unflag_user); - - // Create an article node to flag and unflag. - $title = $this->randomName(8); - $node = array( - 'title' => $title, - 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), - 'uid' => 1, - 'type' => 'article', - 'is_new' => TRUE, - ); - $node = node_submit((object) $node); - node_save($node); - $this->nid = $node->nid; - } - - /** - * Test that a user sees the flag confirm form. - */ - function testFlag() { - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertLink($this->flag_data['flag_short'], 0, 'The flag link appears on the page'); - - // Click the link to flag the node. - $this->clickLink($this->flag_data['flag_short']); - - $this->assertUrl('flag/confirm/flag/test_flag/' . $this->nid, array( - 'query' => array( - 'destination' => 'node/' . $this->nid, - ), - ), 'On confirm flagging form page.'); - - $this->assertText($this->flag_data['flag_confirmation'], 'The flag confirmation text appears as the confirmation page title.'); - - // Click the button to confirm the flagging. - $this->drupalPost(NULL, array(), $this->flag_data['flag_short']); - - $this->assertText($this->flag_data['flag_message'], 'The flag message appears once the item has been flagged.'); - $this->assertLink($this->flag_data['unflag_short'], 0, 'The unflag link appears once the item has been flagged.'); - - // Click the link to unflag the node. - $this->clickLink($this->flag_data['unflag_short']); - - $this->assertUrl('flag/confirm/unflag/test_flag/' . $this->nid, array( - 'query' => array( - 'destination' => 'node/' . $this->nid, - ), - ), t('On confirm unflagging form page.')); - - $this->assertText($this->flag_data['unflag_confirmation'], 'The unflag confirmation text appears as the confirmation page title.'); - - // Click the button to confirm the flagging. - $this->drupalPost(NULL, array(), $this->flag_data['unflag_short']); - - $this->assertText($this->flag_data['unflag_message'], 'The unflag message appears once the item has been flagged.'); - } - -} - -/** - * Verifies the implementation of hook_flag_access(). - */ -class FlagHookFlagAccessTestCase extends FlagTestCaseBase { - - /** - * Implements getInfo(). - */ - public static function getInfo() { - return array( - 'name' => 'Flag hook_flag_access() tests', - 'description' => 'Checks the ability of modules to use hook_flag_access().', - 'group' => 'Flag', - ); - } - - /** - * Implements setUp(). - */ - function setUp() { - parent::setUp('flag'); - - $success = module_enable(array('flagaccesstest'), FALSE); - - // Create a test flag on article nodes. - $flag_data = array( - 'entity_type' => 'node', - 'name' => 'test_flag', - 'title' => 'Test Flag', - 'global' => 0, - 'types' => array( - 0 => 'article', - ), - 'flag_short' => 'Flag this item', - 'flag_long' => '', - 'flag_message' => '', - 'unflag_short' => 'Unflag this item', - 'unflag_long' => '', - 'unflag_message' => '', - 'unflag_denied_text' => 'You may not unflag this item', - // Use the normal link type as it involves no intermediary page loads. - 'link_type' => 'normal', - 'weight' => 0, - 'show_on_form' => 0, - 'access_author' => '', - 'show_contextual_link' => 0, - 'show_in_links' => array( - 'full' => 1, - 'teaser' => 1, - ), - 'i18n' => 0, - 'api_version' => 3, - ); - $flag = $this->createFlag($flag_data); - - // Create an article node that various users will try to flag. - $title = $this->randomName(8); - $node = array( - 'title' => $title, - 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), - 'uid' => 1, - 'type' => 'article', - 'is_new' => TRUE, - ); - $node = node_submit((object) $node); - node_save($node); - $this->nid = $node->nid; - } - - /** - * Verifies that the user sees the flag if a module returns NULL (Ignore). - */ - function testFlagAccessIgnore() { - variable_set('FlagHookFlagAccessTestCaseMode', 'ignore'); - $flag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); - $this->drupalLogin($flag_user); - - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); - - // Click the link to flag the node. - $this->clickLink(t('Flag this item')); - - $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); - - // Click the link to unflag the node. - $this->clickLink(t('Unflag this item')); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); - } - - /** - * Verifies that the user sees the flag if a module returns TRUE (Allow). - */ - function testFlagAccessAllow() { - variable_set('FlagHookFlagAccessTestCaseMode', 'allow'); - $flag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); - $this->drupalLogin($flag_user); - - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); - - // Click the link to flag the node. - $this->clickLink(t('Flag this item')); - - $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); - - // Click the link to unflag the node. - $this->clickLink(t('Unflag this item')); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); - } - - /** - * Verifies that the user sees the flag if a module returns TRUE (Allow) to override default access check. - */ - function testFlagAccessAllowOverride() { - variable_set('FlagHookFlagAccessTestCaseMode', 'allow'); - $flag_user = $this->drupalCreateUser(array()); - $this->drupalLogin($flag_user); - - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page.'); - - // Click the link to flag the node. - $this->clickLink(t('Flag this item')); - - $this->assertLink('Unflag this item', 0, 'The unflag link appears on the page after flagging.'); - - // Click the link to unflag the node. - $this->clickLink(t('Unflag this item')); - - $this->assertLink('Flag this item', 0, 'The flag link appears on the page after unflagging.'); - } - - /** - * Verifies that the user does not see the flag if a module returns FALSE (Deny). - */ - function testFlagAccessDeny() { - variable_set('FlagHookFlagAccessTestCaseMode', 'deny'); - $flag_user = $this->drupalCreateUser(array('flag test_flag', 'unflag test_flag')); - $this->drupalLogin($flag_user); - - // Look at our node. - $this->drupalGet('node/' . $this->nid); - - $this->assertNoLink('Flag this item', 0, 'The flag link does not appear on the page.'); - } - -} - -/** - * Test use of EntityFieldQueries with flagging entities. - */ -class FlagEntityFieldQueryTestCase extends FlagTestCaseBase { - - /** - * Implements getInfo(). - */ - public static function getInfo() { - return array( - 'name' => 'Flagging Entity Field Query Extension', - 'description' => 'Entity Field Query for flagging entities.', - 'group' => 'Flag', - ); - } - - /** - * Implements setUp(). - */ - function setUp() { - parent::setUp('flag'); - - $flag_data = array( - 'entity_type' => 'node', - 'name' => 'test_flag_1', - 'title' => 'Test Flag', - 'global' => 0, - 'types' => array( - 0 => 'article', - ), - 'flag_short' => 'Flag this item', - 'flag_long' => '', - 'flag_message' => '', - 'unflag_short' => 'Unflag this item', - 'unflag_long' => '', - 'unflag_message' => '', - 'unflag_denied_text' => 'You may not unflag this item', - // Use the normal link type as it involves no intermediary page loads. - 'link_type' => 'normal', - 'weight' => 0, - 'show_on_form' => 0, - 'access_author' => '', - 'show_contextual_link' => 0, - 'show_in_links' => array( - 'full' => 1, - 'teaser' => 1, - ), - 'i18n' => 0, - 'api_version' => 3, - ); - - $this->flag1 = $this->createFlag($flag_data); - $flag_data['name'] = 'test_flag_2'; - $this->flag2 = $this->createFlag($flag_data); - $flag_data['name'] = 'test_flag_3'; - $this->flag3 = $this->createFlag($flag_data); - - // Create test user who can flag and unflag. - $this->flag_unflag_user = $this->drupalCreateUser(array('flag test_flag_1', 'unflag test_flag_1', 'flag test_flag_2', 'unflag test_flag_2')); - $this->drupalLogin($this->flag_unflag_user); - - } - - /** - * Test use of EntityFieldQuery with flagging entities. - */ - function testEntityFieldQuery() { - $node_settings = array( - 'title' => $this->randomName(), - 'body' => array(LANGUAGE_NONE => array(array('value' => $this->randomName(32)))), - 'uid' => 1, - 'type' => 'article', - 'is_new' => TRUE, - ); - $node = $this->drupalCreateNode($node_settings); - - flag('flag', 'test_flag_1', $node->nid, $this->flag_unflag_user); - flag('flag', 'test_flag_2', $node->nid, $this->flag_unflag_user); - - $query = new EntityFieldQuery(); - $query->entityCondition('entity_type', 'flagging') - ->entityCondition('bundle', 'test_flag_1'); - - $flagged = $query->execute(); - $this->assertEqual(count($flagged['flagging']), 1); - - $query = new EntityFieldQuery(); - $query->entityCondition('entity_type', 'flagging') - ->entityCondition('bundle', 'test%', 'like'); - $flagged = $query->execute(); - $this->assertEqual(count($flagged['flagging']), 2); - - $query = new EntityFieldQuery(); - $query->entityCondition('entity_type', 'flagging') - ->entityCondition('bundle', array('test_flag_1', 'test_flag_2'), 'IN'); - $this->assertEqual(count($flagged['flagging']), 2); - } - -} diff --git a/tests/flagaccesstest/flagaccesstest.info b/tests/flagaccesstest/flagaccesstest.info deleted file mode 100644 index 3c9c176..0000000 --- a/tests/flagaccesstest/flagaccesstest.info +++ /dev/null @@ -1,6 +0,0 @@ -name = Flag hook_flag_access test -description = Tests for hook_flag_access -core = 7.x -dependencies[] = flag -package = Flags -hidden = TRUE diff --git a/tests/flagaccesstest/flagaccesstest.module b/tests/flagaccesstest/flagaccesstest.module deleted file mode 100644 index 62a2ce7..0000000 --- a/tests/flagaccesstest/flagaccesstest.module +++ /dev/null @@ -1,26 +0,0 @@ - Date: Thu, 21 Nov 2013 23:12:18 -0600 Subject: [PATCH 349/629] FlagType plugins now specify the entity types to which they apply. --- flag.module | 136 +----------------- lib/Drupal/flag/Form/FlagAddPageForm.php | 10 +- .../flag/Plugin/Flag/CommentFlagType.php | 9 ++ .../flag/Plugin/Flag/EntityFlagType.php | 12 ++ lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php | 8 +- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 9 ++ lib/Drupal/flag/Plugin/Flag/UserFlagType.php | 9 ++ 7 files changed, 51 insertions(+), 142 deletions(-) diff --git a/flag.module b/flag.module index 612a3a2..17136f5 100644 --- a/flag.module +++ b/flag.module @@ -12,111 +12,6 @@ define('FLAG_ADMIN_PATH_START', 3); use Drupal\flag\Handlers\AbstractFlag; -/** - * Implements hook_entity_info(). - */ -function flag_entity_info() { - $return = array( - 'flagging' => array( - 'label' => t('Flagging'), - 'controller class' => 'FlaggingController', - 'base table' => 'flagging', - 'fieldable' => TRUE, - 'entity keys' => array( - 'id' => 'flagging_id', - 'bundle' => 'flag_name', - ), - // The following tells Field UI how to extract the bundle name from a - // $flag object when we're visiting ?q=admin/.../manage/%flag/fields. - 'bundle keys' => array( - 'bundle' => 'name', - ), - 'bundles' => array(), - // The following tells EntityAPI how to save flaggings, thus allowing use - // of Entity metadata wrappers (if present). - 'save callback' => 'flagging_save', - ), - ); - - // Add bundle info but bypass flag_get_flags() as we cannot use it here, as - // it calls entity_get_info(). - $result = db_query("SELECT name, title FROM {flag}"); - $flag_names = $result->fetchAllKeyed(); - foreach ($flag_names as $flag_name => $flag_title) { - $return['flagging']['bundles'][$flag_name] = array( - 'label' => $flag_title, - 'admin' => array( - 'path' => FLAG_ADMIN_PATH . '/manage/%flag', - 'real path' => FLAG_ADMIN_PATH . '/manage/' . $flag_name, - 'bundle argument' => FLAG_ADMIN_PATH_START + 1, - 'access arguments' => array('administer flags'), - ), - ); - } - - return $return; -} - -/** - * Loads a flagging entity. - * - * @param $flagging_id - * The 'flagging_id' database serial column. - * @param $reset - * Whether to reset the DrupalDefaultEntityController cache. - * - * @return - * The entity object, or FALSE if it can't be found. - */ -function flagging_load($flagging_id, $reset = FALSE) { - // The flag machine name is loaded in by FlaggingController::buildQuery(). - $result = entity_load('flagging', array($flagging_id), array(), $reset); - return reset($result); -} - -/** - * Saves a flagging entity. - * - * For a new flagging, throws an exception is the flag action is not allowed for - * the given combination of flag, entity, and user. - * - * @param $flagging - * The flagging entity. This may have either flag_name or the flag fid set, - * and may also omit the uid property to use the current user. - * - * @throws Exception - */ -function flagging_save($flagging) { - // Get the flag, either way. - if (isset($flagging->flag_name)) { - $flag = flag_get_flag($flagging->flag_name); - } - else { - $flag = flag_get_flag(NULL, $flagging->fid); - } - - if (!$flag) { - throw new Exception('Flag not found for flagging entity.'); - } - - // Fill in properties that may be omitted. - $flagging->fid = $flag->fid; - $flagging->flag_name = $flag->name; - - if (!empty($flagging->uid)) { - $account = user_load($flagging->uid); - } - else { - $account = NULL; - } - - $result = $flag->flag('flag', $flagging->entity_id, $account, FALSE, $flagging); - - if (!$result) { - throw new Exception('Flag action not allowed for given flagging entity properties.'); - } -} - // @todo: Implement flagging_view(). Not extremely useful. I already have it. // @todo: When renaming a flag: Call field_attach_rename_bundle(). @@ -263,7 +158,6 @@ function flag_menu() { 'file' => 'includes/flag.export.inc', 'type' => MENU_CALLBACK, ); -*/ $items['flag/%/%flag/%'] = array( 'title' => 'Flag', 'page callback' => 'flag_page', @@ -282,7 +176,7 @@ function flag_menu() { 'file' => 'includes/flag.pages.inc', 'type' => MENU_CALLBACK, ); - +*/ return $items; } @@ -445,34 +339,6 @@ function flag_help($path, $arg) { } } -/** - * Implements hook_init() - * - * @todo Figure out where Rules module, see https://drupal.org/node/1211396 - */ -function flag_init() { - module_load_include('inc', 'flag', 'includes/flag.actions'); -} - -/** - * Implements hook_hook_info(). - */ -function flag_hook_info() { - $hooks['flag_type_info'] = array( - 'group' => 'flag', - ); - $hooks['flag_type_info_alter'] = array( - 'group' => 'flag', - ); - $hooks['flag_link_type_info'] = array( - 'group' => 'flag', - ); - $hooks['flag_link_type_info_alter'] = array( - 'group' => 'flag', - ); - return $hooks; -} - /** * Get a flag type definition. * diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index 532cdee..53aad74 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -23,10 +23,14 @@ public function getFormID() { public function buildForm(array $form, array &$form_state) { $types = array(); // @todo Use \Drupal::service() to get a list of FlagType plugins. - // print_r(\Drupal::service('plugin.manager.flag.flagtype')->getDefinitions()); - foreach (flag_fetch_definition() as $type => $info) { - $types[$type] = $info['title'] . '
' . $info['description'] . '
'; + $plugins = \Drupal::service('plugin.manager.flag.flagtype')->getDefinitions(); + + foreach ($plugins as $type => $plugin) { + $class = $plugin['class']; + foreach ($class::entityTypes() as $entityID => $info) { + $types[$entityID] = $info['title'] . '
' . $info['description'] . '
'; + } } $form['type'] = array( diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php index 0a76b88..ae1a48e 100644 --- a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php @@ -25,6 +25,15 @@ class CommentFlagType extends EntityFlagType { public $access_author; + public static function entityTypes() { + return array( + 'comment' => array( + 'title' => t('Comments'), + 'description' => t('Comments are responses to node content.'), + ), + ); + } + public function options() { $options = parent::options(); $options += array( diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php index 1900a91..92dc5fc 100644 --- a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php @@ -33,6 +33,18 @@ class EntityFlagType extends FlagTypeBase { public $show_contextual_link; + public static function entityTypes() { + $entity_types = array(); + foreach (entity_get_info() as $entity_id => $entity_info) { + $entity_types[$entity_id] = array( + 'title' => $entity_info['label'], + 'description' => t('@entity-type entity', array('@entity-type' => $entity_info['label'])), + ); + } + + return $entity_types; + } + function options() { $options = parent::options(); $options += array( diff --git a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php index a238d69..46851c4 100644 --- a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php +++ b/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php @@ -8,7 +8,7 @@ namespace Drupal\flag\Plugin\Flag; -use Drupal\core\Plugin\PluginBase; +use Drupal\Component\Plugin\PluginBase; /** * Class FlagTypeBase @@ -19,7 +19,7 @@ * title = @Translation("Flag Type Base") * ) */ -class FlagTypeBase extends PluginBase { +abstract class FlagTypeBase extends PluginBase { /** * {@inheritdoc} @@ -29,8 +29,8 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi parent::__construct($configuration, $plugin_id, $plugin_definition); } - public funciton flag() { - + public static function entityTypes() { + return array(); } /** diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index 2a27da9..adb473c 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -25,6 +25,15 @@ class NodeFlagType extends EntityFlagType { public $access_author; + public static function entityTypes() { + return array( + 'node' => array( + 'title' => t('Nodes'), + 'description' => t("Nodes are a Drupal site's primary content."), + ), + ); + } + public function options() { $options = parent::options(); // Use own display settings in the meanwhile. diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php index 5ff0285..4495c08 100644 --- a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php @@ -25,6 +25,15 @@ class UserFlagType extends FlagTypeBase { public $show_on_profile; + public static function entityTypes() { + return array( + 'user' => array( + 'title' => t('Users'), + 'description' => t('Users who have created accounts on your site.'), + ), + ); + } + function options() { $options = parent::options(); $options += array( From db9e697c4c3fdf4ba989885c47d2daddd45443ea Mon Sep 17 00:00:00 2001 From: Tess Date: Tue, 26 Nov 2013 23:18:09 -0600 Subject: [PATCH 350/629] Added initial work on the new add form. --- flag.services.yml | 2 +- lib/Drupal/flag/ActionLinkPluginManager.php | 9 ++++ lib/Drupal/flag/FlagTypePluginManager.php | 10 ++++ lib/Drupal/flag/Form/FlagAddForm.php | 1 + lib/Drupal/flag/Form/FlagAddPageForm.php | 50 ++++++++++++++++++- .../flag/Plugin/Derivative/EntityFlagType.php | 31 ++++++++++++ .../flag/Plugin/Flag/EntityFlagType.php | 10 +++- lib/Drupal/flag/Plugin/Flag/UserFlagType.php | 3 +- 8 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php diff --git a/flag.services.yml b/flag.services.yml index 554fa2b..f144eed 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -2,6 +2,6 @@ services: plugin.manager.flag.flagtype: class: Drupal\flag\FlagTypePluginManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] - plugin.manager.action_link: + plugin.manager.flag.linktype: class: Drupal\flag\ActionLinkPluginManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] diff --git a/lib/Drupal/flag/ActionLinkPluginManager.php b/lib/Drupal/flag/ActionLinkPluginManager.php index 81ee91e..1841988 100644 --- a/lib/Drupal/flag/ActionLinkPluginManager.php +++ b/lib/Drupal/flag/ActionLinkPluginManager.php @@ -26,4 +26,13 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac $this->setCacheBackend($cache_backend, $language_manager, 'flag_link_type_info'); } + public function getAllLinkTypes() { + $linkTypes = array(); + foreach($this->getDefinitions() as $pluginID => $pluginDef) { + $linkTypes[$pluginID] = t($pluginDef['label']); + } + + return $linkTypes; + } + } diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php index 2b21305..ed5c650 100644 --- a/lib/Drupal/flag/FlagTypePluginManager.php +++ b/lib/Drupal/flag/FlagTypePluginManager.php @@ -35,4 +35,14 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac $this->setCacheBackend($cache_backend, $language_manager, 'flag'); } + public function getAllFlagTypes() { + $flagTypes = array(); + + foreach ($this->getDefinitions() as $pluginID => $pluginDef) { + $flagTypes[$pluginID] = t($pluginDef['title']); + } + + return $flagTypes; + } + } \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index 218a738..4d59a15 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -14,6 +14,7 @@ class FlagAddForm extends EntityFormController { public function buildForm(array $form, array &$form_state, $entity_type = NULL) { + //@todo Check all non-form_* params with check_plain(). $form = parent::buildForm($form, $form_state); $flag = $this->entity; //\Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index 53aad74..8aea581 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -21,11 +21,59 @@ public function getFormID() { } public function buildForm(array $form, array &$form_state) { + + $form['flag_basic_info'] = array( + '#type' => 'fieldset', + '#title' => t('Flag basic info'), + '#collapsable' => FALSE, + '#weight' => -10, + ); + $form['flag_basic_info']['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), + '#maxlength' => 255, + '#required' => TRUE, + '#weight' => -3, + ); + $form['flag_basic_info']['id'] = array( + '#type' => 'machine_name', + '#title' => t('Machine name'), + '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), + '#weight' => -2, + '#machine_name' => array( + 'exists' => 'flag_load_by_id', + 'source' => array('flag_basic_info', 'label'), + ), + ); + + $form['flag_type_info'] = array( + '#type' => 'fieldset', + '#title' => t('Type and Action'), + '#attributes' => array( + 'class' => array('container-inline'), + ), + ); + + $form['flag_type_info']['flag_entity_type'] = array( + '#type' => 'select', + '#title' => t('Flag'), + '#options' => \Drupal::service('plugin.manager.flag.flagtype')->getAllFlagTypes(), + ); + + $form['flag_type_info']['flag_link_type'] = array( + '#type' => 'select', + '#title' => t('using'), + '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), + ); + $types = array(); // @todo Use \Drupal::service() to get a list of FlagType plugins. $plugins = \Drupal::service('plugin.manager.flag.flagtype')->getDefinitions(); +// print_r($plugins); +/* foreach ($plugins as $type => $plugin) { $class = $plugin['class']; foreach ($class::entityTypes() as $entityID => $info) { @@ -41,7 +89,7 @@ public function buildForm(array $form, array &$form_state) { '#required' => TRUE, '#options' => $types, ); - +*/ $form['actions'] = array( '#type' => 'actions', ); diff --git a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php new file mode 100644 index 0000000..b6269c9 --- /dev/null +++ b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php @@ -0,0 +1,31 @@ + $entity_info) { + $derivatives[$entity_id] = array( + 'title' => $entity_id . " flag type", + 'entity' => $entity_id, + ) + $base_plugin_def; + } + + return $derivatives; + } +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php index 92dc5fc..633efea 100644 --- a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php @@ -18,7 +18,8 @@ * * @FlagType( * id = "flagtype_entity", - * title = @Translation("Flag Type Entity") + * title = @Translation("Flag Type Entity"), + * derivative = "Drupal\flag\Plugin\Derivative\EntityFlagType" * ) */ class EntityFlagType extends FlagTypeBase { @@ -33,7 +34,12 @@ class EntityFlagType extends FlagTypeBase { public $show_contextual_link; - public static function entityTypes() { + public function __construct(array $configuration, $plugin_id, array $plugin_definition) { + array_push($this->types, $plugin_definition['entity']); + parent::__construct($configuration, $plugin_id, $plugin_definition); + } + + public static function entityTypes() { $entity_types = array(); foreach (entity_get_info() as $entity_id => $entity_info) { $entity_types[$entity_id] = array( diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php index 4495c08..62f2ae7 100644 --- a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php @@ -16,7 +16,8 @@ * * @FlagType( * id = "flagtype_user", - * title = @Translation("Flag Type User") + * title = @Translation("Flag Type User"), + * entity = "user" * ) */ class UserFlagType extends FlagTypeBase { From cb9c0939a8286d9793a5df68952eba967ec3769d Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Dec 2013 14:16:39 -0600 Subject: [PATCH 351/629] Removed .idea folder from repo, added .gitignore file. --- .gitignore | 1 + .idea/.name | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 .gitignore delete mode 100644 .idea/.name diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 551c90f..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -flag \ No newline at end of file From 5ac5f7061baaef74560353d4aa7e629427a8653a Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Dec 2013 14:54:20 -0600 Subject: [PATCH 352/629] Added missing use statement to FlaggingInterface.php --- lib/Drupal/flag/FlaggingInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Drupal/flag/FlaggingInterface.php b/lib/Drupal/flag/FlaggingInterface.php index c75bd44..e75dc72 100644 --- a/lib/Drupal/flag/FlaggingInterface.php +++ b/lib/Drupal/flag/FlaggingInterface.php @@ -8,6 +8,7 @@ namespace Drupal\flag; +use Drupal\Core\Entity\ContentEntityInterface; interface FlaggingInterface extends ContentEntityInterface { From 8dddc0d893ad7e08005fc55fe10d2f92501d97f3 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Dec 2013 17:12:23 -0600 Subject: [PATCH 353/629] Moved FlagTypeBase and FlagTypeBroken out of the plugin directory. Changed plugin titles. --- lib/Drupal/flag/{Plugin/Flag => }/BrokenFlagType.php | 0 lib/Drupal/flag/{Plugin/Flag => }/FlagTypeBase.php | 0 lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php | 2 +- lib/Drupal/flag/Plugin/Flag/CommentFlagType.php | 2 +- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 2 +- lib/Drupal/flag/Plugin/Flag/UserFlagType.php | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) rename lib/Drupal/flag/{Plugin/Flag => }/BrokenFlagType.php (100%) rename lib/Drupal/flag/{Plugin/Flag => }/FlagTypeBase.php (100%) diff --git a/lib/Drupal/flag/Plugin/Flag/BrokenFlagType.php b/lib/Drupal/flag/BrokenFlagType.php similarity index 100% rename from lib/Drupal/flag/Plugin/Flag/BrokenFlagType.php rename to lib/Drupal/flag/BrokenFlagType.php diff --git a/lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php b/lib/Drupal/flag/FlagTypeBase.php similarity index 100% rename from lib/Drupal/flag/Plugin/Flag/FlagTypeBase.php rename to lib/Drupal/flag/FlagTypeBase.php diff --git a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php index b6269c9..e5d4679 100644 --- a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php @@ -21,7 +21,7 @@ public function getDerivativeDefinitions(array $base_plugin_def) { $derivatives = array(); foreach (entity_get_info() as $entity_id => $entity_info) { $derivatives[$entity_id] = array( - 'title' => $entity_id . " flag type", + 'title' => $entity_id, 'entity' => $entity_id, ) + $base_plugin_def; } diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php index ae1a48e..5e4ee65 100644 --- a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php @@ -18,7 +18,7 @@ * * @FlagType( * id = "flagtype_comment", - * title = @Translation("Flag Type Comment") + * title = @Translation("Comment") * ) */ class CommentFlagType extends EntityFlagType { diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index adb473c..a0d15c8 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -18,7 +18,7 @@ * * @FlagType( * id = "flagtype_node", - * title = @Translation("Flag Type Node") + * title = @Translation("Content") * ) */ class NodeFlagType extends EntityFlagType { diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php index 62f2ae7..8a6c354 100644 --- a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php @@ -16,7 +16,7 @@ * * @FlagType( * id = "flagtype_user", - * title = @Translation("Flag Type User"), + * title = @Translation("User"), * entity = "user" * ) */ From a6ca5848ea8a55db1bced25022edc94e49e8410a Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Dec 2013 17:14:46 -0600 Subject: [PATCH 354/629] Changed namespace for BrokenFlagType and FlagTypeBase. --- lib/Drupal/flag/BrokenFlagType.php | 2 +- lib/Drupal/flag/FlagTypeBase.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Drupal/flag/BrokenFlagType.php b/lib/Drupal/flag/BrokenFlagType.php index d220e59..86cbba9 100644 --- a/lib/Drupal/flag/BrokenFlagType.php +++ b/lib/Drupal/flag/BrokenFlagType.php @@ -6,7 +6,7 @@ * Time: 8:34 PM */ -namespace Drupal\flag\Plugin\Flag; +namespace Drupal\flag; use Drupal\flag\Plugin\Flag\FlagTypeBase; diff --git a/lib/Drupal/flag/FlagTypeBase.php b/lib/Drupal/flag/FlagTypeBase.php index 46851c4..ac41efd 100644 --- a/lib/Drupal/flag/FlagTypeBase.php +++ b/lib/Drupal/flag/FlagTypeBase.php @@ -6,7 +6,7 @@ * Time: 12:56 PM */ -namespace Drupal\flag\Plugin\Flag; +namespace Drupal\flag; use Drupal\Component\Plugin\PluginBase; From 16a45210987a2dbb7bfd8ff3d65901114a9b62ba Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Dec 2013 22:34:13 -0600 Subject: [PATCH 355/629] Add form improvements, started using TempStore API. --- lib/Drupal/flag/Form/FlagAddForm.php | 38 +++++------------------- lib/Drupal/flag/Form/FlagAddPageForm.php | 36 +++++++++++----------- 2 files changed, 24 insertions(+), 50 deletions(-) diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index 4d59a15..75394b9 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -17,6 +17,9 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) //@todo Check all non-form_* params with check_plain(). $form = parent::buildForm($form, $form_state); + $tempstore = \Drupal::service('user.tempstore')->get('flag'); + $step1_form = $tempstore->get('FlagAddPage'); + $flag = $this->entity; //\Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); // Mark the flag as new. @@ -31,7 +34,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) $form['label'] = array( '#type' => 'textfield', '#title' => t('Label'), - '#default_value' => $flag->label(), + '#default_value' => $step1_form['label'], '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), '#maxlength' => 255, '#required' => TRUE, @@ -41,7 +44,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) $form['id'] = array( '#type' => 'machine_name', '#title' => t('Machine name'), - '#default_value' => $flag->id(), + '#default_value' => $step1_form['id'], '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), '#weight' => -2, '#machine_name' => array( @@ -57,15 +60,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), '#weight' => -1, ); - // Don't allow the 'global' checkbox to be changed when flaggings exist: - // there are too many unpleasant consequences in either direction. - // @todo: Allow this, but with a confirmation form, assuming anyone actually - // needs this feature. -/* if (!empty($flag->id) && flag_get_flag_counts($flag->id)) { - $form['global']['#disabled'] = TRUE; - $form['global']['#description'] .= '
' . t('This setting cannot be changed when flaggings exist for this flag.'); - } -*/ + $form['messages'] = array( '#type' => 'fieldset', '#title' => t('Messages'), @@ -114,26 +109,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#default_value' => $flag->unflag_message, '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), ); -/* - $form['messages']['tokens_help'] = array( - '#title' => t('Token replacement'), - '#type' => 'fieldset', - '#description' => - '

' . t('The above six texts may contain any of the tokens listed below. For example, "Flag link text" could be entered as:') . '

' . - theme('item_list', array( - 'items' => array( - t('Add <em>[node:title]</em> to your favorites'), - t('Add this [node:type] to your favorites'), - t('Vote for this proposal ([node:flag-vote-count] people have already done so)'), - ), - 'attributes' => array('class' => 'token-examples'), - )) . - '

' . t('These tokens will be replaced with the appropriate fields from the node (or user, or comment).') . '

' . - theme('flag_tokens_browser', array('types' => $flag->get_labels_token_types())), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); -*/ + $form['access'] = array( '#type' => 'fieldset', '#title' => t('Flag access'), diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index 8aea581..3a5a897 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -67,29 +67,23 @@ public function buildForm(array $form, array &$form_state) { '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), ); + $role_options = array(0 => 'All users'); + foreach (user_roles() as $rid => $role_info) { + $role_options[$rid] = $role_info->label; + } + + $form['flag_type_info']['flag_role'] = array( + '#type' => 'select', + '#title' => t('for'), + '#options' => $role_options, + '#default' => 0, + ); + $types = array(); // @todo Use \Drupal::service() to get a list of FlagType plugins. $plugins = \Drupal::service('plugin.manager.flag.flagtype')->getDefinitions(); -// print_r($plugins); -/* - foreach ($plugins as $type => $plugin) { - $class = $plugin['class']; - foreach ($class::entityTypes() as $entityID => $info) { - $types[$entityID] = $info['title'] . '
' . $info['description'] . '
'; - } - } - - $form['type'] = array( - '#type' => 'radios', - '#title' => t('Flag type'), - '#default_value' => 'node', - '#description' => t('The type of object this flag will affect. This cannot be changed once the flag is created.'), - '#required' => TRUE, - '#options' => $types, - ); -*/ $form['actions'] = array( '#type' => 'actions', ); @@ -110,6 +104,10 @@ public function validateForm(array &$form, array &$form_state) { } public function submitForm(array &$form, array &$form_state) { - $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['type']; + $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . + $form_state['values']['flag_entity_type']; + + $tempstore = \Drupal::service('user.tempstore')->get('flag'); + $tempstore->set('FlagAddPage', $form_state['values']); } } \ No newline at end of file From 34252809d85e0f8722e3a22a89de50fe25ddd55f Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 15 Dec 2013 23:21:53 -0600 Subject: [PATCH 356/629] Fixed a lot of issues with the plugins and add forms. --- lib/Drupal/flag/ActionLinkTypeBase.php | 60 +++++++++++++-- .../flag/ActionLinkTypePluginInterface.php | 4 + lib/Drupal/flag/Annotation/FlagType.php | 7 ++ lib/Drupal/flag/BrokenFlagType.php | 5 -- lib/Drupal/flag/FlagTypeBase.php | 74 +++++++++++++------ lib/Drupal/flag/FlagTypePluginInterface.php | 20 +++++ lib/Drupal/flag/Form/FlagAddForm.php | 48 +++++++++--- lib/Drupal/flag/Form/FlagAddPageForm.php | 2 + lib/Drupal/flag/Plugin/ActionLink/Reload.php | 5 ++ .../flag/Plugin/Derivative/EntityFlagType.php | 2 +- .../flag/Plugin/Flag/CommentFlagType.php | 22 ++---- .../flag/Plugin/Flag/EntityFlagType.php | 38 ++-------- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 26 +++---- lib/Drupal/flag/Plugin/Flag/UserFlagType.php | 21 ++---- 14 files changed, 215 insertions(+), 119 deletions(-) create mode 100644 lib/Drupal/flag/FlagTypePluginInterface.php diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/lib/Drupal/flag/ActionLinkTypeBase.php index 4bde528..e9ff196 100644 --- a/lib/Drupal/flag/ActionLinkTypeBase.php +++ b/lib/Drupal/flag/ActionLinkTypeBase.php @@ -8,10 +8,14 @@ namespace Drupal\flag; -use Drupal\core\Plugin\PluginBase; -use Drupal\action_link\ActionLinkTypePluginInterface; +use Drupal\Component\Plugin\PluginBase; +use Drupal\flag\ActionLinkTypePluginInterface; -class ActionLinkTypeBase extends PluginBase implements ActionLinkTypePluginInterface { +/** + * Class ActionLinkTypeBase + * @package Drupal\flag + */ +abstract class ActionLinkTypeBase extends PluginBase implements ActionLinkTypePluginInterface { /** * @param array $configuration @@ -24,30 +28,74 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi $this->setConfiguration($configuration); } + /** + * @return string + */ public function buildLink() { return ""; } + /** + * Provides a form array for the action link plugin's settings form. + * Derived classes will want to override this method. + * + * @param array $form + * @param array $form_state + * @return array + * The configuration form array. + */ public function buildConfigurationForm(array $form, array &$form_state) { return $form; } + /** + * Processes the action link setting form submit. Derived classes will want to + * override this method. + * + * @param array $form + * @param array $form_state + */ public function submitConfigurationForm(array &$form, array &$form_state) { - + // Override this. } + /** + * Validates the action link setting form. Derived classes will want to override + * this method. + * + * @param array $form + * @param array $form_state + */ public function validateConfigurationForm(array &$form, array &$form_state) { - + // Override this. } + /** + * Provides the action link plugin's default configuration. Derived classes + * will want to override this method. + * + * @return array + * The plugin configuration array. + */ public function defaultConfiguration() { return array(); } + /** + * Provides the action link plugin's current configuraiton array. + * + * @return array + * An array containing the plugin's currnt configuration. + */ public function getConfiguration() { - return $configuration; + return $this->configuration; } + /** + * Replaces the plugin's current configuration with that given in the parameter. + * @param array $configuration + * An array containing the plugin's configuration. + */ public function setConfiguration(array $configuration) { $this->configuration = $configuration; } diff --git a/lib/Drupal/flag/ActionLinkTypePluginInterface.php b/lib/Drupal/flag/ActionLinkTypePluginInterface.php index e0d746f..ae95739 100644 --- a/lib/Drupal/flag/ActionLinkTypePluginInterface.php +++ b/lib/Drupal/flag/ActionLinkTypePluginInterface.php @@ -11,6 +11,10 @@ use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Component\Plugin\ConfigurablePluginInterface; +/** + * Interface ActionLinkTypePluginInterface + * @package Drupal\flag + */ interface ActionLinkTypePluginInterface extends PluginFormInterface, ConfigurablePluginInterface { public function buildLink(); diff --git a/lib/Drupal/flag/Annotation/FlagType.php b/lib/Drupal/flag/Annotation/FlagType.php index a1cba41..8bc9a8e 100644 --- a/lib/Drupal/flag/Annotation/FlagType.php +++ b/lib/Drupal/flag/Annotation/FlagType.php @@ -34,4 +34,11 @@ class FlagType extends Plugin { */ public $title; + /** + * The entity type the flag type supports. + * + * @var string + */ + public $entity_type; + } diff --git a/lib/Drupal/flag/BrokenFlagType.php b/lib/Drupal/flag/BrokenFlagType.php index 86cbba9..fa991bf 100644 --- a/lib/Drupal/flag/BrokenFlagType.php +++ b/lib/Drupal/flag/BrokenFlagType.php @@ -15,11 +15,6 @@ * @package Drupal\flag\Plugin\Flag * * A dummy Flag Type to be used where the real implementation can't be found. - * - * @FlagType( - * id = "flagtype_broken", - * title = @Translation("Flag Type Broken") - * ) */ class BrokenFlagType extends FlagTypeBase { diff --git a/lib/Drupal/flag/FlagTypeBase.php b/lib/Drupal/flag/FlagTypeBase.php index ac41efd..2bf5473 100644 --- a/lib/Drupal/flag/FlagTypeBase.php +++ b/lib/Drupal/flag/FlagTypeBase.php @@ -8,59 +8,87 @@ namespace Drupal\flag; +use Drupal\flag\FlagTypePluginInterface; use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\PluginFormInterface; /** * Class FlagTypeBase * @package Drupal\flag\Plugin\Flag - * - * @FlagType( - * id = "flagtype_base", - * title = @Translation("Flag Type Base") - * ) */ -abstract class FlagTypeBase extends PluginBase { +abstract class FlagTypeBase extends PluginBase implements FlagTypePluginInterface{ /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, array $plugin_definition) { - $configuration += $this->options(); + $configuration += $this->defaultConfiguration(); parent::__construct($configuration, $plugin_id, $plugin_definition); } - public static function entityTypes() { + /** + * Provides the default configuration values for the flag type. + * + * @return array + */ + public function defaultConfiguration() { return array(); } /** - * Declares the options this flag supports, and their default values. + * Returns this flag type plugin's configuration array. * - * Derived classes should want to override this. + * @return array + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * Replaces the plugin's configurations with those given in the parameter. * - * @todo Rename to defaultConfiguration()? + * @param array $configuration */ - public function options() { - return array(); + public function setConfiguration(array $configuration) { + $this->configuration = $configuration; } /** - * Provides a form for setting options. + * Provides a form for this action link plugin settings. * - * Derived classes should want to override this. + * The form provided by this method is displayed by the FlagAddForm when creating + * or editing the Flag. Derived classes should want to override this. + * + * @param array $form + * @param array $form_state + * @return array + * The form array + * @see \Drupal\flag\Form\FlagAddForm */ public function buildConfigurationForm(array $form, array &$form_state) { return $form; } -/** - * Handles the form submit for this plugin. - * - * @param array $form - * @param array $form_state - */ -public function submitConfigurationForm(array &$form, array &$form_state) { - // Override this + /** + * Handles the form submit for this action link plugin. + * + * Derived classes will want to override this. + * + * @param array $form + * @param array $form_state + */ + public function submitConfigurationForm(array &$form, array &$form_state) { + // Override this. + } + + /** + * Handles the validation for the action link plugin settings form. + * + * @param array $form + * @param array $form_state + */ + public function validateConfigurationForm(array &$form, array &$form_state) { + // Override this. } /** diff --git a/lib/Drupal/flag/FlagTypePluginInterface.php b/lib/Drupal/flag/FlagTypePluginInterface.php new file mode 100644 index 0000000..2436386 --- /dev/null +++ b/lib/Drupal/flag/FlagTypePluginInterface.php @@ -0,0 +1,20 @@ + 10, ); - $bundles = entity_get_bundles($entity_type); + $flag_type_plugin = \Drupal::service('plugin.manager.flag.flagtype')->createInstance($step1_form['flag_entity_type']); + $flag_type_def = $flag_type_plugin->getPluginDefinition(); + + $bundles = entity_get_bundles($flag_type_def['entity_type']); $entity_bundles = array(); foreach ($bundles as $bundle_id => $bundle_row) { $entity_bundles[$bundle_id] = $bundle_row['label']; @@ -156,7 +159,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) 'unflag' => array(DRUPAL_AUTHENTICATED_RID), ); } -*/ + $form['access']['roles'] = array( '#title' => t('Roles that may use this flag'), '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), @@ -174,20 +177,37 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) else { $form['access']['roles']['#description'] .= ' ' . t('Anonymous users may flag content if the Session API module is installed.'); } +*/ + foreach (user_roles() as $rid => $role_info) { + $access_roles_default_value = array(); + if ($rid == $step1_form['flag_role'] || $step1_form['flag_role'] == '0') { + $access_roles_default_value = array('flag', 'unflag'); + } + $form['access']['roles'][$rid] = array( + '#type' => 'checkboxes', + '#options' => array('flag' => t('Flag'), 'unflag' => t('Unflag')), + '#attributes' => array( + 'class' => array('container-inline'), + ), + '#title' => $role_info->label, + '#default_value' => $access_roles_default_value, + ); + } +/* $form['access']['roles']['flag'] = array( '#type' => 'checkboxes', - '#options' => user_roles(!module_exists('session_api')), + '#options' => $role_options, // '#default_value' => $flag->roles['flag'], '#parents' => array('roles', 'flag'), ); $form['access']['roles']['unflag'] = array( '#type' => 'checkboxes', - '#options' => user_roles(!module_exists('session_api')), + '#options' => $role_options, // '#default_value' => $flag->roles['unflag'], '#parents' => array('roles', 'unflag'), ); - +*/ $form['access']['unflag_denied_text'] = array( '#type' => 'textfield', '#title' => t('Unflag not allowed text'), @@ -206,13 +226,14 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) // '#after_build' => array('flag_link_type_options_states'), ); + $form = $flag_type_plugin->buildConfigurationForm($form, $form_state); + $form['display']['link_type'] = array( '#type' => 'radios', '#title' => t('Link type'), - '#options' => _flag_link_type_options(), - // @todo: Move flag_check_link_types into controller? + '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), // '#after_build' => array('flag_check_link_types'), - '#default_value' => $flag->link_type, + '#default_value' => $step1_form['flag_link_type'], // Give this a high weight so additions by the flag classes for entity- // specific options go above. '#weight' => 18, @@ -225,10 +246,13 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) ); // Add the descriptions to each ratio button element. These attach to the // elements when FormAPI expands them. - foreach (_flag_link_type_descriptions() as $key => $description) { - $form['display']['link_type'][$key]['#description'] = $description; + $action_link_plugin_defs = \Drupal::service('plugin.manager.flag.linktype')->getDefinitions(); + foreach ($action_link_plugin_defs as $key => $info) { + $form['display']['link_type'][$key]['#description'] = $info['description']; } + +/* $form['display']['link_options_intro'] = array( // This is a hack to allow a markup element to use FormAPI states. // @see http://www.bywombats.com/blog/06-25-2011/using-containers-states-enabled-markup-form-elements @@ -269,6 +293,10 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) // Allow the flag handler to make additions and changes to the form. // Note that the flag_broken handler will completely empty the form array! // $flag->options_form($form); +*/ + $action_link_plugin = \Drupal::service('plugin.manager.flag.linktype')->createInstance($step1_form['flag_link_type']); + + $form = $action_link_plugin->buildConfigurationForm($form, $form_state); return $form; } diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index 3a5a897..cd9876a 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -97,10 +97,12 @@ public function buildForm(array $form, array &$form_state) { } public function validateForm(array &$form, array &$form_state) { + /* $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); if (get_class($flag) == 'BrokenFlag') { form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); } + */ } public function submitForm(array &$form, array &$form_state) { diff --git a/lib/Drupal/flag/Plugin/ActionLink/Reload.php b/lib/Drupal/flag/Plugin/ActionLink/Reload.php index bb9619e..1ab3889 100644 --- a/lib/Drupal/flag/Plugin/ActionLink/Reload.php +++ b/lib/Drupal/flag/Plugin/ActionLink/Reload.php @@ -6,6 +6,8 @@ * Time: 8:21 PM */ +namespace Drupal\flag\Plugin\ActionLink; + use Drupal\flag\ActionLinkTypeBase; /** @@ -19,6 +21,9 @@ */ class Reload extends ActionLinkTypeBase { + /** + * @return string + */ public function buildLink() { return "/flag/"; } diff --git a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php index e5d4679..d1d196b 100644 --- a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php @@ -22,7 +22,7 @@ public function getDerivativeDefinitions(array $base_plugin_def) { foreach (entity_get_info() as $entity_id => $entity_info) { $derivatives[$entity_id] = array( 'title' => $entity_id, - 'entity' => $entity_id, + 'entity_type' => $entity_id, ) + $base_plugin_def; } diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php index 5e4ee65..5cbfc83 100644 --- a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php @@ -18,24 +18,16 @@ * * @FlagType( * id = "flagtype_comment", - * title = @Translation("Comment") + * title = @Translation("Comment"), + * entity_type = "comment" * ) */ class CommentFlagType extends EntityFlagType { public $access_author; - public static function entityTypes() { - return array( - 'comment' => array( - 'title' => t('Comments'), - 'description' => t('Comments are responses to node content.'), - ), - ); - } - - public function options() { - $options = parent::options(); + public function defaultConfiguration() { + $options = parent::defaultConfiguration(); $options += array( 'access_author' => '', ); @@ -45,8 +37,8 @@ public function options() { /** * Options form extras for comment flags. */ - public function options_form(&$form) { - parent::options_form($form); + public function buildConfigurationForm(array $form, array &$form_state) { + parent::buildConfigurationForm($form, $form_state); $form['access']['access_author'] = array( '#type' => 'radios', @@ -61,6 +53,8 @@ public function options_form(&$form) { '#default_value' => $this->access_author, '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), ); + + return $form; } public function type_access_multiple($entity_ids, $account) { diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php index 633efea..28d40e7 100644 --- a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php @@ -8,7 +8,7 @@ namespace Drupal\flag\Plugin\Flag; -use Drupal\flag\Plugin\Flag\FlagTypeBase; +use Drupal\flag\FlagTypeBase; /** * Class EntityFlagType @@ -35,24 +35,12 @@ class EntityFlagType extends FlagTypeBase { public $show_contextual_link; public function __construct(array $configuration, $plugin_id, array $plugin_definition) { - array_push($this->types, $plugin_definition['entity']); + array_push($this->types, $plugin_definition['entity_type']); parent::__construct($configuration, $plugin_id, $plugin_definition); } - public static function entityTypes() { - $entity_types = array(); - foreach (entity_get_info() as $entity_id => $entity_info) { - $entity_types[$entity_id] = array( - 'title' => $entity_info['label'], - 'description' => t('@entity-type entity', array('@entity-type' => $entity_info['label'])), - ); - } - - return $entity_types; - } - - function options() { - $options = parent::options(); + public function defaultConfiguration() { + $options = parent::defaultConfiguration(); $options += array( // Output the flag in the entity links. // This is empty for now and will get overriden for different @@ -73,20 +61,8 @@ function options() { /** * Options form extras for the generic entity flag. */ - function options_form(&$form) { - $bundles = array(); - $bundle_info = entity_get_bundles($this->entity_type); - foreach ($bundle_info as $bundle_key => $info) { - $bundles[$bundle_key] = $info['label']; - } - $form['access']['types'] = array( - '#type' => 'checkboxes', - '#title' => t('Bundles'), - '#options' => $bundles, - '#description' => t('Select the bundles that this flag may be used on. Leave blank to allow on all bundles for the entity type.'), - '#default_value' => $this->types, - ); - + public function buildConfigurationForm(array $form, array &$form_state) { + /* // Add checkboxes to show flag link on each entity view mode. $options = array(); $defaults = array(); @@ -138,6 +114,8 @@ function options_form(&$form) { '#access' => module_exists('contextual'), '#weight' => 10, ); + */ + return $form; } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index a0d15c8..0de1699 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -18,24 +18,16 @@ * * @FlagType( * id = "flagtype_node", - * title = @Translation("Content") + * title = @Translation("Content"), + * entity_type = "node" * ) */ class NodeFlagType extends EntityFlagType { public $access_author; - public static function entityTypes() { - return array( - 'node' => array( - 'title' => t('Nodes'), - 'description' => t("Nodes are a Drupal site's primary content."), - ), - ); - } - - public function options() { - $options = parent::options(); + public function defaultConfiguration() { + $options = parent::defaultConfiguration(); // Use own display settings in the meanwhile. $options += array( 'i18n' => 0, @@ -46,8 +38,8 @@ public function options() { /** * Options form extras for node flags. */ - public function options_form(&$form) { - parent::options_form($form); + public function buildConfigurationForm(array $form, array &$form_state) { + parent::buildConfigurationForm($form, $form_state); $form['access']['access_author'] = array( '#type' => 'radios', @@ -69,7 +61,7 @@ public function options_form(&$form) { '1' => t('Flag translations of content as a group'), '0' => t('Flag each translation of content separately'), ), - '#default_value' => $this->i18n, + //'#default_value' => $this->i18n, '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), '#access' => module_exists('translation_helpers'), '#weight' => 5, @@ -79,7 +71,9 @@ public function options_form(&$form) { $form['display']['show_on_form'] = array( '#title' => t('Display checkbox on node edit form'), '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), - ) + $form['display']['show_on_form']; + );// + $form['display']['show_on_form']; + + return $form; } function type_access_multiple($entity_ids, $account) { diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php index 8a6c354..62979d4 100644 --- a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php @@ -17,7 +17,7 @@ * @FlagType( * id = "flagtype_user", * title = @Translation("User"), - * entity = "user" + * entity_type = "user" * ) */ class UserFlagType extends FlagTypeBase { @@ -26,17 +26,8 @@ class UserFlagType extends FlagTypeBase { public $show_on_profile; - public static function entityTypes() { - return array( - 'user' => array( - 'title' => t('Users'), - 'description' => t('Users who have created accounts on your site.'), - ), - ); - } - - function options() { - $options = parent::options(); + public function defaultConfiguration() { + $options = parent::defaultConfiguration(); $options += array( 'show_on_profile' => TRUE, 'access_uid' => '', @@ -47,8 +38,8 @@ function options() { /** * Options form extras for user flags. */ - function options_form(&$form) { - parent::options_form($form); + public function buildConfigurationForm(array $form, array &$form_state) { + parent::buildConfigurationForm($form, $form_state); $form['access']['types'] = array( // A user flag doesn't support node types. // TODO: Maybe support roles instead of node types. @@ -69,6 +60,8 @@ function options_form(&$form) { // Put this above 'show on entity'. '#weight' => -1, ); + + return $form; } function type_access_multiple($entity_ids, $account) { From fbe65b5e9f258b5a040a505a3d16aa93bdd7f7a6 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 22 Dec 2013 13:05:24 -0600 Subject: [PATCH 357/629] Flag entity and FlagAddForm now save the flag type and link type plugins. --- lib/Drupal/flag/Entity/Flag.php | 85 ++++++++++++++++++++++++++-- lib/Drupal/flag/FlagTypeBase.php | 2 +- lib/Drupal/flag/Form/FlagAddForm.php | 8 +-- 3 files changed, 86 insertions(+), 9 deletions(-) diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 8fb2f93..782fa6f 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -9,6 +9,7 @@ namespace Drupal\flag\Entity; use Drupal\Component\Plugin\DefaultSinglePluginBag; +use Drupal\Compontent\Plugin\ConfigurablePluginInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageControllerInterface; use Drupal\Core\Entity\Annotation\EntityType; @@ -149,12 +150,27 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $unflag_denied_text = ''; + /** + * The plugin ID of the flag type. + * + * @var string + */ + protected $flag_type; + + protected $flagTypeBag; + + protected $flagTypeConfig = array(); + /** * The link type used by the flag, as defined in hook_flag_link_type_info(). * * @var string */ - public $link_type = 'toggle'; //@todo Convert to plugin + protected $link_type; + + protected $linkTypeBag; + + protected $linkTypeConfig = array(); /** * The weight of the flag. @@ -163,15 +179,17 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $weight = 0; - protected $typesBag; - /** * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(); */ public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); - $this->typesBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), $this->types, array()); + $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), + $this->flag_type, $this->flagTypeConfig); + + $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), + $this->link_type, $this->linkTypeConfig); } public function enable() { @@ -198,4 +216,63 @@ public function isFlagged(AccountInterface $account = NULL) { } } + /** + * Get the flag type plugin for this flag. + * + * @return FlagTypePluginInterface + */ + public function getFlagTypePlugin() { + return $this->flagTypeBag->get($this->flag_type); + } + + /** + * Set the flag type plugin. + * + * @param string $pluginID + * A string containing the flag type plugin ID. + */ + public function setFlagTypePlugin($pluginID) { + $this->flag_type = $pluginID; + $this->flagTypeBag->addInstanceId($pluginID); + } + + /** + * Get the link type plugin for this flag. + * + * @return LinkTypePluginInterface + */ + public function getLinkTypePlugin() { + return $this->linkTypeBag->get($this->link_type); + } + + /** + * Set the link type plugin. + * + * @param string $pluginID + * A string containing the link type plugin ID. + */ + public function setlinkTypePlugin($pluginID) { + $this->link_type = $pluginID; + $this->linkTypeBag->addInstanceId($pluginID); + } + + /** + * @param EntityStorageControllerInterface $storage_controller + */ + public function preSave(EntityStorageControllerInterface $storage_controller) { + parent::preSave($storage_controller); + + // Save the Flag Type configuration. + $flagTypePlugin = $this->getFlagTypePlugin(); + if ($flagTypePlugin instanceof ConfigurablePluginInterface) { + $this->set('flagTypeConfig', $flagTypePlugin->getConfiguration()); + } + + // Save the Link Type configuration. + $linkTypePlugin = $this->getLinkTypePlugin(); + if ($linkTypePlugin instanceof ConfigurablePluginInterface) { + $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); + } + } + } \ No newline at end of file diff --git a/lib/Drupal/flag/FlagTypeBase.php b/lib/Drupal/flag/FlagTypeBase.php index 2bf5473..ec2412d 100644 --- a/lib/Drupal/flag/FlagTypeBase.php +++ b/lib/Drupal/flag/FlagTypeBase.php @@ -22,8 +22,8 @@ abstract class FlagTypeBase extends PluginBase implements FlagTypePluginInterfac * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, array $plugin_definition) { - $configuration += $this->defaultConfiguration(); parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->configuration += $this->defaultConfiguration(); } /** diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index a2d8a19..293028d 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -20,13 +20,13 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) $tempstore = \Drupal::service('user.tempstore')->get('flag'); $step1_form = $tempstore->get('FlagAddPage'); - $flag = $this->entity; //\Drupal\flag\Handlers\AbstractFlag::factory_by_entity_type($entity_type); + $flag = $this->entity; + $flag->setFlagTypePlugin($step1_form['flag_entity_type']); + $flag->setLinkTypePlugin($step1_form['flag_link_type']); // Mark the flag as new. $flag->is_new = TRUE; $type_info = flag_fetch_definition($entity_type); - // drupal_set_title(t('Add new @type flag', array('@type' => $type_info['title']))); - $form['#flag'] = $flag; $form['#flag_name'] = $flag->id; @@ -117,7 +117,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#weight' => 10, ); - $flag_type_plugin = \Drupal::service('plugin.manager.flag.flagtype')->createInstance($step1_form['flag_entity_type']); + $flag_type_plugin = $flag->getFlagTypePlugin(); $flag_type_def = $flag_type_plugin->getPluginDefinition(); $bundles = entity_get_bundles($flag_type_def['entity_type']); From 5b4ef1ce8ff988ba9ab03638751562d86e2d570a Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 29 Dec 2013 16:20:14 -0600 Subject: [PATCH 358/629] Flag plugin form settings now save to entity. --- flag.module | 2 +- .../flag/Controller/FlagListController.php | 21 ++++++- lib/Drupal/flag/Entity/Flag.php | 62 ++++++++++++++++++- lib/Drupal/flag/FlagInterface.php | 11 +++- lib/Drupal/flag/Form/FlagAddForm.php | 45 ++++++++++---- .../flag/Plugin/Flag/CommentFlagType.php | 8 ++- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 10 ++- lib/Drupal/flag/Plugin/Flag/UserFlagType.php | 15 ++--- 8 files changed, 143 insertions(+), 31 deletions(-) diff --git a/flag.module b/flag.module index 17136f5..6820cba 100644 --- a/flag.module +++ b/flag.module @@ -435,7 +435,7 @@ function flag_permission() { $flags = flag_get_flags(); // Provide flag and unflag permissions for each flag. foreach ($flags as $flag_name => $flag) { - $permissions += $flag->get_permissions(); + // $permissions += $flag->get_permissions(); } return $permissions; diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index a71b70d..814b994 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -25,15 +25,32 @@ public function buildHeader() { return $header + parent::buildHeader(); } + protected function getFlagRoles(FlagInterface $flag) { + $allRoles = user_roles(); + $out = ''; + + foreach ($flag->getPermissions() as $rid => $perms) { + $out .= $allRoles[$rid]->label; + $out .= ', '; + } + + if (empty($out)) { + return 'None'; + } + + return rtrim($out, ', '); + } + /** * Overrides Drupal\Core\Entity\EntityListController::buildRow(). */ public function buildRow(EntityInterface $entity) { + $row['label'] = $this->getLabel($entity); - $row['roles'] = ' '; + $row['roles'] = $this->getFlagRoles($entity); - $row['is_global'] = $entity->is_global ? t('Yes') : t('No'); + $row['is_global'] = $entity->isGlobal() ? t('Yes') : t('No'); return $row + parent::buildRow($entity); } diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 782fa6f..10b4c2f 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -83,14 +83,14 @@ class Flag extends ConfigEntityBase implements FlagInterface { * * @var bool */ - public $is_global = FALSE; + protected $is_global = FALSE; /** * Whether this flag is enabled. * * @var bool */ - public $enabled = TRUE; + protected $enabled = TRUE; /** * The sub-types, AKA bundles, this flag applies to. @@ -179,6 +179,8 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $weight = 0; + protected $roles = array(); + /** * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(); */ @@ -256,6 +258,62 @@ public function setlinkTypePlugin($pluginID) { $this->linkTypeBag->addInstanceId($pluginID); } + /** + * @return array + */ + public function getPermissions() { + return $this->roles; + } + + /** + * @param $roleID + * @param $canFlag + * @param $canUnflag + */ + public function setPermission($roleID, $canFlag, $canUnflag) { + if (!$canFlag && !$canUnflag) { + unset($this->roles[$roleID]); + } + else { + $this->roles[$roleID] = array( + 'flag' => $canFlag ? TRUE : FALSE, + 'unflag' => $canUnflag ? TRUE : FALSE, + ); + } + } + + /** + * @param array $flagPermssions + */ + public function setPermissions(array $flagRoles, array $unflagRoles) { + $this->roles = array(); + + foreach ($flagRoles as $roleID => $value) { + if (!empty($value)) { + $this->roles[$roleID]['flag'] = TRUE; + } + } + + foreach ($unflagRoles as $roleID => $value) { + if (!empty($value)) { + $this->roles[$roleID]['unflag'] = TRUE; + } + } + } + + public function isGlobal() { + return $this->is_global; + } + + public function setGlobal($isGlobal = TRUE) { + if ($isGlobal) { + $this->is_global = TRUE; + } + else { + $this->is_global = FALSE; + } + } + /** * @param EntityStorageControllerInterface $storage_controller */ diff --git a/lib/Drupal/flag/FlagInterface.php b/lib/Drupal/flag/FlagInterface.php index 0113880..d97b766 100644 --- a/lib/Drupal/flag/FlagInterface.php +++ b/lib/Drupal/flag/FlagInterface.php @@ -18,4 +18,13 @@ public function enable(); public function disable(); -} \ No newline at end of file + public function getPermissions(); + + public function setPermission($roleID, $canFlag, $canUnflag); + + public function setPermissions(array $flagRoles, array $unflagRoles); + + public function isGlobal(); + + public function setGlobal($isGlobal); +} \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index 293028d..2f4513d 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -13,6 +13,24 @@ class FlagAddForm extends EntityFormController { + protected function getRoleOptions() { + $role_options = array(); + + foreach (user_roles() as $rid => $role_info) { + $role_options[$rid] = $role_info->label; + } + + return $role_options; + } + + protected function getRoleDefault($selction) { + if ($selction == 0) { + return array_keys(user_roles()); + } + + return array($selection); + } + public function buildForm(array $form, array &$form_state, $entity_type = NULL) { //@todo Check all non-form_* params with check_plain(). $form = parent::buildForm($form, $form_state); @@ -53,10 +71,10 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#disabled' => !$flag->isNew(), ); - $form['global'] = array( + $form['is_global'] = array( '#type' => 'checkbox', '#title' => t('Global flag'), - '#default_value' => $flag->is_global, + '#default_value' => $flag->isGlobal(), '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), '#weight' => -1, ); @@ -159,7 +177,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) 'unflag' => array(DRUPAL_AUTHENTICATED_RID), ); } - +*/ $form['access']['roles'] = array( '#title' => t('Roles that may use this flag'), '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), @@ -171,13 +189,13 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) 'css' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.css'), ), ); - if (module_exists('session_api')) { +/* if (module_exists('session_api')) { $form['access']['roles']['#description'] .= ' ' . t('Support for anonymous users is being provided by Session API.'); } else { $form['access']['roles']['#description'] .= ' ' . t('Anonymous users may flag content if the Session API module is installed.'); } -*/ +*//* foreach (user_roles() as $rid => $role_info) { $access_roles_default_value = array(); if ($rid == $step1_form['flag_role'] || $step1_form['flag_role'] == '0') { @@ -194,20 +212,22 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#default_value' => $access_roles_default_value, ); } -/* +*/ $form['access']['roles']['flag'] = array( '#type' => 'checkboxes', - '#options' => $role_options, -// '#default_value' => $flag->roles['flag'], + '#title' => 'Roles that may flag', + '#options' => $this->getRoleOptions(), + '#default_value' => $this->getRoleDefault($step1_form['flag_role']), '#parents' => array('roles', 'flag'), ); $form['access']['roles']['unflag'] = array( '#type' => 'checkboxes', - '#options' => $role_options, -// '#default_value' => $flag->roles['unflag'], + '#title' => 'Roles that may unflag', + '#options' => $this->getRoleOptions(), + '#default_value' => $this->getRoleDefault($step1_form['flag_role']), '#parents' => array('roles', 'unflag'), ); -*/ + $form['access']['unflag_denied_text'] = array( '#type' => 'textfield', '#title' => t('Unflag not allowed text'), @@ -337,7 +357,8 @@ public function validate(array $form, array &$form_state) { public function save(array $form, array &$form_state) { $flag = $this->entity; - $form_state['values']['label'] = trim($form_state['values']['label']); + $flag->getFlagTypePlugin()->submitConfigurationForm($form, $form_state); + $flag->getLinkTypePlugin()->submitConfigurationForm($form, $form_state); $flag->enable(); $status = $flag->save(); diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php index 5cbfc83..b909b71 100644 --- a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php @@ -24,8 +24,6 @@ */ class CommentFlagType extends EntityFlagType { - public $access_author; - public function defaultConfiguration() { $options = parent::defaultConfiguration(); $options += array( @@ -50,13 +48,17 @@ public function buildConfigurationForm(array $form, array &$form_state) { 'node_own' => t('Users may only flag comments of nodes they own'), 'node_others' => t('Users may only flag comments of nodes by others'), ), - '#default_value' => $this->access_author, + '#default_value' => $this->configuration['access_author'], '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), ); return $form; } + public function submitConfigurationForm(array &$form, array &$form_state) { + $this->configuration['access_author'] = $form_state['value']['access']['access_author']; + } + public function type_access_multiple($entity_ids, $account) { $access = array(); diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index 0de1699..4ac3c74 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -24,8 +24,6 @@ */ class NodeFlagType extends EntityFlagType { - public $access_author; - public function defaultConfiguration() { $options = parent::defaultConfiguration(); // Use own display settings in the meanwhile. @@ -49,7 +47,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { 'own' => t('Users may only flag content they own'), 'others' => t('Users may only flag content of others'), ), - '#default_value' => $this->access_author, + '#default_value' => $this->configuration['access_author'], '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), ); @@ -76,6 +74,12 @@ public function buildConfigurationForm(array $form, array &$form_state) { return $form; } + public function submitConfigurationForm(array &$form, array &$form_state) { + $this->configuration['access_author'] = $form_state['values']['access']['access_author']; + $this->configuration['i18n'] = $form_state['values']['i18n']; + $this->configuration['show_on_form'] = $form_state['values']['display']['show_on_form']; + } + function type_access_multiple($entity_ids, $account) { $access = array(); diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php index 62979d4..bbe1f29 100644 --- a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php @@ -8,7 +8,7 @@ namespace Drupal\flag\Plugin\Flag; -use Drupal\flag\Plugin\Flag\FlagTypeBase; +use Drupal\flag\FlagTypeBase; /** * Class UserFlagType @@ -22,10 +22,6 @@ */ class UserFlagType extends FlagTypeBase { - public $access_uid; - - public $show_on_profile; - public function defaultConfiguration() { $options = parent::defaultConfiguration(); $options += array( @@ -50,13 +46,13 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#type' => 'checkbox', '#title' => t('Users may flag themselves'), '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themself does not make sense.'), - '#default_value' => $this->access_uid ? 0 : 1, + '#default_value' => $this->configuration['access_uid'] ? 0 : 1, ); $form['display']['show_on_profile'] = array( '#type' => 'checkbox', '#title' => t('Display link on user profile page'), '#description' => t('Show the link formatted as a user profile element.'), - '#default_value' => $this->show_on_profile, + '#default_value' => $this->configuration['show_on_profile'], // Put this above 'show on entity'. '#weight' => -1, ); @@ -64,6 +60,11 @@ public function buildConfigurationForm(array $form, array &$form_state) { return $form; } + public function submitConfigurationForm(array &$form, array &$form_state) { + $this->configuration['access_uid'] = $form_state['values']['access']['access_uid']; + $this->configuration['show_on_profile'] = $form_state['values']['display']['show_on_profile']; + } + function type_access_multiple($entity_ids, $account) { $access = array(); From bf058029d5aab9e90c7722e6ae590059ab46f90f Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 4 Jan 2014 00:44:10 -0600 Subject: [PATCH 359/629] Split Flag Add form into base, add, and edit forms. --- lib/Drupal/flag/Entity/Flag.php | 24 +- lib/Drupal/flag/Form/FlagAddForm.php | 380 +------------------------- lib/Drupal/flag/Form/FlagEditForm.php | 21 ++ lib/Drupal/flag/Form/FlagFormBase.php | 307 +++++++++++++++++++++ 4 files changed, 346 insertions(+), 386 deletions(-) create mode 100644 lib/Drupal/flag/Form/FlagEditForm.php create mode 100644 lib/Drupal/flag/Form/FlagFormBase.php diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 10b4c2f..758eb2a 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -29,7 +29,7 @@ * "list" = "Drupal\flag\Controller\FlagListController", * "form" = { * "add" = "Drupal\flag\Form\FlagAddForm", - * "edit" = "Drupal\flag\Form\FlagAddForm", + * "edit" = "Drupal\flag\Form\FlagEditForm", * "delete" = "Drupal\flag\Form\FlagAddForm" * } * }, @@ -179,7 +179,10 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $weight = 0; - protected $roles = array(); + protected $roles = array( + 'flag' => array(), + 'unflag' => array(), + ); /** * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(); @@ -286,19 +289,10 @@ public function setPermission($roleID, $canFlag, $canUnflag) { * @param array $flagPermssions */ public function setPermissions(array $flagRoles, array $unflagRoles) { - $this->roles = array(); - - foreach ($flagRoles as $roleID => $value) { - if (!empty($value)) { - $this->roles[$roleID]['flag'] = TRUE; - } - } - - foreach ($unflagRoles as $roleID => $value) { - if (!empty($value)) { - $this->roles[$roleID]['unflag'] = TRUE; - } - } + $this->roles = array( + 'flag' => $flagRoles, + 'unflag' => $unflagRoles, + ); } public function isGlobal() { diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index 2f4513d..a0a7cd3 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -8,20 +8,9 @@ namespace Drupal\flag\Form; -use Drupal\Core\Entity\EntityFormController; -use Drupal\flag\Handlers\AbstractFlag; +use Drupal\flag\Form\FlagFormBase; -class FlagAddForm extends EntityFormController { - - protected function getRoleOptions() { - $role_options = array(); - - foreach (user_roles() as $rid => $role_info) { - $role_options[$rid] = $role_info->label; - } - - return $role_options; - } +class FlagAddForm extends FlagFormBase { protected function getRoleDefault($selction) { if ($selction == 0) { @@ -33,382 +22,31 @@ protected function getRoleDefault($selction) { public function buildForm(array $form, array &$form_state, $entity_type = NULL) { //@todo Check all non-form_* params with check_plain(). - $form = parent::buildForm($form, $form_state); $tempstore = \Drupal::service('user.tempstore')->get('flag'); $step1_form = $tempstore->get('FlagAddPage'); $flag = $this->entity; + $flag->label = $step1_form['label']; + $flag->id = $step1_form['id']; + $flag->setFlagTypePlugin($step1_form['flag_entity_type']); $flag->setLinkTypePlugin($step1_form['flag_link_type']); // Mark the flag as new. $flag->is_new = TRUE; - $type_info = flag_fetch_definition($entity_type); - - $form['#flag'] = $flag; - $form['#flag_name'] = $flag->id; - - $form['label'] = array( - '#type' => 'textfield', - '#title' => t('Label'), - '#default_value' => $step1_form['label'], - '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), - '#maxlength' => 255, - '#required' => TRUE, - '#weight' => -3, - ); - - $form['id'] = array( - '#type' => 'machine_name', - '#title' => t('Machine name'), - '#default_value' => $step1_form['id'], - '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), - '#weight' => -2, - '#machine_name' => array( - 'exists' => 'flag_load_by_id', - ), - '#disabled' => !$flag->isNew(), - ); - - $form['is_global'] = array( - '#type' => 'checkbox', - '#title' => t('Global flag'), - '#default_value' => $flag->isGlobal(), - '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), - '#weight' => -1, - ); - - $form['messages'] = array( - '#type' => 'fieldset', - '#title' => t('Messages'), - ); - - $form['messages']['flag_short'] = array( - '#type' => 'textfield', - '#title' => t('Flag link text'), - '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), - '#description' => t('The text for the "flag this" link for this flag.'), - '#required' => TRUE, - ); - - $form['messages']['flag_long'] = array( - '#type' => 'textfield', - '#title' => t('Flag link description'), - '#default_value' => $flag->flag_long, - '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'), - ); - - $form['messages']['flag_message'] = array( - '#type' => 'textfield', - '#title' => t('Flagged message'), - '#default_value' => $flag->flag_message, - '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - ); - - $form['messages']['unflag_short'] = array( - '#type' => 'textfield', - '#title' => t('Unflag link text'), - '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), - '#description' => t('The text for the "unflag this" link for this flag.'), - '#required' => TRUE, - ); - - $form['messages']['unflag_long'] = array( - '#type' => 'textfield', - '#title' => t('Unflag link description'), - '#default_value' => $flag->unflag_long, - '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'), - ); - - $form['messages']['unflag_message'] = array( - '#type' => 'textfield', - '#title' => t('Unflagged message'), - '#default_value' => $flag->unflag_message, - '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - ); - - $form['access'] = array( - '#type' => 'fieldset', - '#title' => t('Flag access'), - '#tree' => FALSE, - '#weight' => 10, - ); - - $flag_type_plugin = $flag->getFlagTypePlugin(); - $flag_type_def = $flag_type_plugin->getPluginDefinition(); - - $bundles = entity_get_bundles($flag_type_def['entity_type']); - $entity_bundles = array(); - foreach ($bundles as $bundle_id => $bundle_row) { - $entity_bundles[$bundle_id] = $bundle_row['label']; - } - - // Flag classes will want to override this form element. - $form['access']['types'] = array( - '#type' => 'checkboxes', - '#title' => t('Flaggable types'), - '#options' => $entity_bundles, - '#default_value' => $flag->types, - '#description' => t('Check any sub-types that this flag may be used on.'), - '#required' => TRUE, - '#weight' => 10, - ); -/* - // Disabled access breaks checkboxes unless #value is hard coded. - if (!empty($flag->locked['types'])) { - $form['access']['types']['#value'] = $flag->types; - } - - // Load the user permissions into the flag. - if (isset($flag->id)) { - $flag->fetch_roles(); - } - elseif (isset($flag->import_roles)) { - // Convert the roles data from old API 2 flags that have been run through - // the update system. - // @see FlagUpdate_2::update() - $flag->roles = $flag->import_roles; - } - else { - // For new flags, provide a reasonable default value. - $flag->roles = array( - 'flag' => array(DRUPAL_AUTHENTICATED_RID), - 'unflag' => array(DRUPAL_AUTHENTICATED_RID), - ); - } -*/ - $form['access']['roles'] = array( - '#title' => t('Roles that may use this flag'), - '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), - '#theme' => 'flag_form_roles', - '#theme_wrappers' => array('form_element'), - '#weight' => -2, - '#attached' => array( - 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), - 'css' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.css'), - ), - ); -/* if (module_exists('session_api')) { - $form['access']['roles']['#description'] .= ' ' . t('Support for anonymous users is being provided by Session API.'); - } - else { - $form['access']['roles']['#description'] .= ' ' . t('Anonymous users may flag content if the Session API module is installed.'); - } -*//* - foreach (user_roles() as $rid => $role_info) { - $access_roles_default_value = array(); - if ($rid == $step1_form['flag_role'] || $step1_form['flag_role'] == '0') { - $access_roles_default_value = array('flag', 'unflag'); - } - - $form['access']['roles'][$rid] = array( - '#type' => 'checkboxes', - '#options' => array('flag' => t('Flag'), 'unflag' => t('Unflag')), - '#attributes' => array( - 'class' => array('container-inline'), - ), - '#title' => $role_info->label, - '#default_value' => $access_roles_default_value, - ); - } -*/ - $form['access']['roles']['flag'] = array( - '#type' => 'checkboxes', - '#title' => 'Roles that may flag', - '#options' => $this->getRoleOptions(), - '#default_value' => $this->getRoleDefault($step1_form['flag_role']), - '#parents' => array('roles', 'flag'), - ); - $form['access']['roles']['unflag'] = array( - '#type' => 'checkboxes', - '#title' => 'Roles that may unflag', - '#options' => $this->getRoleOptions(), - '#default_value' => $this->getRoleDefault($step1_form['flag_role']), - '#parents' => array('roles', 'unflag'), - ); - - $form['access']['unflag_denied_text'] = array( - '#type' => 'textfield', - '#title' => t('Unflag not allowed text'), - '#default_value' => $flag->unflag_denied_text, - '#description' => t('If a user is allowed to flag but not unflag, this text will be displayed after flagging. Often this is the past-tense of the link text, such as "flagged".'), - '#weight' => -1, - ); - $form['display'] = array( - '#type' => 'fieldset', - '#title' => t('Display options'), - '#description' => t('Flags are usually controlled through links that allow users to toggle their behavior. You can choose how users interact with flags by changing options here. It is legitimate to have none of the following checkboxes ticked, if, for some reason, you wish to place the the links on the page yourself.', array('@placement-url' => 'http://drupal.org/node/295383')), - '#tree' => FALSE, - '#weight' => 20, - // @todo: Move flag_link_type_options_states() into controller? -// '#after_build' => array('flag_link_type_options_states'), - ); + $flag->setPermissions($this->getRoleDefault($step1_form['flag_role']), + $this->getRoleDefault($step1_form['flag_role'])); - $form = $flag_type_plugin->buildConfigurationForm($form, $form_state); - - $form['display']['link_type'] = array( - '#type' => 'radios', - '#title' => t('Link type'), - '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), -// '#after_build' => array('flag_check_link_types'), - '#default_value' => $step1_form['flag_link_type'], - // Give this a high weight so additions by the flag classes for entity- - // specific options go above. - '#weight' => 18, - '#attached' => array( - 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), - ), - '#attributes' => array( - 'class' => array('flag-link-options'), - ), - ); - // Add the descriptions to each ratio button element. These attach to the - // elements when FormAPI expands them. - $action_link_plugin_defs = \Drupal::service('plugin.manager.flag.linktype')->getDefinitions(); - foreach ($action_link_plugin_defs as $key => $info) { - $form['display']['link_type'][$key]['#description'] = $info['description']; - } - - -/* - $form['display']['link_options_intro'] = array( - // This is a hack to allow a markup element to use FormAPI states. - // @see http://www.bywombats.com/blog/06-25-2011/using-containers-states-enabled-markup-form-elements - '#type' => 'container', - '#children' => '', - '#weight' => 20, - ); - - $form['display']['link_options_confirm'] = array( - '#type' => 'fieldset', - '#title' => t('Options for the "Confirmation form" link type'), - // Any "link type" provider module must put its settings fields inside - // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is - // the machine-name of the link type. This is necessary for the - // radiobutton's JavaScript dependency feature to work. - '#id' => 'link-options-confirm', - '#weight' => 21, - ); - - $form['display']['link_options_confirm']['flag_confirmation'] = array( - '#type' => 'textfield', - '#title' => t('Flag confirmation message'), - '#default_value' => isset($flag->flag_confirmation) ? $flag->flag_confirmation : '', - '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), - ); - - $form['display']['link_options_confirm']['unflag_confirmation'] = array( - '#type' => 'textfield', - '#title' => t('Unflag confirmation message'), - '#default_value' => isset($flag->unflag_confirmation) ? $flag->unflag_confirmation : '', - '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), - ); - - // Add our process handler to disable access to locked properties. - //@todo: Fix reference to flag_form_locked_process, or replace entirely. -// $form['#process'][] = 'flag_form_locked_process'; - - // Allow the flag handler to make additions and changes to the form. - // Note that the flag_broken handler will completely empty the form array! -// $flag->options_form($form); -*/ - $action_link_plugin = \Drupal::service('plugin.manager.flag.linktype')->createInstance($step1_form['flag_link_type']); - - $form = $action_link_plugin->buildConfigurationForm($form, $form_state); + $form = parent::buildForm($form, $form_state); return $form; } protected function actions(array $form, array &$form_state) { $actions = parent::actions($form, $form_state); - $actions['submit']['#value'] = t('Save Flag'); + $actions['submit']['#value'] = t('Create Flag'); return $actions; } - - /** - * Overrides Drupal\Core\Entity\EntityFormController::validate(). - */ - public function validate(array $form, array &$form_state) { - parent::validate($form, $form_state); - - $form_state['values']['label'] = trim($form_state['values']['label']); - $form_values = $form_state['values']; - - if ($form_values['link_type'] == 'confirm') { - if (empty($form_values['flag_confirmation'])) { - form_set_error('flag_confirmation', t('A flag confirmation message is required when using the confirmation link type.')); - } - if (empty($form_values['unflag_confirmation'])) { - form_set_error('unflag_confirmation', t('An unflag confirmation message is required when using the confirmation link type.')); - } - } -/* - if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { - form_set_error('label', t('The flag name may only contain lowercase letters, underscores, and numbers.')); - } -*/ - } - - /** - * Overrides Drupal\Core\Entity\EntityFormController::save(). - */ - public function save(array $form, array &$form_state) { - $flag = $this->entity; - - $flag->getFlagTypePlugin()->submitConfigurationForm($form, $form_state); - $flag->getLinkTypePlugin()->submitConfigurationForm($form, $form_state); - - $flag->enable(); - $status = $flag->save(); - $uri = $flag->uri(); - if ($status == SAVED_UPDATED) { - drupal_set_message(t('Flag %label has been updated.', array('%label' => $flag->label()))); - watchdog('flag', 'Flag %label has been updated.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); - } - else { - drupal_set_message(t('Flag %label has been added.', array('%label' => $flag->label()))); - watchdog('flag', 'Flag %label has been added.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); - } - - // We clear caches more vigorously if the flag was new. -// _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); - - // Save permissions. - // This needs to be done after the flag cache has been cleared, so that - // the new permissions are picked up by hook_permission(). - // This may need to move to the flag class when we implement extra permissions - // for different flag types: http://drupal.org/node/879988 - - // If the flag machine name as changed, clean up all the obsolete permissions. - if ($flag->id != $form['#flag_name']) { - $old_name = $form['#flag_name']; - $permissions = array("flag $old_name", "unflag $old_name"); - foreach (array_keys(user_roles()) as $rid) { - user_role_revoke_permissions($rid, $permissions); - } - } -/* - foreach (array_keys(user_roles(!module_exists('session_api'))) as $rid) { - // Create an array of permissions, based on the checkboxes element name. - $permissions = array( - "flag $flag->name" => $flag->roles['flag'][$rid], - "unflag $flag->name" => $flag->roles['unflag'][$rid], - ); - user_role_change_permissions($rid, $permissions); - } -*/ - // @todo: when we add database caching for flags we'll have to clear the - // cache again here. - - $form_state['redirect'] = 'admin/structure/flags'; - } - - /** - * Overrides Drupal\Core\Entity\EntityFormController::delete(). - */ - public function delete(array $form, array &$form_state) { - $form_state['redirect'] = 'admin/structure/flag'; - } } \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagEditForm.php b/lib/Drupal/flag/Form/FlagEditForm.php new file mode 100644 index 0000000..3831ccd --- /dev/null +++ b/lib/Drupal/flag/Form/FlagEditForm.php @@ -0,0 +1,21 @@ + $role_info) { + $role_options[$rid] = $role_info->label; + } + + return $role_options; + } + + public function buildForm(array $form, array &$form_state, $entity_type = NULL) { + $form = parent::buildForm($form, $form_state); + + $flag = $this->entity; + + // Mark the flag as new. + $flag->is_new = TRUE; + $type_info = flag_fetch_definition($entity_type); + + $form['#flag'] = $flag; + $form['#flag_name'] = $flag->id; + + $form['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#default_value' => $flag->label, + '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), + '#maxlength' => 255, + '#required' => TRUE, + '#weight' => -3, + ); + + $form['id'] = array( + '#type' => 'machine_name', + '#title' => t('Machine name'), + '#default_value' => $flag->id, + '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), + '#weight' => -2, + '#machine_name' => array( + 'exists' => 'flag_load_by_id', + ), + '#disabled' => !$flag->isNew(), + ); + + $form['is_global'] = array( + '#type' => 'checkbox', + '#title' => t('Global flag'), + '#default_value' => $flag->isGlobal(), + '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), + '#weight' => -1, + ); + + $form['messages'] = array( + '#type' => 'fieldset', + '#title' => t('Messages'), + ); + + $form['messages']['flag_short'] = array( + '#type' => 'textfield', + '#title' => t('Flag link text'), + '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), + '#description' => t('The text for the "flag this" link for this flag.'), + '#required' => TRUE, + ); + + $form['messages']['flag_long'] = array( + '#type' => 'textfield', + '#title' => t('Flag link description'), + '#default_value' => $flag->flag_long, + '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'), + ); + + $form['messages']['flag_message'] = array( + '#type' => 'textfield', + '#title' => t('Flagged message'), + '#default_value' => $flag->flag_message, + '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), + ); + + $form['messages']['unflag_short'] = array( + '#type' => 'textfield', + '#title' => t('Unflag link text'), + '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), + '#description' => t('The text for the "unflag this" link for this flag.'), + '#required' => TRUE, + ); + + $form['messages']['unflag_long'] = array( + '#type' => 'textfield', + '#title' => t('Unflag link description'), + '#default_value' => $flag->unflag_long, + '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'), + ); + + $form['messages']['unflag_message'] = array( + '#type' => 'textfield', + '#title' => t('Unflagged message'), + '#default_value' => $flag->unflag_message, + '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), + ); + + $form['access'] = array( + '#type' => 'fieldset', + '#title' => t('Flag access'), + '#tree' => FALSE, + '#weight' => 10, + ); + + $flag_type_plugin = $flag->getFlagTypePlugin(); + $flag_type_def = $flag_type_plugin->getPluginDefinition(); + + $bundles = entity_get_bundles($flag_type_def['entity_type']); + $entity_bundles = array(); + foreach ($bundles as $bundle_id => $bundle_row) { + $entity_bundles[$bundle_id] = $bundle_row['label']; + } + + // Flag classes will want to override this form element. + $form['access']['types'] = array( + '#type' => 'checkboxes', + '#title' => t('Flaggable types'), + '#options' => $entity_bundles, + '#default_value' => $flag->types, + '#description' => t('Check any sub-types that this flag may be used on.'), + '#required' => TRUE, + '#weight' => 10, + ); + + $form['access']['roles'] = array( + '#title' => t('Roles that may use this flag'), + '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), + '#theme' => 'flag_form_roles', + '#theme_wrappers' => array('form_element'), + '#weight' => -2, + '#attached' => array( + 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), + 'css' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.css'), + ), + ); + + $flag_permissions = $flag->getPermissions(); + + $form['access']['roles']['flag'] = array( + '#type' => 'checkboxes', + '#title' => 'Roles that may flag', + '#options' => $this->getRoleOptions(), + '#default_value' => $flag_permissions['flag'], + '#parents' => array('roles', 'flag'), + ); + $form['access']['roles']['unflag'] = array( + '#type' => 'checkboxes', + '#title' => 'Roles that may unflag', + '#options' => $this->getRoleOptions(), + '#default_value' => $flag_permissions['unflag'], + '#parents' => array('roles', 'unflag'), + ); + + $form['access']['unflag_denied_text'] = array( + '#type' => 'textfield', + '#title' => t('Unflag not allowed text'), + '#default_value' => $flag->unflag_denied_text, + '#description' => t('If a user is allowed to flag but not unflag, this text will be displayed after flagging. Often this is the past-tense of the link text, such as "flagged".'), + '#weight' => -1, + ); + + $form['display'] = array( + '#type' => 'fieldset', + '#title' => t('Display options'), + '#description' => t('Flags are usually controlled through links that allow users to toggle their behavior. You can choose how users interact with flags by changing options here. It is legitimate to have none of the following checkboxes ticked, if, for some reason, you wish to place the the links on the page yourself.', array('@placement-url' => 'http://drupal.org/node/295383')), + '#tree' => FALSE, + '#weight' => 20, + // @todo: Move flag_link_type_options_states() into controller? +// '#after_build' => array('flag_link_type_options_states'), + ); + + $form = $flag_type_plugin->buildConfigurationForm($form, $form_state); + + $form['display']['link_type'] = array( + '#type' => 'radios', + '#title' => t('Link type'), + '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), +// '#after_build' => array('flag_check_link_types'), + '#default_value' => $flag->getLinkTypePlugin()->getPluginId(), + // Give this a high weight so additions by the flag classes for entity- + // specific options go above. + '#weight' => 18, + '#attached' => array( + 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), + ), + '#attributes' => array( + 'class' => array('flag-link-options'), + ), + ); + // Add the descriptions to each ratio button element. These attach to the + // elements when FormAPI expands them. + $action_link_plugin_defs = \Drupal::service('plugin.manager.flag.linktype')->getDefinitions(); + foreach ($action_link_plugin_defs as $key => $info) { + $form['display']['link_type'][$key]['#description'] = $info['description']; + } + + $action_link_plugin = $flag->getLinkTypePlugin(); + $form = $action_link_plugin->buildConfigurationForm($form, $form_state); + + return $form; + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::validate(). + */ + public function validate(array $form, array &$form_state) { + parent::validate($form, $form_state); + + $form_state['values']['label'] = trim($form_state['values']['label']); + $form_values = $form_state['values']; + + if ($form_values['link_type'] == 'confirm') { + if (empty($form_values['flag_confirmation'])) { + form_set_error('flag_confirmation', t('A flag confirmation message is required when using the confirmation link type.')); + } + if (empty($form_values['unflag_confirmation'])) { + form_set_error('unflag_confirmation', t('An unflag confirmation message is required when using the confirmation link type.')); + } + } + /* + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { + form_set_error('label', t('The flag name may only contain lowercase letters, underscores, and numbers.')); + } + */ + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::save(). + */ + public function save(array $form, array &$form_state) { + $flag = $this->entity; + + $flag->getFlagTypePlugin()->submitConfigurationForm($form, $form_state); + $flag->getLinkTypePlugin()->submitConfigurationForm($form, $form_state); + + $flag->enable(); + $status = $flag->save(); + $uri = $flag->uri(); + if ($status == SAVED_UPDATED) { + drupal_set_message(t('Flag %label has been updated.', array('%label' => $flag->label()))); + watchdog('flag', 'Flag %label has been updated.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + } + else { + drupal_set_message(t('Flag %label has been added.', array('%label' => $flag->label()))); + watchdog('flag', 'Flag %label has been added.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + } + + // We clear caches more vigorously if the flag was new. +// _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); + + // Save permissions. + // This needs to be done after the flag cache has been cleared, so that + // the new permissions are picked up by hook_permission(). + // This may need to move to the flag class when we implement extra permissions + // for different flag types: http://drupal.org/node/879988 + + // If the flag machine name as changed, clean up all the obsolete permissions. + if ($flag->id != $form['#flag_name']) { + $old_name = $form['#flag_name']; + $permissions = array("flag $old_name", "unflag $old_name"); + foreach (array_keys(user_roles()) as $rid) { + user_role_revoke_permissions($rid, $permissions); + } + } + /* + foreach (array_keys(user_roles(!module_exists('session_api'))) as $rid) { + // Create an array of permissions, based on the checkboxes element name. + $permissions = array( + "flag $flag->name" => $flag->roles['flag'][$rid], + "unflag $flag->name" => $flag->roles['unflag'][$rid], + ); + user_role_change_permissions($rid, $permissions); + } + */ + // @todo: when we add database caching for flags we'll have to clear the + // cache again here. + + $form_state['redirect'] = 'admin/structure/flags'; + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::delete(). + */ + public function delete(array $form, array &$form_state) { + $form_state['redirect'] = 'admin/structure/flag'; + } + +} \ No newline at end of file From 9a4f27252b3cacaf2937e18f40d067e462db44fd Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 13 Jan 2014 23:57:31 -0600 Subject: [PATCH 360/629] Working Flag edit and delete forms. --- flag.routing.yml | 18 ++++++++- .../flag/Controller/FlagListController.php | 5 ++- lib/Drupal/flag/Entity/Flag.php | 30 ++++++++++---- lib/Drupal/flag/Form/FlagDeleteForm.php | 40 +++++++++++++++++++ lib/Drupal/flag/Form/FlagFormBase.php | 4 +- .../flag/Plugin/Flag/CommentFlagType.php | 2 +- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 4 +- 7 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 lib/Drupal/flag/Form/FlagDeleteForm.php diff --git a/flag.routing.yml b/flag.routing.yml index efda13c..bc999cf 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -2,6 +2,7 @@ flag_add_page: path: '/admin/structure/flags/add' defaults: _form: '\Drupal\flag\Form\FlagAddPageForm' + _title: 'Add New Flag' requirements: _permission: 'administer flags' @@ -9,6 +10,7 @@ flag.flag_list: path: '/admin/structure/flags' defaults: _entity_list: 'flag_flag' + _title: 'Flags' requirements: _permission: 'administer flags' @@ -16,20 +18,31 @@ flag_add: path: '/admin/structure/flags/add/{entity_type}' defaults: _entity_form: flag_flag.add + _title: 'Add New Flag' requirements: _permission: 'administer flags' flag_edit: - path: '/admin/structure/flags/manage/{entity_type}' + path: '/admin/structure/flags/manage/{flag_flag}' defaults: _entity_form: flag_flag.edit + _title: 'Edit Flag' requirements: - _permission: 'administer flags' + _entity_access: 'flag_flag.update' + +flag_delete: + path: '/admin/structure/flags/manage/{flag_flag}/delete' + defaults: + _entity_form: flag_flag.delete + _title: 'Delete Flag' + requirements: + _entity_access: 'flag_flag.update' flag_import: path: '/admin/structure/flags/import' defaults: _form: '\Drupal\flag\Form\FlagImportForm' + _title: 'Import Flags' requirements: _permission: 'use flag import' @@ -37,5 +50,6 @@ flag_export: path: '/admin/structure/flags/export' defaults: _form: '\Drupal\flag\Form\FlagExportForm' + _title: 'Export Flags' requirements: _permission: 'use flag import' diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index 814b994..d19c2de 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -27,9 +27,10 @@ public function buildHeader() { protected function getFlagRoles(FlagInterface $flag) { $allRoles = user_roles(); + $flagPermissions = $flag->getPermissions(); $out = ''; - foreach ($flag->getPermissions() as $rid => $perms) { + foreach ($flagPermissions['flag'] as $rid) { $out .= $allRoles[$rid]->label; $out .= ', '; } @@ -99,4 +100,4 @@ public function render() { return $build; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 758eb2a..26bbe71 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -24,13 +24,14 @@ * id = "flag_flag", * label = @Translation("Flag"), * module = "flag", + * admin_permission = "administer flags", * controllers = { * "storage" = "Drupal\Core\Config\Entity\ConfigStorageController", * "list" = "Drupal\flag\Controller\FlagListController", * "form" = { * "add" = "Drupal\flag\Form\FlagAddForm", * "edit" = "Drupal\flag\Form\FlagEditForm", - * "delete" = "Drupal\flag\Form\FlagAddForm" + * "delete" = "Drupal\flag\Form\FlagDeleteForm" * } * }, * bundle_of = "flagging", @@ -41,7 +42,7 @@ * "uuid" = "uuid" * }, * links = { - * "edit-form" = "admin/structure/flags/manage/{flag_flag}" + * "edit-form" = "flag_edit" * } * ) * @@ -316,15 +317,28 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { // Save the Flag Type configuration. $flagTypePlugin = $this->getFlagTypePlugin(); - if ($flagTypePlugin instanceof ConfigurablePluginInterface) { - $this->set('flagTypeConfig', $flagTypePlugin->getConfiguration()); - } + $this->set('flagTypeConfig', $flagTypePlugin->getConfiguration()); // Save the Link Type configuration. $linkTypePlugin = $this->getLinkTypePlugin(); - if ($linkTypePlugin instanceof ConfigurablePluginInterface) { - $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); - } + $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); + } + + public function getExportProperties() { + $properties = parent::getExportProperties(); + $names = array( + 'roles', + 'flag_type', + 'link_type', + 'flagTypeConfig', + 'linkTypeConfig', + ); + + foreach ($names as $name) { + $properties[$name] = $this->get($name); + } + + return $properties; } } \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagDeleteForm.php b/lib/Drupal/flag/Form/FlagDeleteForm.php new file mode 100644 index 0000000..3d755f6 --- /dev/null +++ b/lib/Drupal/flag/Form/FlagDeleteForm.php @@ -0,0 +1,40 @@ + $this->entity->label() + )); + } + + public function getConfirmText() { + return t('Delete'); + } + + public function getCancelRoute() { + return array( + 'route_name' => 'flag.flag_list', + ); + } + + public function submit(array $form, array &$form_state) { + $this->entity->delete(); + drupal_set_message(t('Flag %label was deleted.', array( + '%label' => $this->entity->label(), + ))); + + $form_state['redirect_route']['route_name'] = 'flag.flag_list'; + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagFormBase.php b/lib/Drupal/flag/Form/FlagFormBase.php index 657274d..7a7669a 100644 --- a/lib/Drupal/flag/Form/FlagFormBase.php +++ b/lib/Drupal/flag/Form/FlagFormBase.php @@ -28,8 +28,6 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) $flag = $this->entity; - // Mark the flag as new. - $flag->is_new = TRUE; $type_info = flag_fetch_definition($entity_type); $form['#flag'] = $flag; @@ -301,7 +299,7 @@ public function save(array $form, array &$form_state) { * Overrides Drupal\Core\Entity\EntityFormController::delete(). */ public function delete(array $form, array &$form_state) { - $form_state['redirect'] = 'admin/structure/flag'; + $form_state['redirect'] = 'admin/structure/flags'; } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php index b909b71..28ed0c5 100644 --- a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php @@ -56,7 +56,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { } public function submitConfigurationForm(array &$form, array &$form_state) { - $this->configuration['access_author'] = $form_state['value']['access']['access_author']; + $this->configuration['access_author'] = $form_state['values']['access_author']; } public function type_access_multiple($entity_ids, $account) { diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index 4ac3c74..5c1b4d7 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -75,9 +75,9 @@ public function buildConfigurationForm(array $form, array &$form_state) { } public function submitConfigurationForm(array &$form, array &$form_state) { - $this->configuration['access_author'] = $form_state['values']['access']['access_author']; + $this->configuration['access_author'] = $form_state['values']['access_author']; $this->configuration['i18n'] = $form_state['values']['i18n']; - $this->configuration['show_on_form'] = $form_state['values']['display']['show_on_form']; + $this->configuration['show_on_form'] = $form_state['values']['show_on_form']; } function type_access_multiple($entity_ids, $account) { From 0836f61c2d0d908556addfcbbf94c0eec032c5dd Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 20 Jan 2014 23:27:24 -0600 Subject: [PATCH 361/629] Implmented Drupal permissions for Flag entity. --- flag.module | 20 ++--- flag.services.yml | 3 + .../flag/Controller/FlagListController.php | 16 ++-- lib/Drupal/flag/Entity/Flag.php | 87 ++++++++++++++++--- lib/Drupal/flag/Flag.php | 66 +++++++++++++- lib/Drupal/flag/Form/FlagFormBase.php | 2 +- 6 files changed, 158 insertions(+), 36 deletions(-) diff --git a/flag.module b/flag.module index 6820cba..b96707f 100644 --- a/flag.module +++ b/flag.module @@ -11,6 +11,7 @@ define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); use Drupal\flag\Handlers\AbstractFlag; +use Drupal\flag\Flag; // @todo: Implement flagging_view(). Not extremely useful. I already have it. @@ -432,10 +433,10 @@ function flag_permission() { ), ); - $flags = flag_get_flags(); + $flags = \Drupal::service('flag')->getFlags(); // Provide flag and unflag permissions for each flag. foreach ($flags as $flag_name => $flag) { - // $permissions += $flag->get_permissions(); + $permissions += $flag->getPermissions(); } return $permissions; @@ -475,7 +476,7 @@ function flag_flag_link($flag, $action, $entity_id) { function flag_field_extra_fields() { $extra = array(); - $flags = flag_get_flags(); + $flags = $flag_service->getFlags(); foreach ($flags as $name => $flag) { // Skip flags that aren't on entities. if (!($flag instanceof flag_entity)) { @@ -763,7 +764,9 @@ function flag_contextual_links_view_alter(&$element, $items) { */ function flag_entity_view($entity, $type, $view_mode, $langcode) { // Get all possible flags for this entity type. - $flags = flag_get_flags($type); + $flag_service = \Drupal::service('flag'); + $flags = $flag_service->getFlags($entity->entityType(), + $entity->bundle()); foreach ($flags as $flag) { @@ -2330,15 +2333,6 @@ function flag_features_api() { ); } -/** - * Implements hook_ctools_plugin_directory(). - */ -function flag_ctools_plugin_directory($module, $plugin) { - if ($module == 'ctools' && !empty($plugin)) { - return "plugins/$plugin"; - } -} - // --------------------------------------------------------------------------- // Entity Metadata callbacks diff --git a/flag.services.yml b/flag.services.yml index f144eed..8476cd3 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -5,3 +5,6 @@ services: plugin.manager.flag.linktype: class: Drupal\flag\ActionLinkPluginManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] + flag: + class: Drupal\flag\Flag + arguments: ['@module_handler'] diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index d19c2de..56219be 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -26,19 +26,19 @@ public function buildHeader() { } protected function getFlagRoles(FlagInterface $flag) { - $allRoles = user_roles(); - $flagPermissions = $flag->getPermissions(); $out = ''; + $allRoles = array(); - foreach ($flagPermissions['flag'] as $rid) { - $out .= $allRoles[$rid]->label; - $out .= ', '; - } + foreach ($flag->getPermissions() as $perm => $pinfo) { + $roles = user_roles(FALSE, $perm); - if (empty($out)) { - return 'None'; + foreach ($roles as $rid => $role) { + $allRoles[$rid] = $role->label; + } } + $out = implode(', ', $allRoles); + return rtrim($out, ', '); } diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 26bbe71..4774713 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -10,6 +10,7 @@ use Drupal\Component\Plugin\DefaultSinglePluginBag; use Drupal\Compontent\Plugin\ConfigurablePluginInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageControllerInterface; use Drupal\Core\Entity\Annotation\EntityType; @@ -192,10 +193,10 @@ public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), - $this->flag_type, $this->flagTypeConfig); + array($this->flag_type), $this->flagTypeConfig); $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), - $this->link_type, $this->linkTypeConfig); + array($this->link_type), $this->linkTypeConfig); } public function enable() { @@ -240,6 +241,11 @@ public function getFlagTypePlugin() { public function setFlagTypePlugin($pluginID) { $this->flag_type = $pluginID; $this->flagTypeBag->addInstanceId($pluginID); + + // Get the entity type from the plugin definition. + $plugin = $this->getFlagTypePlugin(); + $pluginDef = $plugin->getPluginDefinition(); + $this->entity_type = $pluginDef['entity_type']; } /** @@ -265,10 +271,31 @@ public function setlinkTypePlugin($pluginID) { /** * @return array */ - public function getPermissions() { + public function getRoles() { return $this->roles; } + /** + * Provides permissions for this flag. + * + * @return + * An array of permissions for hook_permission(). + */ + function getPermissions() { + return array( + "flag $this->id" => array( + 'title' => t('Flag %flag_title', array( + '%flag_title' => $this->label, + )), + ), + "unflag $this->id" => array( + 'title' => t('Unflag %flag_title', array( + '%flag_title' => $this->label, + )), + ), + ); + } + /** * @param $roleID * @param $canFlag @@ -296,6 +323,22 @@ public function setPermissions(array $flagRoles, array $unflagRoles) { ); } + public function canFlag(AccountInterface $account) { + if ($account->id() == 0) { + return TRUE; + } + + if (in_array($account->getRoles(), $this->roles['flag'])) { + return TRUE; + } + + return FALSE; + } + + public function canUnflag(AccountInterface $account) { + return TRUE; + } + public function isGlobal() { return $this->is_global; } @@ -313,15 +356,39 @@ public function setGlobal($isGlobal = TRUE) { * @param EntityStorageControllerInterface $storage_controller */ public function preSave(EntityStorageControllerInterface $storage_controller) { - parent::preSave($storage_controller); + parent::preSave($storage_controller); - // Save the Flag Type configuration. - $flagTypePlugin = $this->getFlagTypePlugin(); - $this->set('flagTypeConfig', $flagTypePlugin->getConfiguration()); + // Save the Flag Type configuration. + $flagTypePlugin = $this->getFlagTypePlugin(); + $this->set('flagTypeConfig', $flagTypePlugin->getConfiguration()); - // Save the Link Type configuration. - $linkTypePlugin = $this->getLinkTypePlugin(); - $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); + // Save the Link Type configuration. + $linkTypePlugin = $this->getLinkTypePlugin(); + $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); + + foreach ($this->roles['flag'] as $rid => $value) { + + if (!empty($value)) { + user_role_change_permissions($rid, "flag $this->id"); + } + } + + foreach (user_roles() as $rid => $rinfo) { + $perms = array(); + + // Get the permissions from the $roles class variable. + foreach ($this->roles as $action => $roles) { + if (!empty($roles[$rid])) { + $perms["$action $this->id"] = TRUE; + } + else { + $perms["$action $this->id"] = FALSE; + } + } + + // Assign the permissions. + user_role_change_permissions($rid, $perms); + } } public function getExportProperties() { diff --git a/lib/Drupal/flag/Flag.php b/lib/Drupal/flag/Flag.php index 9785935..cbf89ac 100644 --- a/lib/Drupal/flag/Flag.php +++ b/lib/Drupal/flag/Flag.php @@ -8,12 +8,24 @@ namespace Drupal\flag; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Session\AccountInterface; + /** - * Static service container wrapper for Flag. + * Flag service. */ -class Flag { +class Flag { //@todo Rename to FlagService? - public static function flag($action, $flag_name, $entity_id, $account = NULL, $permissions_check = FALSE) { + /** + * Constructor. + * + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + */ + public function __construct(ModuleHandlerInterface $module_handler) { + $this->moduleHandler = $module_handler; + } + + public function flag($action, $flag_name, $entity_id, $account = NULL, $permissions_check = FALSE) { } @@ -29,7 +41,7 @@ public static function flag($action, $flag_name, $entity_id, $account = NULL, $p * * @see hook_flag_type_info() */ - public static function flag_fetch_definition($entity_type = NULL) { + public function fetchDefinition($entity_type = NULL) { if(!empty($entity_type)){ return \Drupal::service('plugin.manager.flag.flagtype')->getDefinition($entity_type); } @@ -37,4 +49,50 @@ public static function flag_fetch_definition($entity_type = NULL) { return \Drupal::service('plugin.manager.flag.flagtype')->getDefinitions(); } + /** + * List all flags available. + * + * If node type or account are entered, a list of all possible flags will be + * returned. + * + * @param $entity_type + * (optional) The type of entity for which to load the flags. Usually 'node'. + * @param $bundle + * (optional) The bundle for which to load the flags. + * @param $account + * (optional) The user account to filter available flags. If not set, all + * flags for the given entity and bundle will be returned. + * + * @return + * An array of the structure [fid] = flag_object. + */ + public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $account = NULL) { + $query = \Drupal::entityQuery('flag_flag'); + + if($entity_type != NULL) { + $query->condition('entity_type', $entity_type); + } + + if ($bundle != NULL) { + $query->condition("types.$bundle", $bundle); + } + + $result = $query->execute(); + + $flags = entity_load_multiple('flag_flag', $result); + + if ($account == NULL) { + return $flags; + } + + $filtered_flags = array(); + foreach ($flags as $flag) { + if ($flag->canFlag($account) || $flag->canUnflag($account)) { + $filtered_flags[] = $flag; + } + } + + return $filtered_flags; + } + } \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagFormBase.php b/lib/Drupal/flag/Form/FlagFormBase.php index 7a7669a..95249cd 100644 --- a/lib/Drupal/flag/Form/FlagFormBase.php +++ b/lib/Drupal/flag/Form/FlagFormBase.php @@ -151,7 +151,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) ), ); - $flag_permissions = $flag->getPermissions(); + $flag_permissions = $flag->getRoles(); $form['access']['roles']['flag'] = array( '#type' => 'checkboxes', From 196b53f9c2b837d9589880cc01b7c0548b081895 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 16 Feb 2014 19:26:28 -0600 Subject: [PATCH 362/629] New FlaggingAccessController (untested), various changes. --- flag.module | 26 ++++---- .../flag/Controller/FlagListController.php | 1 + lib/Drupal/flag/Entity/Flag.php | 2 +- lib/Drupal/flag/Entity/Flagging.php | 60 +++++++++---------- lib/Drupal/flag/FlaggingAccessController.php | 46 ++++++++++++++ lib/Drupal/flag/Form/FlagFormBase.php | 9 +-- 6 files changed, 95 insertions(+), 49 deletions(-) create mode 100644 lib/Drupal/flag/FlaggingAccessController.php diff --git a/flag.module b/flag.module index b96707f..026dd70 100644 --- a/flag.module +++ b/flag.module @@ -77,17 +77,6 @@ function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { */ function flag_menu() { - $items[FLAG_ADMIN_PATH] = array( - 'title' => 'Flags', - // 'route_name' => 'flag_settings', - 'description' => 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).', -// ); -// $items[FLAG_ADMIN_PATH . '/list'] = array( -// 'title' => 'List', -// 'type' => MENU_DEFAULT_LOCAL_TASK, - 'route_name' => 'flag.flag_list', - 'weight' => -10, - ); $items[FLAG_ADMIN_PATH . '/add'] = array( 'route_name' => 'flag_add_page', 'type' => MENU_SIBLING_LOCAL_TASK, @@ -181,6 +170,17 @@ function flag_menu() { return $items; } +function flag_menu_link_defaults() { + $items['flag.admin.structure.flag'] = array( + 'link_title' => 'Flags', + 'parent' => 'system.admin.structure', + 'description' => 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).', + 'route_name' => 'flag.flag_list', + ); + + return $items; +} + /** * Implements hook_admin_menu_map(). */ @@ -475,7 +475,7 @@ function flag_flag_link($flag, $action, $entity_id) { */ function flag_field_extra_fields() { $extra = array(); - +/* $flags = $flag_service->getFlags(); foreach ($flags as $name => $flag) { // Skip flags that aren't on entities. @@ -506,7 +506,7 @@ function flag_field_extra_fields() { } } } - +*/ return $extra; } diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index 56219be..6b2db31 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -10,6 +10,7 @@ use Drupal\Core\Config\Entity\ConfigEntityListController; use Drupal\Core\Entity\EntityInterface; +use Drupal\flag\FlagInterface; class FlagListController extends ConfigEntityListController { diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 4774713..fe91b63 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -369,7 +369,7 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { foreach ($this->roles['flag'] as $rid => $value) { if (!empty($value)) { - user_role_change_permissions($rid, "flag $this->id"); + user_role_change_permissions($rid, array("flag $this->id")); } } diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index f81fc20..cc65e97 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -24,9 +24,11 @@ * module = "flag", * controllers = { * "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController", + * "access" = "Drupal\flag\FlaggingAccessController", * }, * base_table = "flagging", * fieldable = TRUE, + * bundle_entity_type = "flag", * entity_keys = { * "id" = "id", * "bundle" = "type", @@ -44,40 +46,36 @@ public function getFlag() { } public static function baseFieldDefinitions($entity_type) { - $properties['id'] = array( - 'label' => t('Flagging ID'), - 'description' => t('The Flagging ID.'), - 'type' => 'integer_field', - 'read-only' => TRUE, - ); - $properties['type'] = array( - 'label' => t('Type'), - 'description' => t('The flag type.'), - 'type' => 'string_field', - 'read-only' => TRUE, - ); - $properties['uuid'] = array( - 'label' => t('UUID'), - 'description' => t('The node UUID.'), - 'type' => 'uuid_field', - 'read-only' => TRUE, - ); - $properties['uid'] = array( - 'label' => t('User ID'), - 'description' => t('The ID of the flagging user.'), - 'type' => 'entity_reference_field', - 'settings' => array( + $fields['id'] = FieldDefinition::create('integer') + ->setLabel(t('Node ID')) + ->setDescription(t('The flagging ID.')) + ->setReadOnly(TRUE); + + $fields['uuid'] = FieldDefinition::create('uuid') + ->setLabel(t('UUID')) + ->setDescription(t('The flagging UUID.')) + ->setReadOnly(TRUE); + + $fields['type'] = FieldDefinition::create('entity_reference') + ->setLabel(t('Type')) + ->setDescription(t('The flag type.')) + ->setSetting('target_type', 'flag_flag') + ->setReadOnly(TRUE); + + $fields['uid'] = FieldDefinition::create('entity_reference') + ->setLabel(t('User ID')) + ->setDescription(t('The user ID of the flagging user.')) + ->setSettings(array( 'target_type' => 'user', 'default_value' => 0, - ), - ); - $properties['created'] = array( - 'label' => t('Created'), - 'description' => t('The time that the flagging was created.'), - 'type' => 'integer_field', - ); + )); + + // @todo Convert to a "created" field in https://drupal.org/node/2145103. + $fields['created'] = FieldDefinition::create('integer') + ->setLabel(t('Created')) + ->setDescription(t('The time that the flagging was created.')); - return $properties; + return $fields; } } \ No newline at end of file diff --git a/lib/Drupal/flag/FlaggingAccessController.php b/lib/Drupal/flag/FlaggingAccessController.php new file mode 100644 index 0000000..ce92935 --- /dev/null +++ b/lib/Drupal/flag/FlaggingAccessController.php @@ -0,0 +1,46 @@ +id(), $account); + break; + + case 'delete': + case 'unflag': + return user_access('unflag' . $entity->id(), $account); + break; + } + + return parent::checkAccess($entity, $operation, $langcode, $account); + } + + protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { + return user_access('flag ' . $entity_bundle, $account); + } + + public function getRoles() { + $roles = array(); + + $roles['flag'] = user_roles(FALSE, 'flag ' . $this->entityTypeId); + $roles['unflag'] = user_roles(FALSE, 'unflag ' . $this->entityTypeId); + + return $roles; + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagFormBase.php b/lib/Drupal/flag/Form/FlagFormBase.php index 95249cd..fc7c6a9 100644 --- a/lib/Drupal/flag/Form/FlagFormBase.php +++ b/lib/Drupal/flag/Form/FlagFormBase.php @@ -151,6 +151,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) ), ); + //@todo convert to Drupal::entityManager()->getAccessController('flagging'); $flag_permissions = $flag->getRoles(); $form['access']['roles']['flag'] = array( @@ -252,16 +253,16 @@ public function save(array $form, array &$form_state) { $flag->enable(); $status = $flag->save(); - $uri = $flag->uri(); +/* $url = $flag->url(); if ($status == SAVED_UPDATED) { drupal_set_message(t('Flag %label has been updated.', array('%label' => $flag->label()))); - watchdog('flag', 'Flag %label has been updated.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('flag', 'Flag %label has been updated.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); } else { drupal_set_message(t('Flag %label has been added.', array('%label' => $flag->label()))); - watchdog('flag', 'Flag %label has been added.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); + watchdog('flag', 'Flag %label has been added.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); } - +*/ // We clear caches more vigorously if the flag was new. // _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); From d8f9dd4c2b3fb1b731567f3a086f8b44c3c3314a Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 19 Feb 2014 18:34:39 -0600 Subject: [PATCH 363/629] Added use FieldDefinition to Flagging.php --- lib/Drupal/flag/Entity/Flagging.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index cc65e97..a30b8b3 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityStorageControllerInterface; use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Field\FieldDefinition; use Drupal\flag\FlaggingInterface; /** @@ -36,6 +37,9 @@ * }, * bundle_keys = { * "bundle" = "type" + * }, + * links = { + * "admin-form" = "flag_edit" * } * ) */ From 61a164fcf6923b68b3da2780a86eb4d325f5532d Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 19 Feb 2014 20:35:29 -0600 Subject: [PATCH 364/629] Removed custom Flag permissions UI. --- .../flag/Controller/FlagListController.php | 2 +- lib/Drupal/flag/Entity/Flag.php | 79 ------------------- lib/Drupal/flag/FlagInterface.php | 4 - lib/Drupal/flag/Form/FlagFormBase.php | 43 +--------- 4 files changed, 3 insertions(+), 125 deletions(-) diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index 6b2db31..c6b3481 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -29,7 +29,7 @@ public function buildHeader() { protected function getFlagRoles(FlagInterface $flag) { $out = ''; $allRoles = array(); - + foreach ($flag->getPermissions() as $perm => $pinfo) { $roles = user_roles(FALSE, $perm); diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index fe91b63..d8112ad 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -181,11 +181,6 @@ class Flag extends ConfigEntityBase implements FlagInterface { */ public $weight = 0; - protected $roles = array( - 'flag' => array(), - 'unflag' => array(), - ); - /** * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(); */ @@ -268,13 +263,6 @@ public function setlinkTypePlugin($pluginID) { $this->linkTypeBag->addInstanceId($pluginID); } - /** - * @return array - */ - public function getRoles() { - return $this->roles; - } - /** * Provides permissions for this flag. * @@ -296,49 +284,6 @@ function getPermissions() { ); } - /** - * @param $roleID - * @param $canFlag - * @param $canUnflag - */ - public function setPermission($roleID, $canFlag, $canUnflag) { - if (!$canFlag && !$canUnflag) { - unset($this->roles[$roleID]); - } - else { - $this->roles[$roleID] = array( - 'flag' => $canFlag ? TRUE : FALSE, - 'unflag' => $canUnflag ? TRUE : FALSE, - ); - } - } - - /** - * @param array $flagPermssions - */ - public function setPermissions(array $flagRoles, array $unflagRoles) { - $this->roles = array( - 'flag' => $flagRoles, - 'unflag' => $unflagRoles, - ); - } - - public function canFlag(AccountInterface $account) { - if ($account->id() == 0) { - return TRUE; - } - - if (in_array($account->getRoles(), $this->roles['flag'])) { - return TRUE; - } - - return FALSE; - } - - public function canUnflag(AccountInterface $account) { - return TRUE; - } - public function isGlobal() { return $this->is_global; } @@ -365,30 +310,6 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { // Save the Link Type configuration. $linkTypePlugin = $this->getLinkTypePlugin(); $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); - - foreach ($this->roles['flag'] as $rid => $value) { - - if (!empty($value)) { - user_role_change_permissions($rid, array("flag $this->id")); - } - } - - foreach (user_roles() as $rid => $rinfo) { - $perms = array(); - - // Get the permissions from the $roles class variable. - foreach ($this->roles as $action => $roles) { - if (!empty($roles[$rid])) { - $perms["$action $this->id"] = TRUE; - } - else { - $perms["$action $this->id"] = FALSE; - } - } - - // Assign the permissions. - user_role_change_permissions($rid, $perms); - } } public function getExportProperties() { diff --git a/lib/Drupal/flag/FlagInterface.php b/lib/Drupal/flag/FlagInterface.php index d97b766..a25b3ea 100644 --- a/lib/Drupal/flag/FlagInterface.php +++ b/lib/Drupal/flag/FlagInterface.php @@ -20,10 +20,6 @@ public function disable(); public function getPermissions(); - public function setPermission($roleID, $canFlag, $canUnflag); - - public function setPermissions(array $flagRoles, array $unflagRoles); - public function isGlobal(); public function setGlobal($isGlobal); diff --git a/lib/Drupal/flag/Form/FlagFormBase.php b/lib/Drupal/flag/Form/FlagFormBase.php index fc7c6a9..433869f 100644 --- a/lib/Drupal/flag/Form/FlagFormBase.php +++ b/lib/Drupal/flag/Form/FlagFormBase.php @@ -13,15 +13,6 @@ abstract class FlagFormBase extends EntityFormController { - protected function getRoleOptions() { - $role_options = array(); - - foreach (user_roles() as $rid => $role_info) { - $role_options[$rid] = $role_info->label; - } - - return $role_options; - } public function buildForm(array $form, array &$form_state, $entity_type = NULL) { $form = parent::buildForm($form, $form_state); @@ -139,36 +130,6 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#weight' => 10, ); - $form['access']['roles'] = array( - '#title' => t('Roles that may use this flag'), - '#description' => t('Users may only unflag content if they have access to flag the content initially. Checking authenticated user will allow access for all logged-in users.'), - '#theme' => 'flag_form_roles', - '#theme_wrappers' => array('form_element'), - '#weight' => -2, - '#attached' => array( - 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), - 'css' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.css'), - ), - ); - - //@todo convert to Drupal::entityManager()->getAccessController('flagging'); - $flag_permissions = $flag->getRoles(); - - $form['access']['roles']['flag'] = array( - '#type' => 'checkboxes', - '#title' => 'Roles that may flag', - '#options' => $this->getRoleOptions(), - '#default_value' => $flag_permissions['flag'], - '#parents' => array('roles', 'flag'), - ); - $form['access']['roles']['unflag'] = array( - '#type' => 'checkboxes', - '#title' => 'Roles that may unflag', - '#options' => $this->getRoleOptions(), - '#default_value' => $flag_permissions['unflag'], - '#parents' => array('roles', 'unflag'), - ); - $form['access']['unflag_denied_text'] = array( '#type' => 'textfield', '#title' => t('Unflag not allowed text'), @@ -253,7 +214,7 @@ public function save(array $form, array &$form_state) { $flag->enable(); $status = $flag->save(); -/* $url = $flag->url(); + $url = $flag->url(); if ($status == SAVED_UPDATED) { drupal_set_message(t('Flag %label has been updated.', array('%label' => $flag->label()))); watchdog('flag', 'Flag %label has been updated.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); @@ -262,7 +223,7 @@ public function save(array $form, array &$form_state) { drupal_set_message(t('Flag %label has been added.', array('%label' => $flag->label()))); watchdog('flag', 'Flag %label has been added.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); } -*/ + // We clear caches more vigorously if the flag was new. // _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); From 0445fddf9a55a9a47f88f4df39e70f8d129311c3 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 19 Feb 2014 20:42:54 -0600 Subject: [PATCH 365/629] Removed Flag import export stuff. Migrate path planned instead. --- flag.module | 15 ----- .../flag/Controller/FlagListController.php | 2 +- lib/Drupal/flag/Export/FlagUpdate_2.php | 40 ------------- lib/Drupal/flag/Export/FlagUpdate_3.php | 58 ------------------- 4 files changed, 1 insertion(+), 114 deletions(-) delete mode 100644 lib/Drupal/flag/Export/FlagUpdate_2.php delete mode 100644 lib/Drupal/flag/Export/FlagUpdate_3.php diff --git a/flag.module b/flag.module index 026dd70..aa0277a 100644 --- a/flag.module +++ b/flag.module @@ -87,21 +87,6 @@ function flag_menu() { 'route_name' => 'flag_add', 'type' => MENU_CALLBACK, ); - $items[FLAG_ADMIN_PATH . '/import'] = array( - 'title' => 'Import', - 'route_name' => 'flag_import', - 'type' => MENU_LOCAL_TASK, - 'weight' => 2, - ); - $items[FLAG_ADMIN_PATH . '/export'] = array( - 'title' => 'Export', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_export_form'), - 'access arguments' => array('administer flags'), - 'file' => 'includes/flag.export.inc', - 'type' => MENU_LOCAL_TASK, - 'weight' => 3, - ); /* $items[FLAG_ADMIN_PATH . '/manage/%flag'] = array( 'load arguments' => array(TRUE), // Allow for disabled flags. diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index c6b3481..6b2db31 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -29,7 +29,7 @@ public function buildHeader() { protected function getFlagRoles(FlagInterface $flag) { $out = ''; $allRoles = array(); - + foreach ($flag->getPermissions() as $perm => $pinfo) { $roles = user_roles(FALSE, $perm); diff --git a/lib/Drupal/flag/Export/FlagUpdate_2.php b/lib/Drupal/flag/Export/FlagUpdate_2.php deleted file mode 100644 index 39dd989..0000000 --- a/lib/Drupal/flag/Export/FlagUpdate_2.php +++ /dev/null @@ -1,40 +0,0 @@ - API 2. - * - * The class name after the prefix is immaterial, though we follow the Drupal - * system update convention whereby the number here is what we update to. - */ -class FlagUpdate_2 { - - /** - * The API version this class updates a flag from. - * - * @todo: Change this to a class constant when we drop support for PHP 5.2. - */ - public $old_api_version = 1; - - /** - * The API version this class updates a flag to. - */ - public $new_api_version = 2; - - /** - * The update function for the flag. - */ - static function update(&$flag) { - if (isset($flag->roles) && !isset($flag->roles['flag'])) { - $flag->roles = array( - 'flag' => $flag->roles, - 'unflag' => $flag->roles, - ); - } - } -} \ No newline at end of file diff --git a/lib/Drupal/flag/Export/FlagUpdate_3.php b/lib/Drupal/flag/Export/FlagUpdate_3.php deleted file mode 100644 index 4951c70..0000000 --- a/lib/Drupal/flag/Export/FlagUpdate_3.php +++ /dev/null @@ -1,58 +0,0 @@ - API 3. - */ -class FlagUpdate_3 { - - public $old_api_version = 2; - public $new_api_version = 3; - - static function update(&$flag) { - // Change the content_type property to entity_type. - if (isset($flag->content_type)) { - $flag->entity_type = $flag->content_type; - unset($flag->content_type); - } - - // We can't convert the flag roles data to user permissions at this point - // because the flag is disabled and hence hook_permission() doesn't see it - // to define its permissions. - // Instead, we copy it to import_roles, which the flag add form will handle - // on new flags (which this flag will behave as when it is re-enabled). - // @see flag_form() - if (isset($flag->roles)) { - $flag->import_roles = $flag->roles; - } - - // Update show_on_teaser property to use new view mode settings. - if (!empty($flag->show_on_teaser)) { - $flag->show_in_links['teaser'] = TRUE; - unset($flag->show_on_teaser); - } - - // Update show_on_page property to use new view mode settings. - if (!empty($flag->show_on_page)) { - $flag->show_in_links['full'] = TRUE; - unset($flag->show_on_page); - } - - // Update show_on_comment and show_on_entity properties to use new view - // mode settings. Since the old logic was to show on all view modes, do that. - if (!empty($flag->show_on_entity) || !empty($flag->show_on_comment)) { - if ($entity_info = entity_get_info($flag->entity_type)) { - foreach ($entity_info['view modes'] as $view_mode => $value) { - $flag->show_in_links[$view_mode] = TRUE; - } - } - - unset($flag->show_on_entity, $flag->show_on_comment); - } - } -} \ No newline at end of file From fb27e5562c448613c5347a251e4ba93a628c6759 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 19 Feb 2014 20:56:34 -0600 Subject: [PATCH 366/629] Removed more flag permissions stuff. --- lib/Drupal/flag/Controller/FlagListController.php | 4 ++++ lib/Drupal/flag/Form/FlagAddForm.php | 3 --- lib/Drupal/flag/Form/FlagAddPageForm.php | 12 ------------ lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 6 +++--- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index 6b2db31..d4fe8dc 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -40,6 +40,10 @@ protected function getFlagRoles(FlagInterface $flag) { $out = implode(', ', $allRoles); + if (empty($out)) { + return 'None'; + } + return rtrim($out, ', '); } diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index a0a7cd3..fccc532 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -36,9 +36,6 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) // Mark the flag as new. $flag->is_new = TRUE; - $flag->setPermissions($this->getRoleDefault($step1_form['flag_role']), - $this->getRoleDefault($step1_form['flag_role'])); - $form = parent::buildForm($form, $form_state); return $form; diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index cd9876a..ed37b98 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -67,18 +67,6 @@ public function buildForm(array $form, array &$form_state) { '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), ); - $role_options = array(0 => 'All users'); - foreach (user_roles() as $rid => $role_info) { - $role_options[$rid] = $role_info->label; - } - - $form['flag_type_info']['flag_role'] = array( - '#type' => 'select', - '#title' => t('for'), - '#options' => $role_options, - '#default' => 0, - ); - $types = array(); // @todo Use \Drupal::service() to get a list of FlagType plugins. diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index 5c1b4d7..023ddae 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -66,18 +66,18 @@ public function buildConfigurationForm(array $form, array &$form_state) { ); // Override the UI texts for nodes. - $form['display']['show_on_form'] = array( + /* $form['display']['show_on_form'] = array( '#title' => t('Display checkbox on node edit form'), '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), );// + $form['display']['show_on_form']; - +*/ return $form; } public function submitConfigurationForm(array &$form, array &$form_state) { $this->configuration['access_author'] = $form_state['values']['access_author']; $this->configuration['i18n'] = $form_state['values']['i18n']; - $this->configuration['show_on_form'] = $form_state['values']['show_on_form']; +// $this->configuration['show_on_form'] = $form_state['values']['show_on_form']; } function type_access_multiple($entity_ids, $account) { From cd0f1221cf4d66fee8bc25137e917370060b69b6 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 19 Feb 2014 22:17:45 -0600 Subject: [PATCH 367/629] Fixed broken Entity::getEntityTypeID() API. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index aa0277a..b53249a 100644 --- a/flag.module +++ b/flag.module @@ -750,7 +750,7 @@ function flag_contextual_links_view_alter(&$element, $items) { function flag_entity_view($entity, $type, $view_mode, $langcode) { // Get all possible flags for this entity type. $flag_service = \Drupal::service('flag'); - $flags = $flag_service->getFlags($entity->entityType(), + $flags = $flag_service->getFlags($entity->getEntityTypeID(), $entity->bundle()); foreach ($flags as $flag) { From 71d90cf1dbfc7e0fc62a14a3dbee556cbf06f494 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 22 Feb 2014 21:30:28 -0600 Subject: [PATCH 368/629] Renamed flag\Flag to flag\FlagService. Fixed flag type plugin form build and submit. --- flag.module | 24 ++++++++--- flag.services.yml | 2 +- lib/Drupal/flag/{Flag.php => FlagService.php} | 2 +- .../flag/Plugin/Flag/CommentFlagType.php | 7 ++- .../flag/Plugin/Flag/EntityFlagType.php | 43 ++++++++++++------- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 18 ++++---- lib/Drupal/flag/Plugin/Flag/UserFlagType.php | 10 ++++- 7 files changed, 72 insertions(+), 34 deletions(-) rename lib/Drupal/flag/{Flag.php => FlagService.php} (98%) diff --git a/flag.module b/flag.module index b53249a..39ae014 100644 --- a/flag.module +++ b/flag.module @@ -460,16 +460,18 @@ function flag_flag_link($flag, $action, $entity_id) { */ function flag_field_extra_fields() { $extra = array(); -/* + + $flag_service = \Drupal::service('flag'); $flags = $flag_service->getFlags(); - foreach ($flags as $name => $flag) { + foreach ($flags as $flag) { // Skip flags that aren't on entities. - if (!($flag instanceof flag_entity)) { + $flagTypePlugin = $flag->getFlagTypePlugin(); + if (!($flagTypePlugin instanceof \Drupal\flag\Plugin\Flag\EntityFlagType)) { continue; } foreach ($flag->types as $bundle_name) { - if ($flag->show_on_form) { + if ($flagTypePlugin->showOnForm()) { $extra[$flag->entity_type][$bundle_name]['form']['flag'] = array( 'label' => t('Flags'), 'description' => t('Checkboxes for toggling flags'), @@ -477,13 +479,13 @@ function flag_field_extra_fields() { ); } - if ($flag->show_as_field) { + if ($flagTypePlugin->showAsField()) { $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $name] = array( // It would be nicer to use % as the placeholder, but the label is // run through check_plain() by field_ui_display_overview_form() // (arguably incorrectly; see http://drupal.org/node/1991292). 'label' => t('Flag: @title', array( - '@title' => $flag->title, + '@title' => $flag->label, )), 'description' => t('Individual flag link'), 'weight' => 10, @@ -491,7 +493,7 @@ function flag_field_extra_fields() { } } } -*/ + return $extra; } @@ -533,6 +535,10 @@ function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { } } +function flag_node_links_alter(array &$links, NodeInterface $entity, array &$context) { + //@todo: Define this for handling the showOnLinks() flag mode. +} + /** * Implements hook_field_attach_form(). * @@ -748,6 +754,10 @@ function flag_contextual_links_view_alter(&$element, $items) { * Note this is broken for taxonomy terms for version of Drupal core < 7.17. */ function flag_entity_view($entity, $type, $view_mode, $langcode) { + + //@todo Check $type->getComponent('flag_whateverHookFieldExtraFieldsIS'). + // if not NULL, display it. + // Get all possible flags for this entity type. $flag_service = \Drupal::service('flag'); $flags = $flag_service->getFlags($entity->getEntityTypeID(), diff --git a/flag.services.yml b/flag.services.yml index 8476cd3..25b20ef 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -6,5 +6,5 @@ services: class: Drupal\flag\ActionLinkPluginManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] flag: - class: Drupal\flag\Flag + class: Drupal\flag\FlagService arguments: ['@module_handler'] diff --git a/lib/Drupal/flag/Flag.php b/lib/Drupal/flag/FlagService.php similarity index 98% rename from lib/Drupal/flag/Flag.php rename to lib/Drupal/flag/FlagService.php index cbf89ac..256fd46 100644 --- a/lib/Drupal/flag/Flag.php +++ b/lib/Drupal/flag/FlagService.php @@ -14,7 +14,7 @@ /** * Flag service. */ -class Flag { //@todo Rename to FlagService? +class FlagService { /** * Constructor. diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php index 28ed0c5..e8115f3 100644 --- a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php @@ -36,7 +36,7 @@ public function defaultConfiguration() { * Options form extras for comment flags. */ public function buildConfigurationForm(array $form, array &$form_state) { - parent::buildConfigurationForm($form, $form_state); + $form = parent::buildConfigurationForm($form, $form_state); $form['access']['access_author'] = array( '#type' => 'radios', @@ -56,6 +56,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { } public function submitConfigurationForm(array &$form, array &$form_state) { + parent::submitConfigurationForm($form, $form_state); $this->configuration['access_author'] = $form_state['values']['access_author']; } @@ -82,4 +83,8 @@ public function type_access_multiple($entity_ids, $account) { return $access; } + + function getAccessAuthorSetting() { + return $this->configuration['access_author']; + } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php index 28d40e7..3a3cc73 100644 --- a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php @@ -24,18 +24,10 @@ */ class EntityFlagType extends FlagTypeBase { - public $types = array(); - - public $show_in_links = array(); - - public $show_as_field; - - public $show_on_form; - - public $show_contextual_link; + public $entity_type = ''; public function __construct(array $configuration, $plugin_id, array $plugin_definition) { - array_push($this->types, $plugin_definition['entity_type']); + $this->entity_type = $plugin_definition['entity_type']; parent::__construct($configuration, $plugin_id, $plugin_definition); } @@ -52,7 +44,6 @@ public function defaultConfiguration() { // Add a checkbox for the flag in the entity form. // @see hook_field_attach_form(). 'show_on_form' => FALSE, - 'access_author' => '', 'show_contextual_link' => FALSE, ); return $options; @@ -62,7 +53,7 @@ public function defaultConfiguration() { * Options form extras for the generic entity flag. */ public function buildConfigurationForm(array $form, array &$form_state) { - /* + // Add checkboxes to show flag link on each entity view mode. $options = array(); $defaults = array(); @@ -94,7 +85,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { $form['display']['show_on_form'] = array( '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), - '#default_value' => $this->show_on_form, + '#default_value' => $this->showOnForm(), '#weight' => 5, ); @@ -109,13 +100,35 @@ public function buildConfigurationForm(array $form, array &$form_state) { $form['display']['show_contextual_link'] = array( '#type' => 'checkbox', '#title' => t('Display in contextual links'), - '#default_value' => $this->show_contextual_link, + '#default_value' => $this->showContextualLink(), '#description' => t('Note that not all entity types support contextual links.'), '#access' => module_exists('contextual'), '#weight' => 10, ); - */ + return $form; } + public function submitConfigurationForm(array &$form, array &$form_state) { + parent::submitConfigurationForm($form, $form_state); + $this->configuration['show_in_links'] = $form_state['values']['show_in_links']; + $this->configuration['show_on_form'] = $form_state['values']['show_on_form']; + $this->configuration['show_contextual_link'] = $form_state['values']['show_contextual_link']; + } + + public function showInLinks() { + return $this->configuration['show_in_links']; + } + + public function showAsField() { + return $this->configuration['show_as_field']; + } + + public function showOnForm() { + return $this->configuration['show_on_form']; + } + + public function showContextualLink() { + return $this->configuration['show_contextual_link']; + } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index 023ddae..3bd0ddd 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -37,7 +37,7 @@ public function defaultConfiguration() { * Options form extras for node flags. */ public function buildConfigurationForm(array $form, array &$form_state) { - parent::buildConfigurationForm($form, $form_state); + $form = parent::buildConfigurationForm($form, $form_state); $form['access']['access_author'] = array( '#type' => 'radios', @@ -65,19 +65,13 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#weight' => 5, ); - // Override the UI texts for nodes. - /* $form['display']['show_on_form'] = array( - '#title' => t('Display checkbox on node edit form'), - '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), - );// + $form['display']['show_on_form']; -*/ return $form; } public function submitConfigurationForm(array &$form, array &$form_state) { + parent::submitConfigurationForm($form, $form_state); $this->configuration['access_author'] = $form_state['values']['access_author']; $this->configuration['i18n'] = $form_state['values']['i18n']; -// $this->configuration['show_on_form'] = $form_state['values']['show_on_form']; } function type_access_multiple($entity_ids, $account) { @@ -100,4 +94,12 @@ function type_access_multiple($entity_ids, $account) { return $access; } + + function getAccessAuthorSetting() { + return $this->configuration['access_author']; + } + + function getInternationalizationSetting() { + $this->configuration['i18n']; + } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php index bbe1f29..014ef7d 100644 --- a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/UserFlagType.php @@ -35,7 +35,7 @@ public function defaultConfiguration() { * Options form extras for user flags. */ public function buildConfigurationForm(array $form, array &$form_state) { - parent::buildConfigurationForm($form, $form_state); + $form = parent::buildConfigurationForm($form, $form_state); $form['access']['types'] = array( // A user flag doesn't support node types. // TODO: Maybe support roles instead of node types. @@ -61,6 +61,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { } public function submitConfigurationForm(array &$form, array &$form_state) { + parent::submitConfigurationForm($form, $form_state); $this->configuration['access_uid'] = $form_state['values']['access']['access_uid']; $this->configuration['show_on_profile'] = $form_state['values']['display']['show_on_profile']; } @@ -81,4 +82,11 @@ function type_access_multiple($entity_ids, $account) { return $access; } + public function getAccessUidSetting() { + return $this->configuration['access_uid']; + } + + public function showOnProfile() { + return this->configuration['show_on_profile']; + } } \ No newline at end of file From 22b96d15c3b076013039d7aefc033cc959eeb7c7 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 22 Feb 2014 23:21:30 -0600 Subject: [PATCH 369/629] Working psudofields. --- flag.module | 2 +- lib/Drupal/flag/Plugin/Flag/EntityFlagType.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/flag.module b/flag.module index 39ae014..84844e7 100644 --- a/flag.module +++ b/flag.module @@ -480,7 +480,7 @@ function flag_field_extra_fields() { } if ($flagTypePlugin->showAsField()) { - $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $name] = array( + $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $flag->label()] = array( // It would be nicer to use % as the placeholder, but the label is // run through check_plain() by field_ui_display_overview_form() // (arguably incorrectly; see http://drupal.org/node/1991292). diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php index 3a3cc73..98c862f 100644 --- a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php @@ -77,11 +77,11 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#description' => t('Show the flag link as a pseudofield, which can be ordered among other entity elements in the "Manage display" settings for the entity type.'), '#default_value' => isset($this->show_as_field) ? $this->show_as_field : TRUE, ); - if (empty($entity_info['fieldable'])) { + /* if (empty($entity_info['fieldable'])) { $form['display']['show_as_field']['#disabled'] = TRUE; $form['display']['show_as_field']['#description'] = t("This entity type is not fieldable."); } - +*/ $form['display']['show_on_form'] = array( '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), @@ -93,11 +93,11 @@ public function buildConfigurationForm(array $form, array &$form_state) { // require the entity to be fielable. Since this is a potential DX // headscratcher for a developer wondering where this option has gone, // we disable it and explain why. - if (empty($entity_info['fieldable'])) { + /* if (empty($entity_info['fieldable'])) { $form['display']['show_on_form']['#disabled'] = TRUE; $form['display']['show_on_form']['#description'] = t('This is only possible on entities which are fieldable.'); } - $form['display']['show_contextual_link'] = array( +*/ $form['display']['show_contextual_link'] = array( '#type' => 'checkbox', '#title' => t('Display in contextual links'), '#default_value' => $this->showContextualLink(), @@ -112,6 +112,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { public function submitConfigurationForm(array &$form, array &$form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['show_in_links'] = $form_state['values']['show_in_links']; + $this->configuration['show_as_field'] = $form_state['values']['show_as_field']; $this->configuration['show_on_form'] = $form_state['values']['show_on_form']; $this->configuration['show_contextual_link'] = $form_state['values']['show_contextual_link']; } From 3868837282f892eee49f588f37fd351f1a3b14a0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 11 Mar 2014 23:32:34 -0500 Subject: [PATCH 370/629] New link render chain using link type plugins. --- flag.module | 33 +++---- flag.routing.yml | 11 +++ lib/Drupal/flag/ActionLinkTypeBase.php | 49 +++++++++- .../flag/ActionLinkTypePluginInterface.php | 12 ++- .../flag/Controller/ReloadLinkController.php | 26 ++++++ lib/Drupal/flag/Entity/Flag.php | 12 +-- lib/Drupal/flag/FlagInterface.php | 4 + lib/Drupal/flag/FlagService.php | 16 +++- lib/Drupal/flag/Form/FlagAddPageForm.php | 2 + lib/Drupal/flag/Form/FlaggingConfirmForm.php | 65 ++++++++++++++ .../flag/Plugin/ActionLink/ConfirmForm.php | 90 +++++++++++++++++++ lib/Drupal/flag/Plugin/ActionLink/Reload.php | 4 +- 12 files changed, 288 insertions(+), 36 deletions(-) create mode 100644 lib/Drupal/flag/Controller/ReloadLinkController.php create mode 100644 lib/Drupal/flag/Form/FlaggingConfirmForm.php create mode 100644 lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php diff --git a/flag.module b/flag.module index 84844e7..0f4492c 100644 --- a/flag.module +++ b/flag.module @@ -12,6 +12,7 @@ define('FLAG_ADMIN_PATH_START', 3); use Drupal\flag\Handlers\AbstractFlag; use Drupal\flag\Flag; +use Drupal\node\NodeInterface; // @todo: Implement flagging_view(). Not extremely useful. I already have it. @@ -435,7 +436,7 @@ function flag_permission() { */ function flag_form_user_admin_permissions_alter(&$form, &$form_state, $form_id) { if (!module_exists('session_api')) { - $flags = flag_get_flags(); + $flags = \Drupal::service('flag')->getFlags(); // Disable flag and unflag permission checkboxes for anonymous users. foreach ($flags as $flag_name => $flag) { $form['checkboxes'][DRUPAL_ANONYMOUS_RID]["flag $flag_name"]['#disabled'] = TRUE; @@ -502,7 +503,7 @@ function flag_field_extra_fields() { */ function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { global $user; - $flags = flag_get_flags('node', $form['#node_type']->type, $user); + $flags = \Drupal::service('flag')->getFlags('node', $form['#node_type']->type, $user); foreach ($flags as $flag) { if ($flag->show_on_form) { // To be able to process node tokens in flag labels, we create a fake @@ -558,7 +559,7 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la } // Get all possible flags for this entity type. - $flags = flag_get_flags($entity_type); + $flags = \Drupal::service('flag')->getFlags($entity_type); // Filter out flags which need to be included on the node form. $flags_in_form = 0; @@ -753,7 +754,7 @@ function flag_contextual_links_view_alter(&$element, $items) { * * Note this is broken for taxonomy terms for version of Drupal core < 7.17. */ -function flag_entity_view($entity, $type, $view_mode, $langcode) { +function flag_entity_view($entity, $display, $view_mode, $langcode) { //@todo Check $type->getComponent('flag_whateverHookFieldExtraFieldsIS'). // if not NULL, display it. @@ -764,27 +765,15 @@ function flag_entity_view($entity, $type, $view_mode, $langcode) { $entity->bundle()); foreach ($flags as $flag) { + $linkTypePlugin = $flag->getLinkTypePlugin(); + $action = 'flag'; - if($flag->isFlagged()) { - $action_link_url = "/unflag"; - } - else { - $action_link_url = "/flag"; + if ($flag->isFlagged($entity)) { + $action = 'unflag'; } - $action_link_url .= "/" . $flag->id . "/" . $entity->id(); - - $entity->content['flag_' . $flag->id] = array( - '#markup' => '
' . l($flag->flag_short, $action_link_url) . '
', - '#weight' => 10, - ); -/* - $links = array( - '#prefix' => '
', - '#markup' => l($flag->flag_short, $action_link_url), - '#suffix' => '
', - ); -*/ + $link = $linkTypePlugin->renderLink($action, $flag, $entity); + $entity->content['flag_' . $flag->id] = $link; } /** diff --git a/flag.routing.yml b/flag.routing.yml index bc999cf..c2e6011 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -53,3 +53,14 @@ flag_export: _title: 'Export Flags' requirements: _permission: 'use flag import' + +flag_link: + path: '/flag/{action}/{flag}/{entity}' + defaults: + _controller: '\Drupal\flag\Controller\ReloadLinkController::flag' + +flag_confirm_form: + path: '/flag/confirm/{action}/{flag}/{entity}' + defaults: + _form: '\Drupal\flag\Form\FlaggingConfirmForm' + _title: 'Flag Content' diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/lib/Drupal/flag/ActionLinkTypeBase.php index e9ff196..7283cbd 100644 --- a/lib/Drupal/flag/ActionLinkTypeBase.php +++ b/lib/Drupal/flag/ActionLinkTypeBase.php @@ -8,8 +8,13 @@ namespace Drupal\flag; +use Drupal\Core\URL; +use Drupal\Core\Entity\EntityInterface; +use \Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Component\Plugin\PluginBase; +use Drupal\flag\FlagInterface; use Drupal\flag\ActionLinkTypePluginInterface; +use Drupal\flag\FlagService; /** * Class ActionLinkTypeBase @@ -28,11 +33,51 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi $this->setConfiguration($configuration); } + // @todo Add display, langcode, and view mode to buildLink()? + public function link(FlagInterface $flag, EntityInterface $entity, + EntityViewDisplayInterface $diplay, $view_mode, $langcode) { + + if($flag->isFlagged()) { + $action_link_url = "/unflag"; + } + else { + $action_link_url = "/flag"; + } + + $action_link_url .= "/" . $flag->id . "/" . $entity->id(); + + return l($flag->flag_short, $action_link_url); + } + + /** + * @inheritDoc + */ + abstract public function routeName(); + /** * @return string */ - public function buildLink() { - return ""; + public function buildLink($action, FlagInterface $flag, EntityInterface $entity) { + $options = array( + 'action' => $action, + 'flag' => $flag->id(), + 'entity' => $entity->id(), + ); + + return new URL($this->routeName(), $options); + } + + public function renderLink($action, FlagInterface $flag, EntityInterface $entity) { + $url = $this->buildLink($action, $flag, $entity); + + $url->setOption('destination', \Drupal::request()->attributes->get('_system_path')); + $url->setOption('alt', $flag->flag_long); + + $render = $url->toRenderArray(); + $render['#type'] = 'link'; + $render['#title'] = $flag->flag_short; + + return $render; } /** diff --git a/lib/Drupal/flag/ActionLinkTypePluginInterface.php b/lib/Drupal/flag/ActionLinkTypePluginInterface.php index ae95739..498b70d 100644 --- a/lib/Drupal/flag/ActionLinkTypePluginInterface.php +++ b/lib/Drupal/flag/ActionLinkTypePluginInterface.php @@ -8,6 +8,8 @@ namespace Drupal\flag; +use Drupal\Core\Entity\EntityInterface; +use Drupal\flag\FlagInterface; use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Component\Plugin\ConfigurablePluginInterface; @@ -17,6 +19,14 @@ */ interface ActionLinkTypePluginInterface extends PluginFormInterface, ConfigurablePluginInterface { - public function buildLink(); + public function buildLink($action, FlagInterface $flag, EntityInterface $entity); + + public function renderLink($action, FlagInterface $flag, EntityInterface $entity); + + /** + * @return string + * A string containing the route name. + */ + public function routeName(); } \ No newline at end of file diff --git a/lib/Drupal/flag/Controller/ReloadLinkController.php b/lib/Drupal/flag/Controller/ReloadLinkController.php new file mode 100644 index 0000000..66972a8 --- /dev/null +++ b/lib/Drupal/flag/Controller/ReloadLinkController.php @@ -0,0 +1,26 @@ +flag($flag, $entity); + } + else if ($action == 'unflag') { + \Drupal::service('flag')->unflag($flag, $entity); + } + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index d8112ad..e857c1c 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -10,6 +10,7 @@ use Drupal\Component\Plugin\DefaultSinglePluginBag; use Drupal\Compontent\Plugin\ConfigurablePluginInterface; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageControllerInterface; @@ -202,16 +203,17 @@ public function disable() { $this->enabled = FALSE; } - public function isFlagged(AccountInterface $account = NULL) { + public function isFlagged(EntityInterface $entity, AccountInterface $account = NULL) { if($account == NULL) { global $user; $account = $user; } - $query = \Drupal::entityQuery('flagging'); - $query->condition('uid', $account->id()); - - $result = $query->execute(); + $result = \Drupal::entityQuery('flagging') + ->condition('uid', $account->id()) + ->condition('fid', $this->id()) + ->condition('entity_id', $entity->id()) + ->execute(); if (isset($result['node'])) { $flagging_ids = array_keys($result['flagging']); diff --git a/lib/Drupal/flag/FlagInterface.php b/lib/Drupal/flag/FlagInterface.php index a25b3ea..43fcdad 100644 --- a/lib/Drupal/flag/FlagInterface.php +++ b/lib/Drupal/flag/FlagInterface.php @@ -9,6 +9,8 @@ namespace Drupal\flag; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Session\AccountInterface; interface FlagInterface extends ConfigEntityInterface { @@ -18,6 +20,8 @@ public function enable(); public function disable(); + public function isFlagged(EntityInterface $entity, AccountInterface $account = NULL); + public function getPermissions(); public function isGlobal(); diff --git a/lib/Drupal/flag/FlagService.php b/lib/Drupal/flag/FlagService.php index 256fd46..7ad2d5b 100644 --- a/lib/Drupal/flag/FlagService.php +++ b/lib/Drupal/flag/FlagService.php @@ -25,10 +25,6 @@ public function __construct(ModuleHandlerInterface $module_handler) { $this->moduleHandler = $module_handler; } - public function flag($action, $flag_name, $entity_id, $account = NULL, $permissions_check = FALSE) { - - } - /** * Get a flag type definition. * @@ -95,4 +91,16 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ return $filtered_flags; } + public function getFlaggings(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { + + } + + public function flag(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { + + } + + public function unflag(FlaggingInterface $flagging) { + + } + } \ No newline at end of file diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index ed37b98..4a18772 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -59,12 +59,14 @@ public function buildForm(array $form, array &$form_state) { '#type' => 'select', '#title' => t('Flag'), '#options' => \Drupal::service('plugin.manager.flag.flagtype')->getAllFlagTypes(), + '#default_value' => 'flagtype_node', ); $form['flag_type_info']['flag_link_type'] = array( '#type' => 'select', '#title' => t('using'), '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), + '#default_value' => 'reload', ); $types = array(); diff --git a/lib/Drupal/flag/Form/FlaggingConfirmForm.php b/lib/Drupal/flag/Form/FlaggingConfirmForm.php new file mode 100644 index 0000000..11e8d59 --- /dev/null +++ b/lib/Drupal/flag/Form/FlaggingConfirmForm.php @@ -0,0 +1,65 @@ +action = $action; + $this->flag = $flag; + $this->entity = $entity; + } + + public function getFormID() { + return 'flag_flagging_confirm_form'; + } + + public function getQuestion() { + $linkType = $this->flag->getLinkTypePlugin(); + + if ($action == 'unflag') { + return $linkType->getUnflagQuestion(); + } + else { + return $linkType->getFlagQuestion(); + } + + } + + public function getCancelRoute() { + return $this->entity->urlInfo(); + } + + public function getDescription() { + return $this->t(''); + } + + public function getConfirmText() { + return $this->t('Flag'); + } + + public function submitForm(array &$form, array &$form_state) { + + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php b/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php new file mode 100644 index 0000000..c2ff2e9 --- /dev/null +++ b/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php @@ -0,0 +1,90 @@ + '', + 'unflag_confirmation' => '', + ); + + return $options; + } + + public function buildConfigurationForm(array $form, array &$form_state) { + $form = parent::buildConfigurationForm($form, $form_state); + + + $form['display']['link_options_confirm'] = array( + '#type' => 'fieldset', + '#title' => t('Options for the "Confirmation form" link type'), + // Any "link type" provider module must put its settings fields inside + // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is + // the machine-name of the link type. This is necessary for the + // radiobutton's JavaScript dependency feature to work. + '#id' => 'link-options-confirm', + '#weight' => 21, + ); + + $form['display']['link_options_confirm']['flag_confirmation'] = array( + '#type' => 'textfield', + '#title' => t('Flag confirmation message'), + '#default_value' => $this->configuration['flag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ); + + $form['display']['link_options_confirm']['unflag_confirmation'] = array( + '#type' => 'textfield', + '#title' => t('Unflag confirmation message'), + '#default_value' => $this->configuration['unflag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ); + + return $form; + } + + public function submitConfigurationForm(array &$form, array &$form_state) { + parent::submitConfigurationForm($form, $form_state); + $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; + $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; + } + + public function getFlagQuestion() { + return $this->configuration['flag_confirmation']; + } + + public function getUnflagQuestion() { + return $this->configuration['unflag_confirmation']; + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/ActionLink/Reload.php b/lib/Drupal/flag/Plugin/ActionLink/Reload.php index 1ab3889..0075cad 100644 --- a/lib/Drupal/flag/Plugin/ActionLink/Reload.php +++ b/lib/Drupal/flag/Plugin/ActionLink/Reload.php @@ -24,8 +24,8 @@ class Reload extends ActionLinkTypeBase { /** * @return string */ - public function buildLink() { - return "/flag/"; + public function routeName() { + return 'flag_link'; } } \ No newline at end of file From b05a159b00cd24fbb1d522b4398406e81fd25c1f Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 25 Mar 2014 22:58:41 -0500 Subject: [PATCH 371/629] Multiple updates due to changes in core. --- flag.local_actions.yml | 2 +- flag.module | 14 +++++++------- flag.routing.yml | 2 +- lib/Drupal/flag/ActionLinkPluginManager.php | 6 +++--- lib/Drupal/flag/ActionLinkTypeBase.php | 16 ---------------- .../flag/Controller/FlagListController.php | 4 ++-- lib/Drupal/flag/Entity/Flag.php | 17 +++++++---------- lib/Drupal/flag/Entity/Flagging.php | 3 ++- lib/Drupal/flag/FlagTypePluginManager.php | 4 ++-- lib/Drupal/flag/Form/FlagAddForm.php | 4 ++++ .../flag/Plugin/Derivative/EntityFlagType.php | 4 ++-- lib/Drupal/flag/Plugin/Flag/NodeFlagType.php | 1 + 12 files changed, 32 insertions(+), 45 deletions(-) diff --git a/flag.local_actions.yml b/flag.local_actions.yml index b9b57dc..9b9f593 100644 --- a/flag.local_actions.yml +++ b/flag.local_actions.yml @@ -2,4 +2,4 @@ flag_add_page_action: route_name: flag_add_page title: 'Add New Flag' appears_on: - - flag.flag_list \ No newline at end of file + - flag_list \ No newline at end of file diff --git a/flag.module b/flag.module index 0f4492c..92bb34d 100644 --- a/flag.module +++ b/flag.module @@ -159,9 +159,9 @@ function flag_menu() { function flag_menu_link_defaults() { $items['flag.admin.structure.flag'] = array( 'link_title' => 'Flags', - 'parent' => 'system.admin.structure', + 'parent' => 'system.admin_structure', 'description' => 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).', - 'route_name' => 'flag.flag_list', + 'route_name' => 'flag_list', ); return $items; @@ -341,14 +341,14 @@ function flag_help($path, $arg) { function flag_fetch_definition($entity_type = NULL) { $definitions = &drupal_static(__FUNCTION__); if (!isset($definitions)) { - if ($cache = cache()->get('flag_type_info')) { + if ($cache = \Drupal::cache()->get('flag_type_info')) { $definitions = $cache->data; } else { $definitions = module_invoke_all('flag_type_info'); drupal_alter('flag_type_info', $definitions); - cache()->set('flag_type_info', $definitions); + \Drupal::cache()->set('flag_type_info', $definitions); } } @@ -2101,10 +2101,10 @@ function flag_get_link_types() { $link_types = &drupal_static(__FUNCTION__); if (!isset($link_types)) { - if ($cache = cache()->get('flag_link_type_info')) { + if ($cache = \Drupal::cache()->get('flag_link_type_info')) { $link_types = $cache->data; } - // In some rare edge cases cache()->get() can return an empty result. If it + // In some rare edge cases \Drupal::cache()->get() can return an empty result. If it // does, we make sure to fetch the link types again. if (empty($link_types)) { $link_types = array(); @@ -2125,7 +2125,7 @@ function flag_get_link_types() { } drupal_alter('flag_link_type_info', $link_types); - cache()->set('flag_link_type_info', $link_types); + \Drupal::cache()->set('flag_link_type_info', $link_types); } } diff --git a/flag.routing.yml b/flag.routing.yml index c2e6011..5247a8b 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -6,7 +6,7 @@ flag_add_page: requirements: _permission: 'administer flags' -flag.flag_list: +flag_list: path: '/admin/structure/flags' defaults: _entity_list: 'flag_flag' diff --git a/lib/Drupal/flag/ActionLinkPluginManager.php b/lib/Drupal/flag/ActionLinkPluginManager.php index 1841988..89ad00d 100644 --- a/lib/Drupal/flag/ActionLinkPluginManager.php +++ b/lib/Drupal/flag/ActionLinkPluginManager.php @@ -21,9 +21,9 @@ class ActionLinkPluginManager extends DefaultPluginManager { * {@inheritdoc} */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/ActionLink', $namespaces, 'Drupal\flag\Annotation\ActionLinkType'); - $this->alterInfo($module_handler, 'flag_link_type_info'); - $this->setCacheBackend($cache_backend, $language_manager, 'flag_link_type_info'); + parent::__construct('Plugin/ActionLink', $namespaces, $module_handler, 'Drupal\flag\Annotation\ActionLinkType'); + $this->alterInfo('flag_link_type_info'); + $this->setCacheBackend($cache_backend, $language_manager, 'flag_link_type_plugins'); } public function getAllLinkTypes() { diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/lib/Drupal/flag/ActionLinkTypeBase.php index 7283cbd..9eec7ae 100644 --- a/lib/Drupal/flag/ActionLinkTypeBase.php +++ b/lib/Drupal/flag/ActionLinkTypeBase.php @@ -33,22 +33,6 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi $this->setConfiguration($configuration); } - // @todo Add display, langcode, and view mode to buildLink()? - public function link(FlagInterface $flag, EntityInterface $entity, - EntityViewDisplayInterface $diplay, $view_mode, $langcode) { - - if($flag->isFlagged()) { - $action_link_url = "/unflag"; - } - else { - $action_link_url = "/flag"; - } - - $action_link_url .= "/" . $flag->id . "/" . $entity->id(); - - return l($flag->flag_short, $action_link_url); - } - /** * @inheritDoc */ diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/lib/Drupal/flag/Controller/FlagListController.php index d4fe8dc..44aaede 100644 --- a/lib/Drupal/flag/Controller/FlagListController.php +++ b/lib/Drupal/flag/Controller/FlagListController.php @@ -8,11 +8,11 @@ namespace Drupal\flag\Controller; -use Drupal\Core\Config\Entity\ConfigEntityListController; +use Drupal\Core\Config\Entity\ConfigEntityListBuilder; use Drupal\Core\Entity\EntityInterface; use Drupal\flag\FlagInterface; -class FlagListController extends ConfigEntityListController { +class FlagListController extends ConfigEntityListBuilder { /** * Overrides Drupal\Core\Entity\EntityListController::buildHeader(). diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index e857c1c..8b2ae1a 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -8,7 +8,7 @@ namespace Drupal\flag\Entity; -use Drupal\Component\Plugin\DefaultSinglePluginBag; +use Drupal\Core\Plugin\DefaultSinglePluginBag; use Drupal\Compontent\Plugin\ConfigurablePluginInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; @@ -22,14 +22,12 @@ * Class Flag * @package Drupal\flag\Entity * - * @EntityType( + * @ConfigEntityType( * id = "flag_flag", * label = @Translation("Flag"), - * module = "flag", * admin_permission = "administer flags", * controllers = { - * "storage" = "Drupal\Core\Config\Entity\ConfigStorageController", - * "list" = "Drupal\flag\Controller\FlagListController", + * "list_builder" = "Drupal\flag\Controller\FlagListController", * "form" = { * "add" = "Drupal\flag\Form\FlagAddForm", * "edit" = "Drupal\flag\Form\FlagEditForm", @@ -37,14 +35,13 @@ * } * }, * bundle_of = "flagging", - * config_prefix = "flag.flag", * entity_keys = { * "id" = "id", * "label" = "label", - * "uuid" = "uuid" * }, * links = { - * "edit-form" = "flag_edit" + * "edit-form" = "flag_edit", + * "delete-form" = "flag_delete" * } * ) * @@ -189,10 +186,10 @@ public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), - array($this->flag_type), $this->flagTypeConfig); + $this->flag_type, $this->flagTypeConfig); $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), - array($this->link_type), $this->linkTypeConfig); + $this->link_type, $this->linkTypeConfig); } public function enable() { diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index a30b8b3..c1e133b 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -8,6 +8,7 @@ namespace Drupal\flag\Entity; +use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityStorageControllerInterface; use Drupal\Core\Language\Language; @@ -49,7 +50,7 @@ public function getFlag() { return $this->bundle; } - public static function baseFieldDefinitions($entity_type) { + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['id'] = FieldDefinition::create('integer') ->setLabel(t('Node ID')) ->setDescription(t('The flagging ID.')) diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php index ed5c650..2f5cf8d 100644 --- a/lib/Drupal/flag/FlagTypePluginManager.php +++ b/lib/Drupal/flag/FlagTypePluginManager.php @@ -29,9 +29,9 @@ class FlagTypePluginManager extends DefaultPluginManager { * The module handler to invoke the alter hook with. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/Flag', $namespaces, 'Drupal\flag\Annotation\FlagType'); + parent::__construct('Plugin/Flag', $namespaces, $module_handler, 'Drupal\flag\Annotation\FlagType'); -// $this->alterInfo($module_handler, 'flag_type_info'); + $this->alterInfo('flag_type_info'); $this->setCacheBackend($cache_backend, $language_manager, 'flag'); } diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/lib/Drupal/flag/Form/FlagAddForm.php index fccc532..78de632 100644 --- a/lib/Drupal/flag/Form/FlagAddForm.php +++ b/lib/Drupal/flag/Form/FlagAddForm.php @@ -10,6 +10,10 @@ use Drupal\flag\Form\FlagFormBase; +/** + * Class FlagAddForm + * @package Drupal\flag\Form + */ class FlagAddForm extends FlagFormBase { protected function getRoleDefault($selction) { diff --git a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php index d1d196b..9fb25df 100644 --- a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php @@ -17,9 +17,9 @@ public function __construct($base_plugin_id, EntityStorageControllerInterface $s } */ - public function getDerivativeDefinitions(array $base_plugin_def) { + public function getDerivativeDefinitions($base_plugin_def) { $derivatives = array(); - foreach (entity_get_info() as $entity_id => $entity_info) { + foreach (\Drupal::entityManager()->getDefinitions() as $entity_id => $entity_info) { $derivatives[$entity_id] = array( 'title' => $entity_id, 'entity_type' => $entity_id, diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php index 3bd0ddd..2fbd1ac 100644 --- a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php @@ -29,6 +29,7 @@ public function defaultConfiguration() { // Use own display settings in the meanwhile. $options += array( 'i18n' => 0, + 'access_author' => '', ); return $options; } From 795977018c06693fdcc19317f66da58cb2bf6d21 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 31 Mar 2014 23:41:14 -0500 Subject: [PATCH 372/629] Updates due to changes in core. --- flag.module | 2 +- lib/Drupal/flag/Entity/Flag.php | 12 ++++++++---- lib/Drupal/flag/Form/FlagDeleteForm.php | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/flag.module b/flag.module index 92bb34d..a7e1bc5 100644 --- a/flag.module +++ b/flag.module @@ -877,7 +877,7 @@ function flag_entity_delete($entity, $type) { return; } - _flag_entity_delete($entity->entityType(), $entity->id()); + _flag_entity_delete($entity->getEntityType(), $entity->id()); } /** diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 8b2ae1a..1161e04 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -13,7 +13,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Entity\EntityStorageControllerInterface; +use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\Annotation\EntityType; use Drupal\Core\Annotation\Translation; use Drupal\flag\FlagInterface; @@ -296,10 +296,14 @@ public function setGlobal($isGlobal = TRUE) { } } + public function getEntityType() { + return $this->entity_type; + } + /** * @param EntityStorageControllerInterface $storage_controller */ - public function preSave(EntityStorageControllerInterface $storage_controller) { + public function preSave(EntityStorageInterface $storage_controller) { parent::preSave($storage_controller); // Save the Flag Type configuration. @@ -311,8 +315,8 @@ public function preSave(EntityStorageControllerInterface $storage_controller) { $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); } - public function getExportProperties() { - $properties = parent::getExportProperties(); + public function toArray() { + $properties = parent::toArray(); $names = array( 'roles', 'flag_type', diff --git a/lib/Drupal/flag/Form/FlagDeleteForm.php b/lib/Drupal/flag/Form/FlagDeleteForm.php index 3d755f6..02cb518 100644 --- a/lib/Drupal/flag/Form/FlagDeleteForm.php +++ b/lib/Drupal/flag/Form/FlagDeleteForm.php @@ -24,7 +24,7 @@ public function getConfirmText() { public function getCancelRoute() { return array( - 'route_name' => 'flag.flag_list', + 'route_name' => 'flag_list', ); } @@ -34,7 +34,7 @@ public function submit(array $form, array &$form_state) { '%label' => $this->entity->label(), ))); - $form_state['redirect_route']['route_name'] = 'flag.flag_list'; + $form_state['redirect_route']['route_name'] = 'flag_list'; } } \ No newline at end of file From 7fa02ebe908602d75ab000b859783dd03444e3d5 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 31 Mar 2014 23:50:27 -0500 Subject: [PATCH 373/629] Changed Flag::getEntityType() to getFlaggableEntityType(), fixing mixtakenly overrode Entity::getEntityType(). --- flag.module | 2 +- lib/Drupal/flag/Entity/Flag.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index a7e1bc5..da42bd3 100644 --- a/flag.module +++ b/flag.module @@ -877,7 +877,7 @@ function flag_entity_delete($entity, $type) { return; } - _flag_entity_delete($entity->getEntityType(), $entity->id()); + _flag_entity_delete($entity->getFlaggableEntityType(), $entity->id()); } /** diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 1161e04..af10a85 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -296,7 +296,7 @@ public function setGlobal($isGlobal = TRUE) { } } - public function getEntityType() { + public function getFlaggableEntityType() { return $this->entity_type; } From 5c15eeebdf51a0f64b6b0a7ecd341cadbbad7fe1 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 1 Apr 2014 23:08:37 -0500 Subject: [PATCH 374/629] Fixed services entries due to https://drupal.org/node/2221065, added flag.menu_links.yml due to https://drupal.org/node/2228089 --- flag.menu_links.yml | 5 +++++ flag.module | 11 ----------- flag.services.yml | 4 ++-- lib/Drupal/flag/FlagTypePluginManager.php | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) create mode 100644 flag.menu_links.yml diff --git a/flag.menu_links.yml b/flag.menu_links.yml new file mode 100644 index 0000000..4e8a2c7 --- /dev/null +++ b/flag.menu_links.yml @@ -0,0 +1,5 @@ +flag.admin.structure.flag: + title: 'Flags' + description: 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).' + parent: system.admin_structure + route_name: flag_list \ No newline at end of file diff --git a/flag.module b/flag.module index da42bd3..67d435d 100644 --- a/flag.module +++ b/flag.module @@ -156,17 +156,6 @@ function flag_menu() { return $items; } -function flag_menu_link_defaults() { - $items['flag.admin.structure.flag'] = array( - 'link_title' => 'Flags', - 'parent' => 'system.admin_structure', - 'description' => 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).', - 'route_name' => 'flag_list', - ); - - return $items; -} - /** * Implements hook_admin_menu_map(). */ diff --git a/flag.services.yml b/flag.services.yml index 25b20ef..d637bef 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -1,10 +1,10 @@ services: plugin.manager.flag.flagtype: class: Drupal\flag\FlagTypePluginManager - arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] + arguments: ['@container.namespaces', '@cache.default', '@language_manager', '@module_handler'] plugin.manager.flag.linktype: class: Drupal\flag\ActionLinkPluginManager - arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] + arguments: ['@container.namespaces', '@cache.default', '@language_manager', '@module_handler'] flag: class: Drupal\flag\FlagService arguments: ['@module_handler'] diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/lib/Drupal/flag/FlagTypePluginManager.php index 2f5cf8d..35ccadf 100644 --- a/lib/Drupal/flag/FlagTypePluginManager.php +++ b/lib/Drupal/flag/FlagTypePluginManager.php @@ -31,7 +31,7 @@ class FlagTypePluginManager extends DefaultPluginManager { public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { parent::__construct('Plugin/Flag', $namespaces, $module_handler, 'Drupal\flag\Annotation\FlagType'); - $this->alterInfo('flag_type_info'); + //$this->alterInfo('flag_type_info'); $this->setCacheBackend($cache_backend, $language_manager, 'flag'); } From 990c3bc64b4f150ef99a9367c9e01c57b59ea418 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 2 Apr 2014 22:37:19 -0500 Subject: [PATCH 375/629] Fixed hook_schema(), updated Flagging annontation. --- flag.install | 455 ++-------------------------- lib/Drupal/flag/Entity/Flagging.php | 4 +- 2 files changed, 21 insertions(+), 438 deletions(-) diff --git a/flag.install b/flag.install index d7d20ba..36d3e86 100644 --- a/flag.install +++ b/flag.install @@ -10,7 +10,7 @@ */ function flag_schema() { $schema = array(); - +/* $schema['flag'] = array( 'description' => 'All available flags in the system.', 'fields' => array( @@ -60,7 +60,7 @@ function flag_schema() { 'name' => array('name'), ), ); - +*/ $schema['flagging'] = array( 'description' => 'Objects that have been flagged.', 'fields' => array( @@ -70,6 +70,12 @@ function flag_schema() { 'unsigned' => TRUE, 'not null' => TRUE, ), + 'uuid' => array( + 'description' => 'Unique Key: Universally unique identifier for this entity.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ), 'fid' => array( 'description' => 'The unique flag ID this object has been flagged with, from {flag}.', 'type' => 'int', @@ -113,7 +119,14 @@ function flag_schema() { 'not null' => TRUE, 'default' => 0, 'disp-size' => 11, - ) + ), + 'type' => array( + 'description' => 'The type of this node.', + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), ), 'primary key' => array('id'), 'unique keys' => array( @@ -125,7 +138,7 @@ function flag_schema() { 'entity_id_fid' => array('entity_id', 'fid'), ), ); - +/* $schema['flag_types'] = array( 'description' => 'The entity bundles that are affected by a flag.', 'fields' => array( @@ -200,7 +213,7 @@ function flag_schema() { 'fid_last_updated' => array('fid', 'last_updated'), ), ); - +*/ return $schema; } @@ -208,6 +221,7 @@ function flag_schema() { * Implements hook_uninstall(). */ function flag_uninstall() { + /* $result = db_select('variable', 'v') ->fields('v', array('name')) ->condition('name', 'flag_%', 'LIKE') @@ -215,7 +229,7 @@ function flag_uninstall() { foreach ($result as $row) { variable_del($row->name); } - + */ drupal_set_message(t('Flag has been uninstalled.')); } @@ -255,432 +269,3 @@ function flag_requirements($phase) { } return $requirements; } - -function flag_update_last_removed() { - return 6004; -} - -/** - * Convert role access to have separate "flag" and "unflag" permissions. - */ -function flag_update_6200() { - if (db_field_exists('flags', 'roles')) { - $result = db_select('flags', 'f') - ->fields('f') - ->execute(); - foreach ($result as $flag) { - $roles = array_filter(explode(',', $flag->roles)); - $options = unserialize($flag->options); - $options['roles'] = array( - 'flag' => $roles, - 'unflag' => $roles, - ); - db_update('flags') - ->fields(array( - 'options' => serialize($options), - )) - ->condition('fid', $flag->fid) - ->execute(); - } - db_drop_field('flags', 'roles'); - } -} - -/** - * Refine the indexes. - * - * The content type inclusion actually slowed down on unique key. And a count - * index would be helpful for sorting by counts. - */ -function flag_update_6201() { - // Remove "content type" from one key, see http://drupal.org/node/612602. - db_drop_unique_key('flag_content', 'fid_content_type_content_id_uid'); - db_add_unique_key('flag_content', 'fid_content_id_uid', array('fid', 'content_id', 'uid')); - - // Add a count index, see http://drupal.org/node/489610. - db_add_index('flag_counts', 'count', array('count')); -} - -/** - * Add the sid column and unique index on the flag_content table. - */ -function flag_update_6202() { - // Drop the keys affected by the addition of the SID column. - db_drop_unique_key('flag_content', 'fid_content_id_uid'); - db_drop_index('flag_content', 'content_type_uid'); - - // Add the column. - db_add_field('flag_content', 'sid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)); - - // Re-add the removed keys. - db_add_unique_key('flag_content', 'fid_content_id_uid_sid', array('fid', 'content_id', 'uid', 'sid')); - db_add_index('flag_content', 'content_type_uid_sid', array('content_type', 'uid', 'sid')); -} - -/** - * Remove count = 0 rows from the count tables. - */ -function flag_update_6203() { - db_delete('flag_counts') - ->condition('count', 0) - ->execute(); -} - -/** - * Remove "content type" from the flag_counts primary key. - */ -function flag_update_6204() { - db_drop_primary_key('flag_counts'); - db_add_primary_key('flag_counts', array('fid', 'content_id')); -} - -/** - * Provide a better index on the flag_content table including 'uid' and 'sid'. - */ -function flag_update_6205() { - // This update has been removed and corrected in flag_update_6206. - // See http://drupal.org/node/1105490. -} - -/** - * Correction to flag_update_6205(). Convert unique key to an index. - */ -function flag_update_6206() { - // Remove the old index that did not include UID or SID. - if (db_index_exists('flag_content', 'content_type_content_id')) { - db_drop_index('flag_content', 'content_type_content_id'); - } - - // Remove the erroneous unique key that was added in flag_update_6205(). - if (db_index_exists('flag_content', 'content_type_content_id_uid_sid')) { - db_drop_unique_key('flag_content', 'content_type_content_id_uid_sid'); - } - - db_add_index('flag_content', 'content_type_content_id_uid_sid', array('content_type', 'content_id', 'uid', 'sid')); -} - -/** - * Adds column last_updated to flag_counts table. - */ -function flag_update_6207() { - db_add_field('flag_counts', 'last_updated', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'disp-size' => 11), array('indexes' => array('last_updated' => array('last_updated')))); -} - -/** - * Convert flag_count indexes to include FID for more efficient indexing. - */ -function flag_update_6208() { - db_drop_index('flag_counts', 'count'); - db_drop_index('flag_counts', 'last_updated'); - - db_add_index('flag_counts', 'fid_count', array('fid', 'count')); - db_add_index('flag_counts', 'fid_last_updated', array('fid', 'last_updated')); -} - -/** - * Clear caches. - */ -function flag_update_7201() { - // Do nothing. Update.php is going to clear caches for us. -} - -/** - * Clean-up flag records for deleted nodes and comments. - */ -function flag_update_7202() { - // These queries can't use db_delete() because that doesn't support a - // subquery: see http://drupal.org/node/1267508. - // Clean-up for nodes. - db_query("DELETE FROM {flag_content} WHERE content_type = 'node' AND NOT EXISTS (SELECT 1 FROM {node} n WHERE content_id = n.nid)"); - db_query("DELETE FROM {flag_counts} WHERE content_type = 'node' AND NOT EXISTS (SELECT 1 FROM {node} n WHERE content_id = n.nid)"); - // Clean-up for comments. Do not use module_exists() because comment module - // could be disabled. - if (db_table_exists('comment')) { - db_query("DELETE FROM {flag_content} WHERE content_type = 'comment' AND NOT EXISTS (SELECT 1 FROM {comment} c WHERE content_id = c.cid)"); - db_query("DELETE FROM {flag_counts} WHERE content_type = 'comment' AND NOT EXISTS (SELECT 1 FROM {comment} c WHERE content_id = c.cid)"); - } -} - -/** - * Add an index to help with view's flag_handler_relationship when not required. - */ -function flag_update_7203() { - // Skip if this index was also added by the 6.x-2.x branch. - if (!db_index_exists('flag_content', 'content_id_fid')) { - db_add_index('flag_content', 'content_id_fid', array('content_id', 'fid')); - } -} - -/** - * Rebuild the class registry due to classes moving files. - */ -function flag_update_7300() { - registry_rebuild(); -} - -/** - * Rename {flag_content} table to {flagging} and {flags} table to {flag}. - */ -function flag_update_7301() { - db_rename_table('flag_content', 'flagging'); - db_rename_table('flags', 'flag'); - // A second cache clear appears to be required here... - cache_clear_all(); - // ...which in fact isn't enough, as the schema cache appears to need explicit - // clearing to prevent the next updates failing to get the schema for the new - // table names. - drupal_get_schema(NULL, TRUE); -} - -/** - * Rename database columns on the {flag} table. - */ -function flag_update_7302() { - // No keys or indexes are affected. - // Change field 'content_type' to 'entity_type'. - db_change_field('flag', 'content_type', 'entity_type', - // Spec of the field. Identical to our current hook_schema(): we're not - // changing anything except the name. - array( - 'description' => 'The flag type, such as one of "node", "comment", or "user".', - 'type' => 'varchar', - 'length' => '32', - 'not null' => TRUE, - 'default' => '', - ) - // No keys to re-add. - ); -} - -/** - * Rename database columns on the {flagging} table. - */ -function flag_update_7303() { - // Drop affected keys and indexes. - db_drop_unique_key('flagging', 'fid_content_id_uid_sid'); - db_drop_index('flagging', 'content_type_uid_sid'); - db_drop_index('flagging', 'content_type_content_id_uid_sid'); - db_drop_index('flagging', 'content_id_fid'); - - // Change field 'content_type' to 'entity_type'. - db_change_field('flagging', 'content_type', 'entity_type', - // Spec of the field. Identical to our current hook_schema(): we're not - // changing anything except the name. - array( - 'description' => 'The flag type, eg "node", "comment", "user".', - 'type' => 'varchar', - 'length' => '32', - 'not null' => TRUE, - 'default' => '', - ), - // Keys spec. Some are short-lived, as they are about to be dropped again - // and have hybrid names that refer to 'content_id' still. - array( - 'unique keys' => array( - 'fid_content_id_uid_sid' => array('fid', 'content_id', 'uid', 'sid'), - ), - 'indexes' => array( - 'entity_type_uid_sid' => array('entity_type', 'uid', 'sid'), - 'entity_type_content_id_uid_sid' => array('entity_type', 'content_id', 'uid', 'sid'), - 'content_id_fid' => array('content_id', 'fid'), - ), - ) - ); - - // Now we have to drop keys and indexes all over again! - db_drop_unique_key('flagging', 'fid_content_id_uid_sid'); - db_drop_index('flagging', 'entity_type_content_id_uid_sid'); - db_drop_index('flagging', 'content_id_fid'); - - // Change field 'content_id' to 'entity_id'. - db_change_field('flagging', 'content_id', 'entity_id', - // Spec of the field. Identical to our current hook_schema(): we're not - // changing anything except the name. - array( - 'description' => 'The unique ID of the content, such as either the {cid}, {uid}, or {nid}.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - // Keys spec. Identical to current hook_schema(). - array( - 'unique keys' => array( - 'fid_entity_id_uid_sid' => array('fid', 'entity_id', 'uid', 'sid'), - ), - 'indexes' => array( - 'entity_type_entity_id_uid_sid' => array('entity_type', 'entity_id', 'uid', 'sid'), - 'entity_id_fid' => array('entity_id', 'fid'), - ), - ) - ); - - // A serial field must be defined as a key, so make a temporary index on - // 'fcid' so we can safely drop the primary key. - // @see http://drupal.org/node/190027 - db_add_index('flagging', 'temp', array('fcid')); - // Drop the primary key so we can rename the field. - db_drop_primary_key('flagging'); - - // Change field 'fcid' to 'flagging_id'. - db_change_field('flagging', 'fcid', 'flagging_id', - // Spec of the field. Identical to our current hook_schema(): we're not - // changing anything except the name. - array( - 'description' => 'The unique ID for this particular tag.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - // Keys spec. Identical to current hook_schema(). - array( - 'primary key' => array('flagging_id'), - ) - ); - // Drop our temporary index. - db_drop_index('flagging', 'temp'); - - cache_clear_all(); -} - -/** - * Rename database columns on the {flag_counts} table. - */ -function flag_update_7304() { - // Drop keys and indexes using 'content_type'. - db_drop_index('flag_counts', 'fid_content_type'); - db_drop_index('flag_counts', 'content_type_content_id'); - - // Change field 'content_type' to 'entity_type'. - db_change_field('flag_counts', 'content_type', 'entity_type', - // Spec of the field. Identical to our current hook_schema(): we're not - // changing anything except the name. - array( - 'description' => 'The flag type, usually one of "node", "comment", "user".', - 'type' => 'varchar', - 'length' => '32', - 'not null' => TRUE, - 'default' => '', - ), - // Keys spec. Some are short-lived, as they are about to be dropped again. - // Note the hybrid names refer to 'content_id' still. - array( - 'indexes' => array( - 'fid_entity_type' => array('fid', 'entity_type'), - 'entity_type_content_id' => array('entity_type', 'content_id'), - ) - ) - ); - - // Now drop keys and indexes using 'content_id'. - db_drop_primary_key('flag_counts'); - db_drop_index('flag_counts', 'entity_type_content_id'); - - // Change field 'content_id' to 'entity_id'. - db_change_field('flag_counts', 'content_id', 'entity_id', - // Spec of the field. Identical to our current hook_schema(): we're not - // changing anything except the name. - array( - 'description' => 'The unique ID of the content, usually either the {cid}, {uid}, or {nid}.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'disp-width' => '10', - ), - // Keys spec. Identical to current hook_schema() now we're finished. - array( - 'primary key' => array('fid', 'entity_id'), - 'indexes' => array( - 'entity_type_entity_id' => array('entity_type', 'entity_id'), - ), - ) - ); -} - -/** - * Convert flag roles to permissions. - */ -function flag_update_7305() { - // We can't use flag_get_flags() to get all flags to act on, because that - // now looks for user permissions and we want the old roles array to convert. - // Hence we need to get flags directly from the database. - // Flags defined in code are saved in the database by flag_get_flags(), so - // this will get them too, unless the module providing them was *only just* - // installed before update.php was run. This edge case is not covered. - - $result = db_query("SELECT name, options FROM {flag}"); - $flag_data = $result->fetchAllKeyed(); - - // Note we don't call hook_flag_alter() because we don't have a complete flag. - // If your custom module does something to flag roles, it is your - // responsibility to handle upgrading your extra role data. - - foreach ($flag_data as $flag_name => $flag_options) { - $flag_options = unserialize($flag_options); - $flag_roles = $flag_options['roles']; - - foreach ($flag_roles['flag'] as $rid) { - $permission = "flag $flag_name"; - user_role_grant_permissions($rid, array($permission)); - } - foreach ($flag_roles['unflag'] as $rid) { - $permission = "unflag $flag_name"; - user_role_grant_permissions($rid, array($permission)); - } - - // Save the flag options with the roles array removed. - unset($flag_options['roles']); - db_update('flag') - ->fields(array( - 'options' => serialize($flag_options), - )) - ->condition('name', $flag_name) - ->execute(); - } - - // Flags in code will now report as overridden because the roles option is no - // longer output. Notify the user that they should update them. - if (count(module_implements('flag_default_flags'))) { - drupal_set_message(t('Flags which are defined in code with hook_flag_default_flags() or Features need to be re-exported.')); - } - - // Direct the user to read the change notice, which has more details of how - // access to flag objects has been affected. - return t('Flag roles have been converted to user permissions. Permissions have been granted to each flag based on flag roles. You should review the consequences of this in the change record.', array( - '!url' => 'http://drupal.org/node/1724256', - )); -} - -/** - * Convert flag view modes settings. - */ -function flag_update_7306() { - foreach (flag_get_flags() as $flag) { - // Update show_on_teaser property to use new view mode settings. - if (!empty($flag->show_on_teaser)) { - $flag->show_in_links['teaser'] = TRUE; - unset($flag->show_on_teaser); - } - - // Update show_on_page property to use new view mode settings. - if (!empty($flag->show_on_page)) { - $flag->show_in_links['full'] = TRUE; - unset($flag->show_on_page); - } - - // Update show_on_comment and show_on_entity properties to use new view - // mode settings. Since the old logic was to show on all view modes, do that. - if (!empty($flag->show_on_entity) || !empty($flag->show_on_comment)) { - if ($entity_info = entity_get_info($flag->entity_type)) { - foreach ($entity_info['view modes'] as $view_mode => $value) { - $flag->show_in_links[$view_mode] = TRUE; - } - } - - unset($flag->show_on_entity, $flag->show_on_comment); - } - - $flag->save(); - } -} diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index c1e133b..21e984f 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -20,12 +20,10 @@ * Class Flagging * @package Drupal\flag\Entity * - * @EntityType( + * @ContentEntityType( * id = "flagging", * label = @Translation("Flagging"), - * module = "flag", * controllers = { - * "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController", * "access" = "Drupal\flag\FlaggingAccessController", * }, * base_table = "flagging", From 2d44192ca825e5a8c06fb16a7b5820409199227b Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 6 Apr 2014 12:29:52 -0500 Subject: [PATCH 376/629] Working flaggings and flagging access controller. --- flag.install | 11 +++---- flag.routing.yml | 15 +++++++-- lib/Drupal/flag/ActionLinkTypeBase.php | 32 +++++++++++++------ .../flag/Controller/ReloadLinkController.php | 28 ++++++++++++---- lib/Drupal/flag/Entity/Flag.php | 10 +++--- lib/Drupal/flag/Entity/Flagging.php | 24 ++++++++++++-- lib/Drupal/flag/FlagService.php | 14 ++++++-- lib/Drupal/flag/FlaggingAccessController.php | 9 ++++++ lib/Drupal/flag/Plugin/ActionLink/Reload.php | 8 +++-- 9 files changed, 113 insertions(+), 38 deletions(-) diff --git a/flag.install b/flag.install index 36d3e86..364686b 100644 --- a/flag.install +++ b/flag.install @@ -78,18 +78,15 @@ function flag_schema() { ), 'fid' => array( 'description' => 'The unique flag ID this object has been flagged with, from {flag}.', - 'type' => 'int', - 'size' => 'small', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, + 'type' => 'varchar', + 'length' => 32, + 'not null' => FALSE, ), 'entity_type' => array( 'description' => 'The flag type, eg "node", "comment", "user".', 'type' => 'varchar', - 'length' => '128', + 'length' => 128, 'not null' => TRUE, - 'default' => '', ), 'entity_id' => array( 'description' => 'The unique ID of the object, such as either the {cid}, {uid}, or {nid}.', diff --git a/flag.routing.yml b/flag.routing.yml index 5247a8b..7b780dd 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -54,13 +54,22 @@ flag_export: requirements: _permission: 'use flag import' -flag_link: - path: '/flag/{action}/{flag}/{entity}' +flag_link_flag: + path: '/flag/flag/{flag_id}/{entity_id}' defaults: _controller: '\Drupal\flag\Controller\ReloadLinkController::flag' + requirements: + _entity_create_access: flagging + +flag_link_unflag: + path: '/flag/unflag/{flag_id}/{entity_id}' + defaults: + _controller: '\Drupal\flag\Controller\ReloadLinkController::unflag' + requirements: + _entity_access: flagging.delete flag_confirm_form: - path: '/flag/confirm/{action}/{flag}/{entity}' + path: '/flag/confirm/{action}/{flag_id}/{entity_id}' defaults: _form: '\Drupal\flag\Form\FlaggingConfirmForm' _title: 'Flag Content' diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/lib/Drupal/flag/ActionLinkTypeBase.php index 9eec7ae..82ac259 100644 --- a/lib/Drupal/flag/ActionLinkTypeBase.php +++ b/lib/Drupal/flag/ActionLinkTypeBase.php @@ -34,32 +34,44 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi } /** - * @inheritDoc + * Returns a route name given an $action. + * + * @param $action + * A string containing the action name. + * @return string + * A string containing a route name. */ - abstract public function routeName(); + abstract public function routeName($action = NULL); /** * @return string */ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) { - $options = array( - 'action' => $action, - 'flag' => $flag->id(), - 'entity' => $entity->id(), + $parameters = array( + 'flag_id' => $flag->id(), + 'entity_id' => $entity->id(), ); - return new URL($this->routeName(), $options); + return new URL($this->routeName($action), $parameters); } public function renderLink($action, FlagInterface $flag, EntityInterface $entity) { $url = $this->buildLink($action, $flag, $entity); - $url->setOption('destination', \Drupal::request()->attributes->get('_system_path')); - $url->setOption('alt', $flag->flag_long); + $url->setRouteParameter('destination', \Drupal::request()->getRequestUri()); $render = $url->toRenderArray(); $render['#type'] = 'link'; - $render['#title'] = $flag->flag_short; + + //@todo check if flagged, assign flag or unflag text. + if ($action === 'unflag') { + $render['#title'] = $flag->unflag_short; + $render['#alt'] = $flag->unflag_long; + } + else { + $render['#title'] = $flag->flag_short; + $render['#alt'] = $flag->flag_long; + } return $render; } diff --git a/lib/Drupal/flag/Controller/ReloadLinkController.php b/lib/Drupal/flag/Controller/ReloadLinkController.php index 66972a8..4a27840 100644 --- a/lib/Drupal/flag/Controller/ReloadLinkController.php +++ b/lib/Drupal/flag/Controller/ReloadLinkController.php @@ -11,16 +11,30 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\flag\FlagInterface; use Drupal\Core\Entity\EntityInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; class ReloadLinkController extends ControllerBase { - public function flag($action, FlagInterface $flag, EntityInterface $entity) { - if ($action == 'flag') { - \Drupal::service('flag')->flag($flag, $entity); - } - else if ($action == 'unflag') { - \Drupal::service('flag')->unflag($flag, $entity); - } + public function flag($flag_id, $entity_id) { + $flag = entity_load('flag_flag', $flag_id); + $entity = entity_load($flag->getFlaggableEntityType(), $entity_id); + \Drupal::service('flag')->flag($flag, $entity); + + $destination = \Drupal::request()->get('destination', $entity->url()); + + //@todo SECURITY HOLE. Please fix! + return new RedirectResponse($destination); + } + + public function unflag($flag, $entity) { + $flag = entity_load('flag_flag', $flag_id); + $entity = entity_load($flag->getFlaggableEntityType(), $entity_id); + \Drupal::service('flag')->unflag($flag, $entity); + + $destination = \Drupal::request()->get('destination', $entity->url()); + + //@todo SECURITY HOLE. Please fix! + return new RedirectResponse($destination); } } \ No newline at end of file diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index af10a85..2515ae2 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -202,19 +202,21 @@ public function disable() { public function isFlagged(EntityInterface $entity, AccountInterface $account = NULL) { if($account == NULL) { - global $user; - $account = $user; + $account = \Drupal::currentUser(); } $result = \Drupal::entityQuery('flagging') ->condition('uid', $account->id()) ->condition('fid', $this->id()) + ->condition('entity_type', $entity->getEntityTypeId()) ->condition('entity_id', $entity->id()) ->execute(); - if (isset($result['node'])) { - $flagging_ids = array_keys($result['flagging']); + if (!empty($result)) { + return TRUE; } + + return FALSE; } /** diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index 21e984f..7d0fb1e 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -44,13 +44,19 @@ */ class Flagging extends ContentEntityBase implements FlaggingInterface { + protected $entity_id; + + protected $entity_type; + + protected $fid; + public function getFlag() { return $this->bundle; } public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['id'] = FieldDefinition::create('integer') - ->setLabel(t('Node ID')) + ->setLabel(t('Flagging ID')) ->setDescription(t('The flagging ID.')) ->setReadOnly(TRUE); @@ -59,6 +65,19 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The flagging UUID.')) ->setReadOnly(TRUE); + $fields['fid'] = FieldDefinition::create('integer') + ->setLabel(t('Flag ID')) + ->setDescription(t('The Flag ID.')) + ->setReadOnly(TRUE); + + $fields['entity_type'] = FieldDefinition::create('string') + ->setLabel(t('Entity Type')) + ->setDescription(t('The Entity Type.')); + + $fields['entity_id'] = FieldDefinition::create('string') + ->setLabel(t('Entity ID')) + ->setDescription(t('The Entity ID.')); + $fields['type'] = FieldDefinition::create('entity_reference') ->setLabel(t('Type')) ->setDescription(t('The flag type.')) @@ -73,8 +92,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { 'default_value' => 0, )); - // @todo Convert to a "created" field in https://drupal.org/node/2145103. - $fields['created'] = FieldDefinition::create('integer') + $fields['created'] = FieldDefinition::create('created') ->setLabel(t('Created')) ->setDescription(t('The time that the flagging was created.')); diff --git a/lib/Drupal/flag/FlagService.php b/lib/Drupal/flag/FlagService.php index 7ad2d5b..71895ea 100644 --- a/lib/Drupal/flag/FlagService.php +++ b/lib/Drupal/flag/FlagService.php @@ -95,11 +95,21 @@ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, Accou } - public function flag(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { + public function flag($flag, $entity, AccountInterface $account = NULL) { + if (empty($account)) { + $account = \Drupal::currentUser(); + } + entity_create('flagging', array( + 'type' => 'flag_flag', + 'uid' => $account->id(), + 'fid' => $flag->id(), + 'entity_id' => $entity->id(), + 'entity_type' => $entity->getEntityTypeId(), + ))->save(); } - public function unflag(FlaggingInterface $flagging) { + public function unflag($flagging) { } diff --git a/lib/Drupal/flag/FlaggingAccessController.php b/lib/Drupal/flag/FlaggingAccessController.php index ce92935..906b0f8 100644 --- a/lib/Drupal/flag/FlaggingAccessController.php +++ b/lib/Drupal/flag/FlaggingAccessController.php @@ -15,6 +15,10 @@ class FlaggingAccessController extends EntityAccessController { protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) { + if ($account->id() == 1) { + return TRUE; + } + switch ($operation) { case 'view': case 'flag': @@ -31,6 +35,11 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A } protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { + if ($account->id() == 1) { + return TRUE; + } + + //@todo Figure out how to handle the NULL $entity_bundle case. return user_access('flag ' . $entity_bundle, $account); } diff --git a/lib/Drupal/flag/Plugin/ActionLink/Reload.php b/lib/Drupal/flag/Plugin/ActionLink/Reload.php index 0075cad..8683e90 100644 --- a/lib/Drupal/flag/Plugin/ActionLink/Reload.php +++ b/lib/Drupal/flag/Plugin/ActionLink/Reload.php @@ -24,8 +24,12 @@ class Reload extends ActionLinkTypeBase { /** * @return string */ - public function routeName() { - return 'flag_link'; + public function routeName($action = NULL) { + if ($action === 'unflag') { + return 'flag_link_unflag'; + } + + return 'flag_link_flag'; } } \ No newline at end of file From 7dea70fd27401bbc944577588278f7d09d0eb313 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 7 Apr 2014 23:08:33 -0500 Subject: [PATCH 377/629] Refactored FlagService. --- .../flag/Controller/ReloadLinkController.php | 30 ++++++-- lib/Drupal/flag/FlagService.php | 73 ++++++++++++++++++- 2 files changed, 92 insertions(+), 11 deletions(-) diff --git a/lib/Drupal/flag/Controller/ReloadLinkController.php b/lib/Drupal/flag/Controller/ReloadLinkController.php index 4a27840..f28dd56 100644 --- a/lib/Drupal/flag/Controller/ReloadLinkController.php +++ b/lib/Drupal/flag/Controller/ReloadLinkController.php @@ -16,20 +16,36 @@ class ReloadLinkController extends ControllerBase { public function flag($flag_id, $entity_id) { - $flag = entity_load('flag_flag', $flag_id); - $entity = entity_load($flag->getFlaggableEntityType(), $entity_id); - \Drupal::service('flag')->flag($flag, $entity); + // Get the Flag Service. + $flagService = \Drupal::service('flag'); + // Get the Flag and Entity objects. + $flag = $flagService->getFlagById($flag_id); + $entity = $flagService->getFlaggableById($flag, $entity_id); + + // While we could use FlagService::flag() here, we wouldn't have the URL + // to redirect Drupal afterward. So we flag by object instead. + $flagService->flagByObject($flag, $entity); + + // Get the destination. $destination = \Drupal::request()->get('destination', $entity->url()); //@todo SECURITY HOLE. Please fix! return new RedirectResponse($destination); } - public function unflag($flag, $entity) { - $flag = entity_load('flag_flag', $flag_id); - $entity = entity_load($flag->getFlaggableEntityType(), $entity_id); - \Drupal::service('flag')->unflag($flag, $entity); + public function unflag($flag_id, $entity_id) { + // Get the Flag Service. + $flagService = \Drupal::service('flag'); + + // Get the Flag and Entity objects. + $flag = $flagService->getFlagById($flag_id); + $entity = $flagService->getFlaggableById($flag, $entity_id); + + $flaggings = \Drupal::service('flag')->getFlaggings($entity, $flag); + foreach ($flaggings as $flagging) { + \Drupal::service('flag')->unflagByObject($flagging); + } $destination = \Drupal::request()->get('destination', $entity->url()); diff --git a/lib/Drupal/flag/FlagService.php b/lib/Drupal/flag/FlagService.php index 71895ea..17bbcd1 100644 --- a/lib/Drupal/flag/FlagService.php +++ b/lib/Drupal/flag/FlagService.php @@ -10,6 +10,9 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\flag\FlagInterface; +use Drupal\Core\Entity\EntityInterface; + /** * Flag service. @@ -92,25 +95,87 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ } public function getFlaggings(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { + if($account == NULL) { + $account = \Drupal::currentUser(); + } + + $result = \Drupal::entityQuery('flagging') + ->condition('uid', $account->id()) + ->condition('fid', $flag->id()) + ->condition('entity_type', $entity->getEntityTypeId()) + ->condition('entity_id', $entity->id()) + ->execute(); + + $flaggings = array(); + foreach ($result as $flagging_id) { + $flaggings[$flagging_id] = entity_load('flagging', $flagging_id); + } + + return $flaggings; + } + + public function getFlagById($flag_id) { + return entity_load('flag_flag', $flag_id); + } + public function getFlaggableById(FlagInterface $flag, $entity_id) { + return entity_load($flag->getFlaggableEntityType(), $entity_id); } - public function flag($flag, $entity, AccountInterface $account = NULL) { + public function flagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { if (empty($account)) { $account = \Drupal::currentUser(); } - entity_create('flagging', array( + $flagging = entity_create('flagging', array( 'type' => 'flag_flag', 'uid' => $account->id(), 'fid' => $flag->id(), 'entity_id' => $entity->id(), 'entity_type' => $entity->getEntityTypeId(), - ))->save(); + )); + + $flagging->save(); + + \Drupal::entityManager() + ->getViewBuilder($entity->getEntityTypeId()) + ->resetCache(array( + $entity, + )); + + return $flagging; + } + + public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { + if (empty($account)) { + $account = \Drupal::currentUser(); + } + + $flag = $this->getFlagById($flag_id); + $entity = $this->getFlaggableById($flag, $entity_id); + + return $this->flagByObject($flag, $entity, $account); + } + + public function unflagByObject(FlaggingInterface $flagging) { + $flagging->delete(); } - public function unflag($flagging) { + public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { + if (empty($account)) { + $account = \Drupal::currentUser(); + } + + $flag = $this->getFlagById($flag_id); + $entity = $this->getFlaggableById($flag, $entity_id); + + $out = array(); + $flaggings = $this->getFlaggings($entity, $flag); + foreach ($flaggings as $flagging) { + $out[] = $this->unflagByObject($flagging); + } + return $out; } } \ No newline at end of file From cf8c684cf8c710f9aed10103d25e1fc9815bc6a4 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 8 Apr 2014 22:37:13 -0500 Subject: [PATCH 378/629] Augmented Flagging, simplified reload link controller. --- .../flag/Controller/ReloadLinkController.php | 13 +++---------- lib/Drupal/flag/Entity/Flagging.php | 16 +++++++++++----- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/Drupal/flag/Controller/ReloadLinkController.php b/lib/Drupal/flag/Controller/ReloadLinkController.php index f28dd56..9928005 100644 --- a/lib/Drupal/flag/Controller/ReloadLinkController.php +++ b/lib/Drupal/flag/Controller/ReloadLinkController.php @@ -16,19 +16,12 @@ class ReloadLinkController extends ControllerBase { public function flag($flag_id, $entity_id) { - // Get the Flag Service. - $flagService = \Drupal::service('flag'); - // Get the Flag and Entity objects. - $flag = $flagService->getFlagById($flag_id); - $entity = $flagService->getFlaggableById($flag, $entity_id); - - // While we could use FlagService::flag() here, we wouldn't have the URL - // to redirect Drupal afterward. So we flag by object instead. - $flagService->flagByObject($flag, $entity); + $flagging = \Drupal::service('flag')->flag($flag_id, $entity_id); // Get the destination. - $destination = \Drupal::request()->get('destination', $entity->url()); + $destination = \Drupal::request()->get('destination', + $flagging->getFlaggable()->url()); //@todo SECURITY HOLE. Please fix! return new RedirectResponse($destination); diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index 7d0fb1e..b1d37ad 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -44,14 +44,20 @@ */ class Flagging extends ContentEntityBase implements FlaggingInterface { - protected $entity_id; + public function getFlag() { + return $this->bundle; + } - protected $entity_type; + public function getFlaggableType() { + return $this->get('entity_type')->value; + } - protected $fid; + public function getFlaggableId() { + return $this->get('entity_id')->value; + } - public function getFlag() { - return $this->bundle; + public function getFlaggable() { + return entity_load($this->getFlaggableType(), $this->getFlaggableId()); } public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { From b0887ccfc2f71b496b753f7ad81442c47786b40d Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 9 Apr 2014 20:53:21 -0500 Subject: [PATCH 379/629] Removed old flag handlers, hook_menu(), etc. --- flag.module | 173 +-- lib/Drupal/flag/Entity/Flag.php | 5 + lib/Drupal/flag/Handlers/AbstractFlag.php | 1541 --------------------- lib/Drupal/flag/Handlers/BrokenFlag.php | 19 - lib/Drupal/flag/Handlers/CommentFlag.php | 103 -- lib/Drupal/flag/Handlers/Flag.php | 239 ---- lib/Drupal/flag/Handlers/NodeFlag.php | 122 -- lib/Drupal/flag/Handlers/UserFlag.php | 99 -- 8 files changed, 9 insertions(+), 2292 deletions(-) delete mode 100644 lib/Drupal/flag/Handlers/AbstractFlag.php delete mode 100644 lib/Drupal/flag/Handlers/BrokenFlag.php delete mode 100644 lib/Drupal/flag/Handlers/CommentFlag.php delete mode 100644 lib/Drupal/flag/Handlers/Flag.php delete mode 100644 lib/Drupal/flag/Handlers/NodeFlag.php delete mode 100644 lib/Drupal/flag/Handlers/UserFlag.php diff --git a/flag.module b/flag.module index 67d435d..ed42a9e 100644 --- a/flag.module +++ b/flag.module @@ -43,7 +43,7 @@ use Drupal\node\NodeInterface; * with query condition on [name] field in [flag] table. * * @see flag_query_flagging_flag_names_alter() - */ + *//* function flag_entity_query_alter(EntityFieldQuery $query) { $conditions = &$query->entityConditions; @@ -56,13 +56,13 @@ function flag_entity_query_alter(EntityFieldQuery $query) { $query->addMetaData('flag_name_operator', $conditions['bundle']['operator']); unset($conditions['bundle']); } -} +}*/ /** * Implements hook_query_TAG_alter() for flagging_flag_names tag. * * @see flag_entity_query_alter() - */ + *//* function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { // Get value and operator for bundle condition from meta data. $value = $query->getMetaData('flag_name_value'); @@ -71,90 +71,7 @@ function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { // apply bundle condition on [flag].[name] field. $query->join('flag', 'f', 'flagging.fid = f.fid'); $query->condition('f.name', $value, $operator); -} - -/** - * Implements hook_menu(). - */ -function flag_menu() { - - $items[FLAG_ADMIN_PATH . '/add'] = array( - 'route_name' => 'flag_add_page', - 'type' => MENU_SIBLING_LOCAL_TASK, - 'weight' => 1, - ); - $items[FLAG_ADMIN_PATH . '/add/%node_type'] = array( - 'title' => 'Flag Add', - 'route_name' => 'flag_add', - 'type' => MENU_CALLBACK, - ); -/* - $items[FLAG_ADMIN_PATH . '/manage/%flag'] = array( - 'load arguments' => array(TRUE), // Allow for disabled flags. - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_form', FLAG_ADMIN_PATH_START + 1), - 'access callback' => 'user_access', - 'access arguments' => array('administer flags'), - 'file' => 'includes/flag.admin.inc', - 'type' => MENU_CALLBACK, - // Make the flag title the default title for descendant menu items. - 'title callback' => '_flag_menu_title', - 'title arguments' => array(FLAG_ADMIN_PATH_START + 1), - ); - $items[FLAG_ADMIN_PATH . '/manage/%flag/edit'] = array( - 'load arguments' => array(TRUE), // Allow for disabled flags. - 'title' => 'Edit flag', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, - ); - $items[FLAG_ADMIN_PATH . '/manage/%flag/export'] = array( - 'title' => 'Export', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_export_form', FLAG_ADMIN_PATH_START + 1), - 'access arguments' => array('administer flags'), - 'file' => 'includes/flag.export.inc', - 'type' => MENU_LOCAL_TASK, - 'weight' => 20, - ); - $items[FLAG_ADMIN_PATH . '/manage/%flag/delete'] = array( - 'title' => 'Delete flag', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_delete_confirm', FLAG_ADMIN_PATH_START + 1), - 'access callback' => 'user_access', - 'access arguments' => array('administer flags'), - 'file' => 'includes/flag.admin.inc', - 'type' => MENU_CALLBACK, - ); - $items[FLAG_ADMIN_PATH . '/manage/%flag/update'] = array( - 'load arguments' => array(TRUE), // Allow for disabled flags. - 'title' => 'Update', - 'page callback' => 'flag_update_page', - 'page arguments' => array(FLAG_ADMIN_PATH_START + 1), - 'access arguments' => array('administer flags'), - 'file' => 'includes/flag.export.inc', - 'type' => MENU_CALLBACK, - ); - $items['flag/%/%flag/%'] = array( - 'title' => 'Flag', - 'page callback' => 'flag_page', - 'page arguments' => array(1, 2, 3), - 'access callback' => 'user_access', - 'access arguments' => array('access content'), - 'file' => 'includes/flag.pages.inc', - 'type' => MENU_CALLBACK, - ); - $items['flag/confirm/%/%flag/%'] = array( - 'title' => 'Flag confirm', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('flag_confirm', 2, 3, 4), - 'access callback' => 'user_access', - 'access arguments' => array('access content'), - 'file' => 'includes/flag.pages.inc', - 'type' => MENU_CALLBACK, - ); -*/ - return $items; -} +}*/ /** * Implements hook_admin_menu_map(). @@ -235,15 +152,6 @@ function flag_load($flag_name, $include_disabled = FALSE) { // A menu loader has to return FALSE (not NULL) when no object is found. return FALSE; } - -/** - * Menu title callback. - */ -function _flag_menu_title($flag) { - // The following conditional it to handle a D7 bug (@todo: link). - return $flag ? $flag->label : ''; -} - /** * Implements hook_help(). */ @@ -365,33 +273,6 @@ function flag_get_types() { return $types; } -/** - * Instantiates a new flag handler. - * - * A flag handler is more commonly know as "a flag". A factory method usually - * populates this empty flag with settings loaded from the database. - * - * @param $entity_type - * The entity type to create a flag handler for. This may be FALSE if the - * entity type property could not be found in the flag configuration data. - * - * @return - * A flag handler object. This may be the special class BrokenFlag is there is - * a problem with the flag. - */ -function flag_create_handler($entity_type) { - $definition = flag_fetch_definition($entity_type); - if (isset($definition) && class_exists($definition['handler'])) { - $handler = new $definition['handler']; - } - else { - $handler = new \Drupal\flag\Handlers\BrokenFlag(); - } - $handler->entity_type = $entity_type; - $handler->construct(); - return $handler; -} - /** * Implements hook_permission(). */ @@ -690,52 +571,6 @@ function flag_field_attach_save($entity_type, $entity) { } } -/* - * Implements hook_contextual_links_view_alter(). - */ -function flag_contextual_links_view_alter(&$element, $items) { -/* - if (isset($element['#element']['#entity_type'])) { - $entity_type = $element['#element']['#entity_type']; - - // Get the entity out of the element. This requires a bit of legwork. - if (isset($element['#element']['#entity'])) { - // EntityAPI entities will all have the entity in the same place. - $entity = $element['#element']['#entity']; - } - elseif (isset($element['#element']['#' . $entity_type])) { - // Node module at least puts it here. - $entity = $element['#element']['#' . $entity_type]; - } - else { - // Give up. - return; - } - - // Get all possible flags for this entity type. - $flags = flag_get_flags($entity_type); - - foreach ($flags as $name => $flag) { - if (!$flag->show_contextual_link) { - continue; - } - - list($entity_id) = entity_extract_ids($entity_type, $entity); - if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { - // User has no permission to use this flag or flag does not apply to this - // object. The link is not skipped if the user has "flag" access but - // not "unflag" access (this way the unflag denied message is shown). - continue; - } - - $element['#links']['flag-'. $name] = array( - 'title' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), - 'html' => TRUE, - ); - } - }*/ -} - /** * Implements hook_entity_view(). * diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 2515ae2..6c74265 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -315,6 +315,11 @@ public function preSave(EntityStorageInterface $storage_controller) { // Save the Link Type configuration. $linkTypePlugin = $this->getLinkTypePlugin(); $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); + + // Reset the render cache for the entity. + \Drupal::entityManager() + ->getViewBuilder($this->getFlaggableEntityType()) + ->resetCache(); } public function toArray() { diff --git a/lib/Drupal/flag/Handlers/AbstractFlag.php b/lib/Drupal/flag/Handlers/AbstractFlag.php deleted file mode 100644 index a43ebad..0000000 --- a/lib/Drupal/flag/Handlers/AbstractFlag.php +++ /dev/null @@ -1,1541 +0,0 @@ -construct() on the new handler object. - */ -class AbstractFlag { - - /** - * The database ID. - * - * NULL for flags that haven't been saved to the database yet. - * - * @var integer - */ - var $fid = NULL; - - /** - * The entity type this flag works with. - * - * @var string - */ - var $entity_type = NULL; - - /** - * The flag's "machine readable" name. - * - * @var string - */ - var $name = ''; - - /** - * The human-readable title for this flag. - * - * @var string - */ - var $title = ''; - - /** - * Whether this flag state should act as a single toggle to all users. - * - * @var bool - */ - var $global = FALSE; - - /** - * The sub-types, AKA bundles, this flag applies to. - * - * This may be an empty array to indicate all types apply. - * - * @var array - */ - var $types = array(); - - /** - * The roles array. This can be populated by fetch_roles() when needed. - */ - var $roles = array( - 'flag' => array(), - 'unflag' => array(), - ); - - /** - * An associative array containing textual errors that may be created during validation. - * - * The array keys should reflect the type of error being set. At this time, - * the only "special" behavior related to the array keys is that - * drupal_access_denied() is called when the key is 'access-denied' and - * javascript is disabled. - * - * @var array - */ - var $errors = array(); - - /** - * Creates a flag from a database row. Returns it. - * - * This is static method. - * - * The reason this isn't a non-static instance method --like Views's init()-- - * is because the class to instantiate changes according to the 'entity_type' - * database column. This design pattern is known as the "Single Table - * Inheritance". - */ - static function factory_by_row($row) { - $flag = flag_create_handler($row->entity_type); - - // Lump all data unto the object... - foreach ($row as $field => $value) { - $flag->$field = $value; - } - // ...but skip the following two. - unset($flag->options, $flag->type); - - // Populate the options with the defaults. - $options = (array) unserialize($row->options); - $options += $flag->options(); - - // Make the unserialized options accessible as normal properties. - foreach ($options as $option => $value) { - $flag->$option = $value; - } - - if (!empty($row->type)) { - // The loop loading from the database should further populate this property. - $flag->types[] = $row->type; - } - - return $flag; - } - - /** - * Create a complete flag (except an FID) from an array definition. - */ - static function factory_by_array($config) { - // Allow for flags with a missing entity type. - $config += array( - 'entity_type' => FALSE, - ); - $flag = flag_create_handler($config['entity_type']); - - foreach ($config as $option => $value) { - $flag->$option = $value; - } - - if (isset($config['locked']) && is_array($config['locked'])) { - $flag->locked = drupal_map_assoc($config['locked']); - } - - return $flag; - } - - /** - * Another factory method. Returns a new, "empty" flag; e.g., one suitable for - * the "Add new flag" page. - */ - static function factory_by_entity_type($entity_type) { - return flag_create_handler($entity_type); - } - - /** - * Declares the options this flag supports, and their default values. - * - * Derived classes should want to override this. - */ - function options() { - $options = array( - // The text for the "flag this" link for this flag. - 'flag_short' => '', - // The description of the "flag this" link. - 'flag_long' => '', - // Message displayed after flagging an entity. - 'flag_message' => '', - // Likewise but for unflagged. - 'unflag_short' => '', - 'unflag_long' => '', - 'unflag_message' => '', - 'unflag_denied_text' => '', - // The link type used by the flag, as defined in hook_flag_link_type_info(). - 'link_type' => 'toggle', - 'weight' => 0, - ); - - // Merge in options from the current link type. - $link_type = $this->get_link_type(); - $options = array_merge($options, $link_type['options']); - - // Allow other modules to change the flag options. - drupal_alter('flag_options', $options, $this); - return $options; - } - /** - * Provides a form for setting options. - * - * Derived classes should want to override this. - */ - function options_form(&$form) { - } - - /** - * Default constructor. Loads the default options. - */ - function construct() { - $options = $this->options(); - foreach ($options as $option => $value) { - $this->$option = $value; - } - } - - /** - * Load this flag's role data from permissions. - * - * Loads an array of roles into the flag, where each key is an action ('flag' - * and 'unflag'), and each value is a flat array of role ids which may perform - * that action. - * - * This should only be used when a complete overview of a flag's permissions - * is needed. Use $flag->access or $flag->user_access() instead. - */ - function fetch_roles() { - $actions = array('flag', 'unflag'); - foreach ($actions as $action) { - // Build the permission string. - $permission = "$action $this->name"; - // We want a flat array of rids rather than $rid => $role_name. - $this->roles[$action] = array_keys(user_roles(FALSE, $permission)); - } - } - - /** - * Update the flag with settings entered in a form. - */ - function form_input($form_values) { - // Load the form fields indiscriminately unto the flag (we don't care about - // stray FormAPI fields because we aren't touching unknown properties anyway. - foreach ($form_values as $field => $value) { - $this->$field = $value; - } - $this->types = array_values(array_filter($this->types)); - // Clear internal titles cache: - $this->get_title(NULL, TRUE); - } - - /** - * Validates this flag's options. - * - * @return - * A list of errors encountered while validating this flag's options. - */ - function validate() { - // TODO: It might be nice if this used automatic method discovery rather - // than hard-coding the list of validate functions. - return array_merge_recursive( - $this->validate_name(), - $this->validate_access() - ); - } - - /** - * Validates that the current flag's name is valid. - * - * @return - * A list of errors encountered while validating this flag's name. - */ - function validate_name() { - $errors = array(); - - // Ensure a safe machine name. - if (!preg_match('/^[a-z_][a-z0-9_]*$/', $this->name)) { - $errors['name'][] = array( - 'error' => 'flag_name_characters', - 'message' => t('The flag name may only contain lowercase letters, underscores, and numbers.'), - ); - } - // Ensure the machine name is unique. - $flag = flag_get_flag($this->name); - if (!empty($flag) && (!isset($this->fid) || $flag->fid != $this->fid)) { - $errors['name'][] = array( - 'error' => 'flag_name_unique', - 'message' => t('Flag names must be unique. This flag name is already in use.'), - ); - } - - return $errors; - } - - /** - * Validates that the current flag's access settings are valid. - */ - function validate_access() { - $errors = array(); - - // Require an unflag access denied message a role is not allowed to unflag. - if (empty($this->unflag_denied_text)) { - foreach ($this->roles['flag'] as $key => $rid) { - if ($rid && empty($this->roles['unflag'][$key])) { - $errors['unflag_denied_text'][] = array( - 'error' => 'flag_denied_text_required', - 'message' => t('The "Unflag not allowed text" is required if any user roles are not allowed to unflag.'), - ); - break; - } - } - } - - // Do not allow unflag access without flag access. - foreach ($this->roles['unflag'] as $key => $rid) { - if ($rid && empty($this->roles['flag'][$key])) { - $errors['roles'][] = array( - 'error' => 'flag_roles_unflag', - 'message' => t('Any user role that has the ability to unflag must also have the ability to flag.'), - ); - break; - } - } - - return $errors; - } - - /** - * Fetches, possibly from some cache, an entity this flag works with. - */ - function fetch_entity($entity_id, $object_to_remember = NULL) { - static $cache = array(); - if (isset($object_to_remember)) { - $cache[$entity_id] = $object_to_remember; - } - if (!array_key_exists($entity_id, $cache)) { - $entity = $this->_load_entity($entity_id); - $cache[$entity_id] = $entity ? $entity : NULL; - } - return $cache[$entity_id]; - } - - /** - * Loads an entity this flag works with. - * Derived classes must implement this. - * - * @abstract - * @private - * @static - */ - function _load_entity($entity_id) { - return NULL; - } - - /** - * Store an object in the flag handler's cache. - * - * This is needed because otherwise fetch_object() loads the object from the - * database (by calling _load_entity()), whereas sometimes we want to fetch - * an object that hasn't yet been saved to the database. Subsequent calls to - * fetch_entity() return the remembered object. - * - * @param $entity_id - * The ID of the object to cache. - * @param $object - * The object to cache. - */ - function remember_entity($entity_id, $object) { - $this->fetch_entity($entity_id, $object); - } - - /** - * @defgroup access Access control - * @{ - */ - - /** - * Returns TRUE if the flag applies to the given entity. - * - * Derived classes must implement this. - * - * @abstract - */ - function applies_to_entity($entity) { - return FALSE; - } - - /** - * Returns TRUE if the flag applies to the entity with the given ID. - * - * This is a convenience method that simply loads the object and calls - * applies_to_entity(). If you already have the object, don't call - * this function: call applies_to_entity() directly. - */ - function applies_to_entity_id($entity_id) { - return $this->applies_to_entity($this->fetch_entity($entity_id)); - } - - /** - * Provides permissions for this flag. - * - * @return - * An array of permissions for hook_permission(). - */ - function get_permissions() { - return array( - "flag $this->name" => array( - 'title' => t('Flag %flag_title', array( - '%flag_title' => $this->title, - )), - ), - "unflag $this->name" => array( - 'title' => t('Unflag %flag_title', array( - '%flag_title' => $this->title, - )), - ), - ); - } - - /** - * Determines whether the user has the permission to use this flag. - * - * @param $action - * (optional) The action to test, either "flag" or "unflag". If none given, - * "flag" will be tested, which is the minimum permission to use a flag. - * @param $account - * (optional) The user object. If none given, the current user will be used. - * - * @return - * Boolean TRUE if the user is allowed to flag/unflag. FALSE otherwise. - * - * @see flag_permission() - */ - function user_access($action = 'flag', $account = NULL) { - if (!isset($account)) { - $account = $GLOBALS['user']; - } - - // Anonymous user can't use this system unless Session API is installed. - if ($account->uid == 0 && !module_exists('session_api')) { - return FALSE; - } - - $permission_string = "$action $this->name"; - return user_access($permission_string, $account); - } - - /** - * Determines whether the user may flag, or unflag, the given entity. - * - * This method typically should not be overridden by child classes. Instead - * they should implement type_access(), which is called by this method. - * - * @param $entity_id - * The entity ID to flag/unflag. - * @param $action - * The action to test. Either 'flag' or 'unflag'. Leave NULL to determine - * by flag status. - * @param $account - * The user on whose behalf to test the flagging action. Leave NULL for the - * current user. - * - * @return - * Boolean TRUE if the user is allowed to flag/unflag the given entity. - * FALSE otherwise. - */ - function access($entity_id, $action = NULL, $account = NULL) { - if (!isset($account)) { - $account = $GLOBALS['user']; - } - - if (isset($entity_id) && !$this->applies_to_entity_id($entity_id)) { - // Flag does not apply to this entity. - return FALSE; - } - - if (!isset($action)) { - $uid = $account->uid; - $sid = flag_get_sid($uid); - $action = $this->is_flagged($entity_id, $uid, $sid) ? 'unflag' : 'flag'; - } - - // Base initial access on the user's basic permission to use this flag. - $access = $this->user_access($action, $account); - - // Check for additional access rules provided by sub-classes. - $child_access = $this->type_access($entity_id, $action, $account); - if (isset($child_access)) { - $access = $child_access; - } - - // Allow modules to disallow (or allow) access to flagging. - // We grant access to the flag if both of the following conditions are met: - // - No modules say to deny access. - // - At least one module says to grant access. - // If no module specified either allow or deny, we fall back to the - // default access check above. - $module_access = module_invoke_all('flag_access', $this, $entity_id, $action, $account); - if (in_array(FALSE, $module_access, TRUE)) { - $access = FALSE; - } - elseif (in_array(TRUE, $module_access, TRUE)) { - // WARNING: This allows modules to bypass the default access check! - $access = TRUE; - } - - return $access; - } - - /** - * Determine access to multiple objects. - * - * Similar to user_access() but works on multiple IDs at once. Called in the - * pre_render() stage of the 'Flag links' field within Views to find out where - * that link applies. The reason we do a separate DB query, and not lump this - * test in the Views query, is to make 'many to one' tests possible without - * interfering with the rows, and also to reduce the complexity of the code. - * - * This method typically should not be overridden by child classes. Instead - * they should implement type_access_multiple(), which is called by this - * method. - * - * @param $entity_ids - * The array of entity IDs to check. The keys are the entity IDs, the - * values are the actions to test: either 'flag' or 'unflag'. - * @param $account - * (optional) The account for which the actions will be compared against. - * If left empty, the current user will be used. - * - * @return - * An array whose keys are the object IDs and values are booleans indicating - * access. - * - * @see hook_flag_access_multiple() - */ - function access_multiple($entity_ids, $account = NULL) { - $account = isset($account) ? $account : $GLOBALS['user']; - $access = array(); - - // First check basic user access for this action. - foreach ($entity_ids as $entity_id => $action) { - $access[$entity_id] = $this->user_access($entity_ids[$entity_id], $account); - } - - // Check for additional access rules provided by sub-classes. - $child_access = $this->type_access_multiple($entity_ids, $account); - if (isset($child_access)) { - foreach ($child_access as $entity_id => $entity_access) { - if (isset($entity_access)) { - $access[$entity_id] = $entity_access; - } - } - } - - // Merge in module-defined access. - foreach (module_implements('flag_access_multiple') as $module) { - $module_access = module_invoke($module, 'flag_access_multiple', $this, $entity_ids, $account); - foreach ($module_access as $entity_id => $entity_access) { - if (isset($entity_access)) { - $access[$entity_id] = $entity_access; - } - } - } - - return $access; - } - - /** - * Implements access() implemented by each child class. - * - * @abstract - * - * @return - * FALSE if access should be denied, or NULL if there is no restriction to - * be made. This should NOT return TRUE. - */ - function type_access($entity_id, $action, $account) { - return NULL; - } - - /** - * Implements access_multiple() implemented by each child class. - * - * @abstract - * - * @return - * An array keyed by entity ids, whose values represent the access to the - * corresponding entity. The access value may be FALSE if access should be - * denied, or NULL (or not set) if there is no restriction to be made. It - * should NOT be TRUE. - */ - function type_access_multiple($entity_ids, $account) { - return array(); - } - - /** - * @} End of "defgroup access". - */ - - /** - * Given an entity, returns its ID. - * Derived classes must implement this. - * - * @abstract - */ - function get_entity_id($entity) { - return NULL; - } - - /** - * Utility function: Checks whether a flag applies to a certain type, and - * possibly subtype, of entity. - * - * @param $entity_type - * The type of entity being checked, such as "node". - * @param $content_subtype - * The subtype being checked. For entities this will be the bundle name (the - * node type in the case of nodes). - * - * @return - * TRUE if the flag is enabled for this type and subtype. - */ - function access_entity_enabled($entity_type, $content_subtype = NULL) { - $entity_type_matches = ($this->entity_type == $entity_type); - $sub_type_matches = FALSE; - if (!isset($content_subtype) || !count($this->types)) { - // Subtype automatically matches if we're not asked about it, - // or if the flag applies to all subtypes. - $sub_type_matches = TRUE; - } - else { - $sub_type_matches = in_array($content_subtype, $this->types); - } - return $entity_type_matches && $sub_type_matches; - } - - /** - * Determine whether the flag should show a flag link in entity links. - * - * Derived classes are likely to implement this. - * - * @param $view_mode - * The view mode of the entity being displayed. - * - * @return - * A boolean indicating whether the flag link is to be shown in entity - * links. - */ - function shows_in_entity_links($view_mode) { - return FALSE; - } - - /** - * Returns TRUE if this flag requires anonymous user cookies. - */ - function uses_anonymous_cookies() { - global $user; - return $user->uid == 0 && variable_get('cache', 0); - } - - /** - * Flags, or unflags, an item. - * - * @param $action - * Either 'flag' or 'unflag'. - * @param $entity_id - * The ID of the item to flag or unflag. - * @param $account - * The user on whose behalf to flag. Leave empty for the current user. - * @param $skip_permission_check - * Flag the item even if the $account user don't have permission to do so. - * @param $flagging - * (optional) This method works in tandem with Drupal's Field subsystem. - * Pass in a flagging entity if you want operate on it as well. - * - * @return - * FALSE if some error occured (e.g., user has no permission, flag isn't - * applicable to the item, etc.), TRUE otherwise. - */ - function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { - // Get the user. - if (!isset($account)) { - $account = $GLOBALS['user']; - } - if (!$account) { - return FALSE; - } - - // Check access and applicability. - if (!$skip_permission_check) { - if (!$this->access($entity_id, $action, $account)) { - $this->errors['access-denied'] = t('You are not allowed to flag, or unflag, this content.'); - // User has no permission to flag/unflag this object. - return FALSE; - } - } - else { - // We are skipping permission checks. However, at a minimum we must make - // sure the flag applies to this entity type: - if (!$this->applies_to_entity_id($entity_id)) { - $this->errors['entity-type'] = t('This flag does not apply to this entity type.'); - return FALSE; - } - } - - if (($this->errors = module_invoke_all('flag_validate', $action, $this, $entity_id, $account, $skip_permission_check, $flagging))) { - return FALSE; - } - - // Clear various caches; We don't want code running after us to report - // wrong counts or false flaggings. - drupal_static_reset('flag_get_counts'); - drupal_static_reset('flag_get_user_flags'); - drupal_static_reset('flag_get_entity_flags'); - - // Find out which user id to use. - $uid = $this->global ? 0 : $account->uid; - - // Find out which session id to use. - if ($this->global) { - $sid = 0; - } - else { - $sid = flag_get_sid($uid, TRUE); - // Anonymous users must always have a session id. - if ($sid == 0 && $account->uid == 0) { - $this->errors['session'] = t('Internal error: You are anonymous but you have no session ID.'); - return FALSE; - } - } - - // Set our uid and sid to the flagging object. - if (isset($flagging)) { - $flagging->uid = $uid; - $flagging->sid = $sid; - } - - // @todo: Discuss: Should we call field_attach_validate()? None of the - // entities in core does this (fields entered through forms are already - // validated). - // - // @todo: Discuss: Core wraps everything in a try { }, should we? - - // Perform the flagging or unflagging of this flag. - $existing_flagging_id = $this->_is_flagged($entity_id, $uid, $sid); - $flagged = (bool) $existing_flagging_id; - if ($action == 'unflag') { - if ($this->uses_anonymous_cookies()) { - $this->_unflag_anonymous($entity_id); - } - if ($flagged) { - if (!isset($flagging)) { - $flagging = flagging_load($existing_flagging_id); - } - $transaction = db_transaction(); - try { - // Note the order: We decrease the count first so hooks have accurate - // data, then invoke hooks, then delete the flagging entity. - $this->_decrease_count($entity_id); - module_invoke_all('flag_unflag', $this, $entity_id, $account, $flagging); - // Invoke Rules event. - if (module_exists('rules')) { - $event_name = 'flag_unflagged_' . $this->name; - // We only support flags on entities. - if (entity_get_info($this->entity_type)) { - $variables = array( - 'flag' => $this, - 'flagged_' . $this->entity_type => $entity_id, - 'flagging_user' => $account, - 'flagging' => $flagging, - ); - rules_invoke_event_by_args($event_name, $variables); - } - } - $this->_delete_flagging($flagging); - $this->_unflag($entity_id, $flagging->flagging_id); - } - catch (Exception $e) { - $transaction->rollback(); - watchdog_exception('flag', $e); - throw $e; - } - } - } - elseif ($action == 'flag') { - if ($this->uses_anonymous_cookies()) { - $this->_flag_anonymous($entity_id); - } - if (!$flagged) { - // The entity is unflagged. By definition there is no flagging entity, - // but we may have been passed one in to save. - if (!isset($flagging)) { - // Construct a new flagging object if we don't have one. - $flagging = $this->new_flagging($entity_id, $uid, $sid); - } - // Save the flagging entity (just our table). - $flagging_id = $this->_flag($entity_id, $uid, $sid); - // The _flag() method is a plain DB record writer, so it's a bit - // antiquated. We have to explicitly get our new ID out. - $flagging->flagging_id = $flagging_id; - $this->_increase_count($entity_id); - // We're writing out a flagging entity even when we aren't passed one - // (e.g., when flagging via JavaScript toggle links); in this case - // Field API will assign the fields their default values. - $this->_insert_flagging($flagging); - module_invoke_all('flag_flag', $this, $entity_id, $account, $flagging); - // Invoke Rules event. - if (module_exists('rules')) { - $event_name = 'flag_flagged_' . $this->name; - // We only support flags on entities. - if (entity_get_info($this->entity_type)) { - $variables = array( - 'flag' => $this, - 'flagged_' . $this->entity_type => $entity_id, - 'flagging_user' => $account, - 'flagging' => $this->get_flagging($entity_id, $account->uid), - ); - rules_invoke_event_by_args($event_name, $variables); - } - } - } - else { - // Nothing to do. Item is already flagged. - // - // Except in the case a $flagging object is passed in: in this case - // we're, for example, arriving from an editing form and need to update - // the entity. - if ($flagging) { - $this->_update_flagging($flagging); - } - } - } - - return TRUE; - } - - /** - * The entity CRUD methods _{insert,update,delete}_flagging() are for private - * use by the flag() method. - * - * The reason programmers should not call them directly is because a flagging - * operation is also accompanied by some bookkeeping (calling hooks, updating - * counters) or access control. These tasks are handled by the flag() method. - */ - private function _insert_flagging($flagging) { - field_attach_presave('flagging', $flagging); - field_attach_insert('flagging', $flagging); - } - private function _update_flagging($flagging) { - field_attach_presave('flagging', $flagging); - field_attach_update('flagging', $flagging); - // Update the cache. - entity_get_controller('flagging')->resetCache(); - } - private function _delete_flagging($flagging) { - field_attach_delete('flagging', $flagging); - // Remove from the cache. - entity_get_controller('flagging')->resetCache(); - } - - /** - * Construct a new, empty flagging entity object. - * - * @param mixed $entity_id - * The unique identifier of the object being flagged. - * @param int $uid - * (optional) The user id of the user doing the flagging. - * @param mixed $sid - * (optional) The user SID (provided by Session API) who is doing the - * flagging. The SID is 0 for logged in users. - * - * @return stdClass - * The returned object has at least the 'flag_name' property set, which - * enables Field API to figure out the bundle, but it's your responsibility - * to eventually populate 'entity_id' and 'flagging_id'. - */ - function new_flagging($entity_id = NULL, $uid = NULL, $sid = NULL) { - return (object) array( - 'flagging_id' => NULL, - 'flag_name' => $this->name, - 'entity_id' => $entity_id, - 'uid' => $uid, - 'sid' => $sid, - ); - } - - /** - * Determines if a certain user has flagged this object. - * - * Thanks to using a cache, inquiring several different flags about the same - * item results in only one SQL query. - * - * @param $uid - * (optional) The user ID whose flags we're checking. If none given, the - * current user will be used. - * - * @return - * TRUE if the object is flagged, FALSE otherwise. - */ - function is_flagged($entity_id, $uid = NULL, $sid = NULL) { - return (bool) $this->get_flagging_record($entity_id, $uid, $sid); - } - - /** - * Returns the flagging record. - * - * This method returns the "flagging record": the {flagging} record that - * exists for each flagged item (for a certain user). If the item isn't - * flagged, returns NULL. This method could be useful, for example, when you - * want to find out the 'flagging_id' or 'timestamp' values. - * - * Thanks to using a cache, inquiring several different flags about the same - * item results in only one SQL query. - * - * Parameters are the same as is_flagged()'s. - */ - function get_flagging_record($entity_id, $uid = NULL, $sid = NULL) { - $uid = $this->global ? 0 : (!isset($uid) ? $GLOBALS['user']->uid : $uid); - $sid = $this->global ? 0 : (!isset($sid) ? flag_get_sid($uid) : $sid); - - // flag_get_user_flags() does caching. - $user_flags = flag_get_user_flags($this->entity_type, $entity_id, $uid, $sid); - return isset($user_flags[$this->name]) ? $user_flags[$this->name] : NULL; - } - - /** - * Similar to is_flagged() excepts it returns the flagging entity. - */ - function get_flagging($entity_id, $uid = NULL, $sid = NULL) { - if (($record = $this->get_flagging_record($entity_id, $uid, $sid))) { - return flagging_load($record->flagging_id); - } - } - - /** - * Determines if a certain user has flagged this object. - * - * You probably shouldn't call this raw private method: call the - * is_flagged() method instead. - * - * This method is similar to is_flagged() except that it does direct SQL and - * doesn't do caching. Use it when you want to not affect the cache, or to - * bypass it. - * - * @return - * If the object is flagged, returns the value of the 'flagging_id' column. - * Else, returns FALSE. - * - * @private - */ - function _is_flagged($entity_id, $uid, $sid) { - return db_select('flagging', 'fc') - ->fields('fc', array('flagging_id')) - ->condition('fid', $this->fid) - ->condition('uid', $uid) - ->condition('sid', $sid) - ->condition('entity_id', $entity_id) - ->execute() - ->fetchField(); - } - - /** - * A low-level method to flag an object. - * - * You probably shouldn't call this raw private method: call the flag() - * function instead. - * - * @return - * The 'flagging_id' column of the new {flagging} record. - * - * @private - */ - function _flag($entity_id, $uid, $sid) { - $flagging_id = db_insert('flagging') - ->fields(array( - 'fid' => $this->fid, - 'entity_type' => $this->entity_type, - 'entity_id' => $entity_id, - 'uid' => $uid, - 'sid' => $sid, - 'timestamp' => REQUEST_TIME, - )) - ->execute(); - return $flagging_id; - } - - /** - * A low-level method to unflag an object. - * - * You probably shouldn't call this raw private method: call the flag() - * function instead. - * - * @private - */ - function _unflag($entity_id, $flagging_id) { - db_delete('flagging')->condition('flagging_id', $flagging_id)->execute(); - } - - /** - * Increases the flag count for an object. - * - * @param $entity_id - * For which item should the count be increased. - * @param $number - * The amount of counts to increasing. Defaults to 1. - * - * @private - */ - function _increase_count($entity_id, $number = 1) { - db_merge('flag_counts') - ->key(array( - 'fid' => $this->fid, - 'entity_id' => $entity_id, - )) - ->fields(array( - 'entity_type' => $this->entity_type, - 'count' => $number, - 'last_updated' => REQUEST_TIME, - )) - ->updateFields(array( - 'last_updated' => REQUEST_TIME, - )) - ->expression('count', 'count + :inc', array(':inc' => $number)) - ->execute(); - } - - /** - * Decreases the flag count for an object. - * - * @param $entity_id - * For which item should the count be descreased. - * @param $number - * The amount of counts to decrease. Defaults to 1. - * - * @private - */ - function _decrease_count($entity_id, $number = 1) { - // Delete rows with count 0, for data consistency and space-saving. - // Done before the db_update() to prevent out-of-bounds errors on "count". - db_delete('flag_counts') - ->condition('fid', $this->fid) - ->condition('entity_id', $entity_id) - ->condition('count', $number, '<=') - ->execute(); - - // Update the count with the new value otherwise. - db_update('flag_counts') - ->expression('count', 'count - :inc', array(':inc' => $number)) - ->fields(array( - 'last_updated' => REQUEST_TIME, - )) - ->condition('fid', $this->fid) - ->condition('entity_id', $entity_id) - ->execute(); - } - - /** - * Set a cookie for anonymous users to record their flagging. - * - * @private - */ - function _flag_anonymous($entity_id) { - $storage = FlagCookieStorage::factory($this); - $storage->flag($entity_id); - } - - /** - * Remove the cookie for anonymous users to record their unflagging. - * - * @private - */ - function _unflag_anonymous($entity_id) { - $storage = FlagCookieStorage::factory($this); - $storage->unflag($entity_id); - } - - /** - * Returns the number of times an item is flagged. - * - * Thanks to using a cache, inquiring several different flags about the same - * item results in only one SQL query. - */ - function get_count($entity_id) { - $counts = flag_get_counts($this->entity_type, $entity_id); - return isset($counts[$this->name]) ? $counts[$this->name] : 0; - } - - /** - * Returns the number of items a user has flagged. - * - * For global flags, pass '0' as the user ID and session ID. - */ - function get_user_count($uid, $sid = NULL) { - if (!isset($sid)) { - $sid = flag_get_sid($uid); - } - return db_select('flagging', 'fc')->fields('fc', array('flagging_id')) - ->condition('fid', $this->fid) - ->condition('uid', $uid) - ->condition('sid', $sid) - ->countQuery() - ->execute() - ->fetchField(); - } - - /** - * Processes a flag label for display. This means language translation and - * token replacements. - * - * You should always call this function and not get at the label directly. - * E.g., do `print $flag->get_label('title')` instead of `print - * $flag->title`. - * - * @param $label - * The label to get, e.g. 'title', 'flag_short', 'unflag_short', etc. - * @param $entity_id - * The ID in whose context to interpret tokens. If not given, only global - * tokens will be substituted. - * @return - * The processed label. - */ - function get_label($label, $entity_id = NULL) { - if (!isset($this->$label)) { - return; - } - $label = t($this->$label); - if (strpos($label, '[') !== FALSE) { - $label = $this->replace_tokens($label, array(), array('sanitize' => FALSE), $entity_id); - } - return filter_xss_admin($label); - } - - /** - * Get the link type for this flag. - */ - function get_link_type() { - $link_types = flag_get_link_types(); - return (isset($this->link_type) && isset($link_types[$this->link_type])) ? $link_types[$this->link_type] : $link_types['normal']; - } - - /** - * Replaces tokens in a label. Only the 'global' token context is recognized - * by default, so derived classes should override this method to add all - * token contexts they understand. - */ - function replace_tokens($label, $contexts, $options, $entity_id) { - if (strpos($label , 'flagging:') !== FALSE) { - if (($flagging = $this->get_flagging($entity_id))) { - $contexts['flagging'] = $flagging; - } - } - return token_replace($label, $contexts, $options); - } - - /** - * Returns the token types this flag understands in labels. These are used - * for narrowing down the token list shown in the help box to only the - * relevant ones. - * - * Derived classes should override this. - */ - function get_labels_token_types() { - return array('flagging'); - } - - /** - * A convenience method for getting the flag title. - * - * `$flag->get_title()` is shorthand for `$flag->get_label('title')`. - */ - function get_title($entity_id = NULL, $reset = FALSE) { - static $titles = array(); - if ($reset) { - $titles = array(); - } - $slot = intval($entity_id); // Convert NULL to 0. - if (!isset($titles[$this->fid][$slot])) { - $titles[$this->fid][$slot] = $this->get_label('title', $entity_id); - } - return $titles[$this->fid][$slot]; - } - - /** - * Returns a 'flag action' object. It exists only for the sake of its - * informative tokens. Currently, it's utilized only for the 'mail' action. - * - * Derived classes should populate the 'content_title' and 'content_url' - * slots. - */ - function get_flag_action($entity_id) { - $flag_action = new stdClass(); - $flag_action->flag = $this->name; - $flag_action->entity_type = $this->entity_type; - $flag_action->entity_id = $entity_id; - return $flag_action; - } - - /** - * Returns an array of errors set during validation. - */ - function get_errors() { - return $this->errors; - } - - /** - * @addtogroup actions - * @{ - * Methods that can be overridden to support Actions. - */ - - /** - * Returns an array of all actions that are executable with this flag. - */ - function get_valid_actions() { - $actions = module_invoke_all('action_info'); - foreach ($actions as $callback => $action) { - if ($action['type'] != $this->entity_type && !in_array('any', $action['triggers'])) { - unset($actions[$callback]); - } - } - return $actions; - } - - /** - * Returns objects the action may possibly need. This method should return at - * least the 'primary' object the action operates on. - * - * This method is needed because get_valid_actions() returns actions that - * don't necessarily operate on an object of a type this flag manages. For - * example, flagging a comment may trigger an 'Unpublish post' action on a - * node; So the comment flag needs to tell the action about some node. - * - * Derived classes must implement this. - * - * @abstract - */ - function get_relevant_action_objects($entity_id) { - return array(); - } - - /** - * @} End of "addtogroup actions". - */ - - /** - * @addtogroup views - * @{ - * Methods that can be overridden to support the Views module. - */ - - /** - * Returns information needed for Views integration. E.g., the Views table - * holding the flagged object, its primary key, and various labels. See - * derived classes for examples. - * - * @static - */ - function get_views_info() { - return array(); - } - - /** - * @} End of "addtogroup views". - */ - - /** - * Saves a flag to the database. It is a wrapper around update() and insert(). - */ - function save() { - // Allow the 'global' property to be a boolean, particularly when defined in - // hook_flag_default_flags(). Without this, a value of FALSE gets casted to - // an empty string which violates our schema. Other boolean properties are - // fine, as they are serialized. - $this->global = (int) $this->global; - - if (isset($this->fid)) { - $this->update(); - $this->is_new = FALSE; - } - else { - $this->insert(); - $this->is_new = TRUE; - } - // Clear the page cache for anonymous users. - cache()->deleteTags(array('content' => TRUE)); - } - - /** - * Saves an existing flag to the database. Better use save(). - */ - function update() { - db_update('flag')->fields(array( - 'name' => $this->name, - 'title' => $this->title, - 'global' => $this->global, - 'options' => $this->get_serialized_options())) - ->condition('fid', $this->fid) - ->execute(); - db_delete('flag_types')->condition('fid', $this->fid)->execute(); - foreach ($this->types as $type) { - db_insert('flag_types')->fields(array( - 'fid' => $this->fid, - 'type' => $type)) - ->execute(); - } - } - - /** - * Saves a new flag to the database. Better use save(). - */ - function insert() { - $this->fid = db_insert('flag') - ->fields(array( - 'entity_type' => $this->entity_type, - 'name' => $this->name, - 'title' => $this->title, - 'global' => $this->global, - 'options' => $this->get_serialized_options(), - )) - ->execute(); - foreach ($this->types as $type) { - db_insert('flag_types') - ->fields(array( - 'fid' => $this->fid, - 'type' => $type, - )) - ->execute(); - } - } - - /** - * Options are stored serialized in the database. - */ - function get_serialized_options() { - $option_names = array_keys($this->options()); - $options = array(); - foreach ($option_names as $option) { - $options[$option] = $this->$option; - } - return serialize($options); - } - - /** - * Deletes a flag from the database. - */ - function delete() { - db_delete('flag')->condition('fid', $this->fid)->execute(); - db_delete('flagging')->condition('fid', $this->fid)->execute(); - db_delete('flag_types')->condition('fid', $this->fid)->execute(); - db_delete('flag_counts')->condition('fid', $this->fid)->execute(); - module_invoke_all('flag_delete', $this); - } - - /** - * Returns TRUE if this flag's declared API version is compatible with this - * module. - * - * An "incompatible" flag is one exported (and now being imported or exposed - * via hook_flag_default_flags()) by a different version of the Flag module. - * An incompatible flag should be treated as a "black box": it should not be - * saved or exported because our code may not know to handle its internal - * structure. - */ - function is_compatible() { - if (isset($this->fid)) { - // Database flags are always compatible. - return TRUE; - } - else { - if (!isset($this->api_version)) { - $this->api_version = 1; - } - return $this->api_version == FLAG_API_VERSION; - } - } - - /** - * Finds the "default flag" corresponding to this flag. - * - * Flags defined in code ("default flags") can be overridden. This method - * returns the default flag that is being overridden by $this. Returns NULL - * if $this overrides no default flag. - */ - function find_default_flag() { - if ($this->fid) { - $default_flags = flag_get_default_flags(TRUE); - if (isset($default_flags[$this->name])) { - return $default_flags[$this->name]; - } - } - } - - /** - * Reverts an overriding flag to its default state. - * - * Note that $this isn't altered. To see the reverted flag you'll have to - * call flag_get_flag($this->name) again. - * - * @return - * TRUE if the flag was reverted successfully; FALSE if there was an error; - * NULL if this flag overrides no default flag. - */ - function revert() { - if (($default_flag = $this->find_default_flag())) { - if ($default_flag->is_compatible()) { - $default_flag = clone $default_flag; - $default_flag->fid = $this->fid; - $default_flag->save(); - drupal_static_reset('flag_get_flags'); - return TRUE; - } - else { - return FALSE; - } - } - } - - /** - * Disable a flag provided by a module. - */ - function disable() { - if (isset($this->module)) { - $flag_status = variable_get('flag_default_flag_status', array()); - $flag_status[$this->name] = FALSE; - variable_set('flag_default_flag_status', $flag_status); - } - } - - /** - * Enable a flag provided by a module. - */ - function enable() { - if (isset($this->module)) { - $flag_status = variable_get('flag_default_flag_status', array()); - $flag_status[$this->name] = TRUE; - variable_set('flag_default_flag_status', $flag_status); - } - } - - /** - * Returns administrative menu path for carrying out some action. - */ - function admin_path($action) { - if ($action == 'edit') { - // Since 'edit' is the default tab, we omit the action. - return FLAG_ADMIN_PATH . '/manage/' . $this->name; - } - else { - return FLAG_ADMIN_PATH . '/manage/' . $this->name . '/' . $action; - } - } - - /** - * Renders a flag/unflag link. - * - * This is a wrapper around theme('flag') that channels the call to the right - * template file. - * - * @param $action - * The action the link is about to carry out, either "flag" or "unflag". - * @param $entity_id - * The ID of the object to flag. - * @param $variables = array() - * An array of further variables to pass to theme('flag'). For the full list - * of parameters, see flag.tpl.php. Of particular interest: - * - after_flagging: Set to TRUE if this flag link is being displayed as the result - * of a flagging action. - * - errors: An array of error messages. - * - * @return - * The HTML for the flag link. - */ - function theme($action, $entity_id, $variables = array()) { - static $js_added = array(); - global $user; - - $after_flagging = !empty($variables['after_flagging']); - - // If the flagging user is anonymous, set a boolean for the benefit of - // JavaScript code. Currently, only our "anti-crawlers" mechanism uses it. - if ($user->uid == 0 && !isset($js_added['anonymous'])) { - $js_added['anonymous'] = TRUE; - drupal_add_js(array('flag' => array('anonymous' => TRUE)), 'setting'); - } - - // If the flagging user is anonymous and the page cache is enabled, we - // update the links through JavaScript. - if ($this->uses_anonymous_cookies() && !$after_flagging) { - if ($this->global) { - // In case of global flags, the JavaScript template is to contain - // the opposite of the current state. - $js_action = ($action == 'flag' ? 'unflag' : 'flag'); - } - else { - // In case of non-global flags, we always show the "flag!" link, - // and then replace it with the "unflag!" link through JavaScript. - $js_action = 'unflag'; - $action = 'flag'; - } - if (!isset($js_added[$this->name . '_' . $entity_id])) { - $js_added[$this->name . '_' . $entity_id] = TRUE; - $js_template = theme($this->theme_suggestions(), array( - 'flag' => $this, - 'action' => $js_action, - 'entity_id' => $entity_id, - 'after_flagging' => $after_flagging, - )); - drupal_add_js(array('flag' => array('templates' => array($this->name . '_' . $entity_id => $js_template))), 'setting'); - } - } - - return theme($this->theme_suggestions(), array( - 'flag' => $this, - 'action' => $action, - 'entity_id' => $entity_id, - ) + $variables); - } - - /** - * Provides an array of possible themes to try for a given flag. - */ - function theme_suggestions() { - $suggestions = array(); - $suggestions[] = 'flag__' . $this->name; - $suggestions[] = 'flag__' . $this->link_type; - $suggestions[] = 'flag'; - return $suggestions; - } - - /** - * A shortcut function to output the link URL. - */ - function _flag_url($path, $fragment = NULL, $absolute = TRUE) { - return url($path, array('fragment' => $fragment, 'absolute' => $absolute)); - } -} diff --git a/lib/Drupal/flag/Handlers/BrokenFlag.php b/lib/Drupal/flag/Handlers/BrokenFlag.php deleted file mode 100644 index 0ea9d3e..0000000 --- a/lib/Drupal/flag/Handlers/BrokenFlag.php +++ /dev/null @@ -1,19 +0,0 @@ - $this->entity_type)), 'error'); - $form = array(); - } -} diff --git a/lib/Drupal/flag/Handlers/CommentFlag.php b/lib/Drupal/flag/Handlers/CommentFlag.php deleted file mode 100644 index a0148dd..0000000 --- a/lib/Drupal/flag/Handlers/CommentFlag.php +++ /dev/null @@ -1,103 +0,0 @@ - '', - ); - return $options; - } - - /** - * Options form extras for comment flags. - */ - function options_form(&$form) { - parent::options_form($form); - - $form['access']['access_author'] = array( - '#type' => 'radios', - '#title' => t('Flag access by content authorship'), - '#options' => array( - '' => t('No additional restrictions'), - 'comment_own' => t('Users may only flag own comments'), - 'comment_others' => t('Users may only flag comments by others'), - 'node_own' => t('Users may only flag comments of nodes they own'), - 'node_others' => t('Users may only flag comments of nodes by others'), - ), - '#default_value' => $this->access_author, - '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), - ); - } - - function type_access_multiple($entity_ids, $account) { - $access = array(); - - // If all subtypes are allowed, we have nothing to say here. - if (empty($this->types)) { - return $access; - } - - // Ensure node types are granted access. This avoids a - // node_load() on every type, usually done by applies_to_entity_id(). - $query = db_select('comment', 'c'); - $query->innerJoin('node', 'n', 'c.nid = n.nid'); - $result = $query - ->fields('c', array('cid')) - ->condition('c.cid', $entity_ids, 'IN') - ->condition('n.type', $this->types, 'NOT IN') - ->execute(); - foreach ($result as $row) { - $access[$row->nid] = FALSE; - } - - return $access; - } - - function get_entity_id($comment) { - // Store the comment object in the static cache, to avoid getting it - // again unneedlessly. - $this->remember_entity($comment->cid, $comment); - return $comment->cid; - } - - function get_labels_token_types() { - return array_merge(array('comment', 'node'), parent::get_labels_token_types()); - } - - function replace_tokens($label, $contexts, $options, $entity_id) { - if ($entity_id) { - if (($comment = $this->fetch_entity($entity_id)) && ($node = node_load($comment->nid))) { - $contexts['node'] = $node; - $contexts['comment'] = $comment; - } - } - return parent::replace_tokens($label, $contexts, $options, $entity_id); - } - - function get_flag_action($entity_id) { - $flag_action = parent::get_flag_action($entity_id); - $comment = $this->fetch_entity($entity_id); - $flag_action->content_title = $comment->subject; - $flag_action->content_url = $this->_flag_url("comment/$comment->cid", "comment-$comment->cid"); - return $flag_action; - } - - function get_relevant_action_objects($entity_id) { - $comment = $this->fetch_entity($entity_id); - return array( - 'comment' => $comment, - 'node' => node_load($comment->nid), - ); - } -} diff --git a/lib/Drupal/flag/Handlers/Flag.php b/lib/Drupal/flag/Handlers/Flag.php deleted file mode 100644 index f659049..0000000 --- a/lib/Drupal/flag/Handlers/Flag.php +++ /dev/null @@ -1,239 +0,0 @@ - array(), - // Output the flag as individual pseudofields. - 'show_as_field' => FALSE, - // Add a checkbox for the flag in the entity form. - // @see hook_field_attach_form(). - 'show_on_form' => FALSE, - 'access_author' => '', - 'show_contextual_link' => FALSE, - ); - return $options; - } - - /** - * Options form extras for the generic entity flag. - */ - function options_form(&$form) { - $bundles = array(); - $bundle_info = entity_get_bundles($this->entity_type); - foreach ($bundle_info as $bundle_key => $info) { - $bundles[$bundle_key] = $info['label']; - } - $form['access']['types'] = array( - '#type' => 'checkboxes', - '#title' => t('Bundles'), - '#options' => $bundles, - '#description' => t('Select the bundles that this flag may be used on. Leave blank to allow on all bundles for the entity type.'), - '#default_value' => $this->types, - ); - - // Add checkboxes to show flag link on each entity view mode. - $options = array(); - $defaults = array(); - $view_modes = entity_get_view_modes($this->entity_type); - foreach ($view_modes as $name => $view_mode) { - $options[$name] = t('Display on @name view mode', array('@name' => $view_mode['label'])); - $defaults[$name] = !empty($this->show_in_links[$name]) ? $name : 0; - } - - $form['display']['show_in_links'] = array( - '#type' => 'checkboxes', - '#title' => t('Display in entity links'), - '#description' => t('Show the flag link with the other links on the entity.'), - '#options' => $options, - '#default_value' => $defaults, - ); - - $form['display']['show_as_field'] = array( - '#type' => 'checkbox', - '#title' => t('Display link as field'), - '#description' => t('Show the flag link as a pseudofield, which can be ordered among other entity elements in the "Manage display" settings for the entity type.'), - '#default_value' => isset($this->show_as_field) ? $this->show_as_field : TRUE, - ); - if (empty($entity_info['fieldable'])) { - $form['display']['show_as_field']['#disabled'] = TRUE; - $form['display']['show_as_field']['#description'] = t("This entity type is not fieldable."); - } - - $form['display']['show_on_form'] = array( - '#type' => 'checkbox', - '#title' => t('Display checkbox on entity edit form'), - '#default_value' => $this->show_on_form, - '#weight' => 5, - ); - - // We use FieldAPI to put the flag checkbox on the entity form, so therefore - // require the entity to be fielable. Since this is a potential DX - // headscratcher for a developer wondering where this option has gone, - // we disable it and explain why. - if (empty($entity_info['fieldable'])) { - $form['display']['show_on_form']['#disabled'] = TRUE; - $form['display']['show_on_form']['#description'] = t('This is only possible on entities which are fieldable.'); - } - $form['display']['show_contextual_link'] = array( - '#type' => 'checkbox', - '#title' => t('Display in contextual links'), - '#default_value' => $this->show_contextual_link, - '#description' => t('Note that not all entity types support contextual links.'), - '#access' => module_exists('contextual'), - '#weight' => 10, - ); - } - - /** - * Loads the entity object. - */ - function _load_entity($entity_id) { - if (is_numeric($entity_id)) { - $entity = entity_load($this->entity_type, array($entity_id)); - return reset($entity); - } - return NULL; - } - - /** - * Checks whether the flag applies for the current entity bundle. - */ - function applies_to_entity($entity) { - $entity_info = entity_get_info($this->entity_type); - // The following conditions are applied: - // - if the types array is empty, the flag applies to all bundles and thus - // to this entity. - // - if the entity has no bundles, the flag applies to the entity. - // - if the entity's bundle is in the list of types. - if (empty($this->types) || empty($entity_info['entity keys']['bundle']) || in_array($entity->{$entity_info['entity keys']['bundle']}, $this->types)) { - return TRUE; - } - return FALSE; - } - - /** - * Provides permissions for this flag. - * - * @return - * An array of permissions for hook_permission(). - */ - function get_permissions() { - // For entity flags, use the human label of the entity. - $entity_info = entity_get_info($this->entity_type); - $entity_label = $entity_info['label']; - return array( - "flag $this->name" => array( - 'title' => t('Flag %entity entities as %flag_title', array( - '%flag_title' => $this->title, - '%entity' => $entity_label, - )), - ), - "unflag $this->name" => array( - 'title' => t('Unflag %entity entities as %flag_title', array( - '%flag_title' => $this->title, - '%entity' => $entity_label, - )), - ), - ); - } - - /** - * Returns the entity id, if it already exists. - */ - function get_entity_id($entity) { - $entity_info = entity_get_info($this->entity_type); - if ($entity && isset($entity->{$entity_info['entity keys']['id']})) { - return $entity->{$entity_info['entity keys']['id']}; - } - } - - /** - * Determine whether the flag should show a flag link in entity links. - */ - function shows_in_entity_links($view_mode) { - // Check for settings for the given view mode. - if (isset($this->show_in_links[$view_mode])) { - return (bool) $this->show_in_links[$view_mode]; - } - return FALSE; - } - - /** - * Returns token types for the current entity type. - */ - function get_labels_token_types() { - // The token type name might be different to the entity type name. If so, - // an own flag entity handler can be used for overriding this. - return array_merge(array($this->entity_type), parent::get_labels_token_types()); - } - - /** - * Replaces tokens. - */ - function replace_tokens($label, $contexts, $options, $entity_id) { - if ($entity_id && ($entity = $this->fetch_entity($entity_id))) { - $contexts[$this->entity_type] = $entity; - } - return parent::replace_tokens($label, $contexts, $options, $entity_id); - } - - /** - * Returns a 'flag action' object. - */ - function get_flag_action($entity_id) { - $flag_action = parent::get_flag_action($entity_id); - $entity = $this->fetch_entity($entity_id); - $flag_action->content_title = entity_label($this->entity_type, $entity); - $flag_action->content_url = $this->_flag_url($this->entity_type . '/' . $this->get_entity_id($entity)); - return $flag_action; - } - - /** - * Returns objects the action may possible need. - */ - function get_relevant_action_objects($entity_id) { - return array( - $this->entity_type => $this->fetch_entity($entity_id), - ); - } - - /** - * Returns information for the Views integration. - */ - function get_views_info() { - $entity_info = entity_get_info($this->entity_type); - - if (!isset($entity_info['base table'])) { - return NULL; - } - - return array( - 'views table' => $entity_info['base table'], - 'join field' => $entity_info['entity keys']['id'], - 'title field' => isset($entity_info['entity keys']['label']) ? $entity_info['entity keys']['label'] : '', - 'title' => t('@entity_label flag', array('@entity_label' => $entity_info['label'])), - 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), - 'counter title' => t('@entity_label flag counter', array('@entity_label' => $entity_info['label'])), - 'counter help' => t('Include this to gain access to the flag counter field.'), - ); - } -} diff --git a/lib/Drupal/flag/Handlers/NodeFlag.php b/lib/Drupal/flag/Handlers/NodeFlag.php deleted file mode 100644 index 18a5b7f..0000000 --- a/lib/Drupal/flag/Handlers/NodeFlag.php +++ /dev/null @@ -1,122 +0,0 @@ - 0, - ); - return $options; - } - - /** - * Options form extras for node flags. - */ - function options_form(&$form) { - parent::options_form($form); - - $form['access']['access_author'] = array( - '#type' => 'radios', - '#title' => t('Flag access by content authorship'), - '#options' => array( - '' => t('No additional restrictions'), - 'own' => t('Users may only flag content they own'), - 'others' => t('Users may only flag content of others'), - ), - '#default_value' => $this->access_author, - '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), - ); - - // Support for i18n flagging requires Translation helpers module. - $form['i18n'] = array( - '#type' => 'radios', - '#title' => t('Internationalization'), - '#options' => array( - '1' => t('Flag translations of content as a group'), - '0' => t('Flag each translation of content separately'), - ), - '#default_value' => $this->i18n, - '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), - '#access' => module_exists('translation_helpers'), - '#weight' => 5, - ); - - // Override the UI texts for nodes. - $form['display']['show_on_form'] = array( - '#title' => t('Display checkbox on node edit form'), - '#description' => t('If you elect to have a checkbox on the node edit form, you may specify its initial state in the settings form for each content type.', array('@content-types-url' => url('admin/structure/types'))), - ) + $form['display']['show_on_form']; - } - - function type_access_multiple($entity_ids, $account) { - $access = array(); - - // If all subtypes are allowed, we have nothing to say here. - if (empty($this->types)) { - return $access; - } - - // Ensure that only flaggable node types are granted access. This avoids a - // node_load() on every type, usually done by applies_to_entity_id(). - $result = db_select('node', 'n')->fields('n', array('nid')) - ->condition('nid', array_keys($entity_ids), 'IN') - ->condition('type', $this->types, 'NOT IN') - ->execute(); - foreach ($result as $row) { - $access[$row->nid] = FALSE; - } - - return $access; - } - - /** - * Adjust the Content ID to find the translation parent if i18n-enabled. - * - * @param $entity_id - * The nid for the content. - * @return - * The tnid if available, the nid otherwise. - */ - function get_translation_id($entity_id) { - if ($this->i18n) { - $node = $this->fetch_entity($entity_id); - if (!empty($node->tnid)) { - $entity_id = $node->tnid; - } - } - return $entity_id; - } - - function flag($action, $entity_id, $account = NULL, $skip_permission_check = FALSE, $flagging = NULL) { - $entity_id = $this->get_translation_id($entity_id); - return parent::flag($action, $entity_id, $account, $skip_permission_check, $flagging); - } - - // Instead of overriding is_flagged() we override get_flagging_record(), - // which is the underlying method. - function get_flagging_record($entity_id, $uid = NULL, $sid = NULL) { - $entity_id = $this->get_translation_id($entity_id); - return parent::get_flagging_record($entity_id, $uid, $sid); - } - - /** - * This is overridden for no other purpose than to document that $entity_id - * can be one of the following fake IDs in certain contexts: - * - 'new': On a new node form. - * - 'fake': On the node type admin form. - */ - function replace_tokens($label, $contexts, $options, $entity_id) { - return parent::replace_tokens($label, $contexts, $options, $entity_id); - } -} diff --git a/lib/Drupal/flag/Handlers/UserFlag.php b/lib/Drupal/flag/Handlers/UserFlag.php deleted file mode 100644 index e009c5c..0000000 --- a/lib/Drupal/flag/Handlers/UserFlag.php +++ /dev/null @@ -1,99 +0,0 @@ - TRUE, - 'access_uid' => '', - ); - return $options; - } - - /** - * Options form extras for user flags. - */ - function options_form(&$form) { - parent::options_form($form); - $form['access']['types'] = array( - // A user flag doesn't support node types. - // TODO: Maybe support roles instead of node types. - '#type' => 'value', - '#value' => array(0 => 0), - ); - $form['access']['access_uid'] = array( - '#type' => 'checkbox', - '#title' => t('Users may flag themselves'), - '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themself does not make sense.'), - '#default_value' => $this->access_uid ? 0 : 1, - ); - $form['display']['show_on_profile'] = array( - '#type' => 'checkbox', - '#title' => t('Display link on user profile page'), - '#description' => t('Show the link formatted as a user profile element.'), - '#default_value' => $this->show_on_profile, - // Put this above 'show on entity'. - '#weight' => -1, - ); - } - - function form_input($form_values) { - parent::form_input($form_values); - // The access_uid value is intentionally backwards from the UI, to avoid - // confusion caused by checking a box to disable a feature. - $this->access_uid = empty($form_values['access_uid']) ? 'others' : ''; - } - - function type_access($entity_id, $action, $account) { - // Prevent users from flagging themselves. - if ($this->access_uid == 'others' && $entity_id == $account->uid) { - return FALSE; - } - } - - function type_access_multiple($entity_ids, $account) { - $access = array(); - - // Exclude anonymous. - if (array_key_exists(0, $entity_ids)) { - $access[0] = FALSE; - } - - // Prevent users from flagging themselves. - if ($this->access_uid == 'others' && array_key_exists($account->uid, $entity_ids)) { - $access[$account->uid] = FALSE; - } - - return $access; - } - - function get_flag_action($entity_id) { - $flag_action = parent::get_flag_action($entity_id); - $user = $this->fetch_entity($entity_id); - $flag_action->content_title = $user->name; - $flag_action->content_url = $this->_flag_url('user/' . $user->uid); - return $flag_action; - } - - function get_relevant_action_objects($entity_id) { - return array( - 'user' => $this->fetch_entity($entity_id), - ); - } - - function get_views_info() { - $views_info = parent::get_views_info(); - $views_info['title field'] = 'name'; - return $views_info; - } -} From d2c20a676828b68a2216ee8fb0c526b87ec3c789 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 10 Apr 2014 22:44:39 -0500 Subject: [PATCH 380/629] Refinded ConfirmForm action link plugin to work more like Reload. --- flag.routing.yml | 15 +++++++- lib/Drupal/flag/Form/FlagFormBase.php | 4 +- lib/Drupal/flag/Form/FlaggingConfirmForm.php | 37 ++++++++++++++----- .../flag/Plugin/ActionLink/ConfirmForm.php | 8 +++- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index 7b780dd..7d13611 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -68,8 +68,19 @@ flag_link_unflag: requirements: _entity_access: flagging.delete -flag_confirm_form: - path: '/flag/confirm/{action}/{flag_id}/{entity_id}' +flag_confirm_flag: + path: '/flag/confirm/flag/{flag_id}/{entity_id}' defaults: _form: '\Drupal\flag\Form\FlaggingConfirmForm' _title: 'Flag Content' + requirements: + _entity_create_access: flagging + +flag_confirm_unflag: + path: '/flag/confirm/unflag/{flag_id}/{entity_id}' + defaults: + _form: '\Drupal\flag\Form\FlaggingConfirmForm' + _title: 'Flag Content' + requirements: + _entity_access: flagging.delete + diff --git a/lib/Drupal/flag/Form/FlagFormBase.php b/lib/Drupal/flag/Form/FlagFormBase.php index 433869f..257a692 100644 --- a/lib/Drupal/flag/Form/FlagFormBase.php +++ b/lib/Drupal/flag/Form/FlagFormBase.php @@ -190,10 +190,10 @@ public function validate(array $form, array &$form_state) { if ($form_values['link_type'] == 'confirm') { if (empty($form_values['flag_confirmation'])) { - form_set_error('flag_confirmation', t('A flag confirmation message is required when using the confirmation link type.')); + form_set_error('flag_confirmation', array(t('A flag confirmation message is required when using the confirmation link type.'))); } if (empty($form_values['unflag_confirmation'])) { - form_set_error('unflag_confirmation', t('An unflag confirmation message is required when using the confirmation link type.')); + form_set_error('unflag_confirmation', array(t('An unflag confirmation message is required when using the confirmation link type.'))); } } /* diff --git a/lib/Drupal/flag/Form/FlaggingConfirmForm.php b/lib/Drupal/flag/Form/FlaggingConfirmForm.php index 11e8d59..8d212d4 100644 --- a/lib/Drupal/flag/Form/FlaggingConfirmForm.php +++ b/lib/Drupal/flag/Form/FlaggingConfirmForm.php @@ -9,23 +9,20 @@ namespace Drupal\flag\Form; use Drupal\Core\Form\ConfirmFormBase; -use Drupal\Core\EntityInterface; +use Drupal\Core\Entity\EntityInterface; use Drupal\flag\FlagInterface; class FlaggingConfirmForm extends ConfirmFormBase { - protected $action; - protected $entity; protected $flag; - // @todo add parameters for the entity, flag public function buildForm(array $form, array &$form_state, - $action, FlagInterface $flag, EntityInterface $entity) { + FlagInterface $flag = NULL, + EntityInterface $entity = NULL) { - $this->action = $action; $this->flag = $flag; $this->entity = $entity; } @@ -37,7 +34,7 @@ public function getFormID() { public function getQuestion() { $linkType = $this->flag->getLinkTypePlugin(); - if ($action == 'unflag') { + if (!$this->isFlagged()) { return $linkType->getUnflagQuestion(); } else { @@ -47,19 +44,41 @@ public function getQuestion() { } public function getCancelRoute() { +/* $destination = \Drupal::request()->get('destination'); + if (!empty($destination)) { + return new URL($destination); + } +*/ return $this->entity->urlInfo(); } public function getDescription() { - return $this->t(''); + if (!$this->isFlagged()) { + return $this->flag->unflag_long; + } + + return $this->flag->flag_long; } public function getConfirmText() { + if (!$this->isFlagged()) { + return $this->t('Unflag'); + } + return $this->t('Flag'); } - public function submitForm(array &$form, array &$form_state) { + protected function isFlagged() { + return $this->flag->isFlagged($this->entity); + } + public function submitForm(array &$form, array &$form_state) { + if ($this->isFlagged()) { + \Drupal::service('flag')->unflagByObject($this->flag, $this->entity); + } + else { + \Drupal::service('flag')->flagByObject($this->flag, $this->entity); + } } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php b/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php index c2ff2e9..6b46b88 100644 --- a/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php +++ b/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php @@ -22,8 +22,12 @@ */ class ConfirmForm extends ActionLinkTypeBase { - public function routeName() { - return 'flag_confirm_form'; + public function routeName($action = NULL) { + if ($action == 'unflag') { + return 'flag_confirm_unflag'; + } + + return 'flag_confirm_flag'; } public function defaultConfiguration() { From f9d2c3a83c1ac5c0ca359b3b5134257124b412d1 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 11 Apr 2014 21:34:34 -0500 Subject: [PATCH 381/629] Working flagging confirm form. --- lib/Drupal/flag/Form/FlaggingConfirmForm.php | 21 ++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/Drupal/flag/Form/FlaggingConfirmForm.php b/lib/Drupal/flag/Form/FlaggingConfirmForm.php index 8d212d4..6965763 100644 --- a/lib/Drupal/flag/Form/FlaggingConfirmForm.php +++ b/lib/Drupal/flag/Form/FlaggingConfirmForm.php @@ -20,11 +20,12 @@ class FlaggingConfirmForm extends ConfirmFormBase { protected $flag; public function buildForm(array $form, array &$form_state, - FlagInterface $flag = NULL, - EntityInterface $entity = NULL) { + $flag_id = NULL, $entity_id = NULL) { - $this->flag = $flag; - $this->entity = $entity; + $flagService = \Drupal::service('flag'); + $this->flag = $flagService->getFlagByID($flag_id); + $this->entity = $flagService->getFlaggableById($this->flag, $entity_id); + return parent::buildForm($form, $form_state); } public function getFormID() { @@ -34,7 +35,7 @@ public function getFormID() { public function getQuestion() { $linkType = $this->flag->getLinkTypePlugin(); - if (!$this->isFlagged()) { + if ($this->isFlagged()) { return $linkType->getUnflagQuestion(); } else { @@ -44,16 +45,16 @@ public function getQuestion() { } public function getCancelRoute() { -/* $destination = \Drupal::request()->get('destination'); + $destination = \Drupal::request()->get('destination'); if (!empty($destination)) { - return new URL($destination); + return URL::createFromPath($destination); } -*/ + return $this->entity->urlInfo(); } public function getDescription() { - if (!$this->isFlagged()) { + if ($this->isFlagged()) { return $this->flag->unflag_long; } @@ -61,7 +62,7 @@ public function getDescription() { } public function getConfirmText() { - if (!$this->isFlagged()) { + if ($this->isFlagged()) { return $this->t('Unflag'); } From 52b0cad10dc4b809188b507759d92b54f86ccc95 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 13 Apr 2014 00:03:11 -0500 Subject: [PATCH 382/629] Working AJAX link. --- lib/Drupal/flag/ActionLinkTypeBase.php | 1 + .../flag/Controller/ReloadLinkController.php | 24 ++++++++++++++--- lib/Drupal/flag/Entity/Flagging.php | 6 ++++- .../flag/Plugin/ActionLink/AJAXactionLink.php | 27 +++++++++++++++++++ 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/lib/Drupal/flag/ActionLinkTypeBase.php index 82ac259..fa32b2f 100644 --- a/lib/Drupal/flag/ActionLinkTypeBase.php +++ b/lib/Drupal/flag/ActionLinkTypeBase.php @@ -62,6 +62,7 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity $render = $url->toRenderArray(); $render['#type'] = 'link'; + $render['#attributes']['id'] = 'flag-' . $flag->id() . '-id-' . $entity->id(); //@todo check if flagged, assign flag or unflag text. if ($action === 'unflag') { diff --git a/lib/Drupal/flag/Controller/ReloadLinkController.php b/lib/Drupal/flag/Controller/ReloadLinkController.php index 9928005..9ab05fb 100644 --- a/lib/Drupal/flag/Controller/ReloadLinkController.php +++ b/lib/Drupal/flag/Controller/ReloadLinkController.php @@ -11,23 +11,39 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\flag\FlagInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Ajax\AjaxResponse; +use Drupal\Core\Ajax\ReplaceCommand; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; class ReloadLinkController extends ControllerBase { - public function flag($flag_id, $entity_id) { + public function flag(Request $request, $flag_id, $entity_id) { $flagging = \Drupal::service('flag')->flag($flag_id, $entity_id); + // If the response is coming from JavaScript, we can't return a redirect. + // Instead, we replace the flag link with an unflag link via JSON. + if ($request->request->get('js')) { + $response = new AjaxResponse(); + $linkType = $flagging->getFlag()->getLinkTypePlugin(); + $link = $linkType->renderLink('unflag', $flagging->getFlag(), $flagging->getFlaggable()); + $linkId = '#' . $link['#attributes']['id']; + $html = drupal_render($link); + $replace = new ReplaceCommand($linkId, $html); + $response->addCommand($replace); + + return $response; + } + // Get the destination. - $destination = \Drupal::request()->get('destination', - $flagging->getFlaggable()->url()); + $destination = $request->get('destination', $flagging->getFlaggable()->url()); //@todo SECURITY HOLE. Please fix! return new RedirectResponse($destination); } - public function unflag($flag_id, $entity_id) { + public function unflag(Request $request, $flag_id, $entity_id) { // Get the Flag Service. $flagService = \Drupal::service('flag'); diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index b1d37ad..6e4fdb2 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -44,8 +44,12 @@ */ class Flagging extends ContentEntityBase implements FlaggingInterface { + public function getFlagId() { + return $this->get('fid')->value; + } + public function getFlag() { - return $this->bundle; + return entity_load($this->bundle, $this->getFlagId()); } public function getFlaggableType() { diff --git a/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php b/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php new file mode 100644 index 0000000..b3c8fd1 --- /dev/null +++ b/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php @@ -0,0 +1,27 @@ + Date: Tue, 15 Apr 2014 23:39:18 -0500 Subject: [PATCH 383/629] Converted FlaggingAccessController to a custom controller. Separated Reload and AJAX controllers. --- flag.module | 2 +- flag.routing.yml | 27 ++++++- .../flag/Controller/AJAXLinkController.php | 73 +++++++++++++++++++ .../flag/Controller/ReloadLinkController.php | 22 +----- lib/Drupal/flag/FlaggingAccessController.php | 47 +++++------- .../flag/Plugin/ActionLink/AJAXactionLink.php | 12 ++- 6 files changed, 126 insertions(+), 57 deletions(-) create mode 100644 lib/Drupal/flag/Controller/AJAXLinkController.php diff --git a/flag.module b/flag.module index ed42a9e..4e823d2 100644 --- a/flag.module +++ b/flag.module @@ -701,7 +701,7 @@ function flag_entity_delete($entity, $type) { return; } - _flag_entity_delete($entity->getFlaggableEntityType(), $entity->id()); +// _flag_entity_delete($entity->getFlaggableEntityType(), $entity->id()); } /** diff --git a/flag.routing.yml b/flag.routing.yml index 7d13611..a007500 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -59,14 +59,32 @@ flag_link_flag: defaults: _controller: '\Drupal\flag\Controller\ReloadLinkController::flag' requirements: - _entity_create_access: flagging + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + _format: 'html' + +flag.link_flag.json: + path: '/flag/flag/{flag_id}/{entity_id}' + defaults: + _controller: '\Drupal\flag\Controller\AJAXLinkController::flag' + requirements: + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + _format: 'json' flag_link_unflag: path: '/flag/unflag/{flag_id}/{entity_id}' defaults: _controller: '\Drupal\flag\Controller\ReloadLinkController::unflag' requirements: - _entity_access: flagging.delete + _custom_access: '\Drupal\flag\FlaggingAccessController::checkUnflag' + _format: 'html' + +flag.link_unflag.json: + path: '/flag/unflag/{flag_id}/{entity_id}' + defaults: + _controller: '\Drupal\flag\Controller\AJAXLinkController::unflag' + requirements: + _custom_access: '\Drupal\flag\FlaggingAccessController::checkUnflag' + _format: 'json' flag_confirm_flag: path: '/flag/confirm/flag/{flag_id}/{entity_id}' @@ -74,7 +92,7 @@ flag_confirm_flag: _form: '\Drupal\flag\Form\FlaggingConfirmForm' _title: 'Flag Content' requirements: - _entity_create_access: flagging + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' flag_confirm_unflag: path: '/flag/confirm/unflag/{flag_id}/{entity_id}' @@ -82,5 +100,6 @@ flag_confirm_unflag: _form: '\Drupal\flag\Form\FlaggingConfirmForm' _title: 'Flag Content' requirements: - _entity_access: flagging.delete + _custom_access: '\Drupal\flag\FlaggingAccessController::checkUnflag' + diff --git a/lib/Drupal/flag/Controller/AJAXLinkController.php b/lib/Drupal/flag/Controller/AJAXLinkController.php new file mode 100644 index 0000000..8f99d53 --- /dev/null +++ b/lib/Drupal/flag/Controller/AJAXLinkController.php @@ -0,0 +1,73 @@ +flag($flag_id, $entity_id); + + $flag = $flagging->getFlag(); + $entity = $flagging->getFlaggable(); + + return $this->generateResponse('unflag', $flag, $entity); + } + + /** + * @param $flag_id + * @param $entity_id + * @return AjaxResponse + */ + public function unflag($flag_id, $entity_id) { + $flagService = \Drupal::service('flag'); + $flagService->unflag($flag_id, $entity_id); + + $flag = $flagService->getFlagById($flag_id); + $entity = $flagService->getFlaggableById($flag, $entity_id); + + return $this->generateResponse('flag', $flag, $entity); + } + + /** + * @param $action + * @param FlagInterface $flag + * @param EntityInterface $entity + * @return AjaxResponse + */ + protected function generateResponse($action, FlagInterface $flag, EntityInterface $entity) { + // Create a new AJAX response. + $response = new AjaxResponse(); + + // Get the link type plugin. + $linkType = $flag->getLinkTypePlugin(); + + // Generate the link render array and get the link CSS ID. + $link = $linkType->renderLink($action, $flag, $entity); + $linkId = '#' . $link['#attributes']['id']; + + // Create a new JQuery Replace command to update the link display. + $replace = new ReplaceCommand($linkId, drupal_render($link)); + $response->addCommand($replace); + + return $response; + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Controller/ReloadLinkController.php b/lib/Drupal/flag/Controller/ReloadLinkController.php index 9ab05fb..b4dc711 100644 --- a/lib/Drupal/flag/Controller/ReloadLinkController.php +++ b/lib/Drupal/flag/Controller/ReloadLinkController.php @@ -22,20 +22,6 @@ public function flag(Request $request, $flag_id, $entity_id) { $flagging = \Drupal::service('flag')->flag($flag_id, $entity_id); - // If the response is coming from JavaScript, we can't return a redirect. - // Instead, we replace the flag link with an unflag link via JSON. - if ($request->request->get('js')) { - $response = new AjaxResponse(); - $linkType = $flagging->getFlag()->getLinkTypePlugin(); - $link = $linkType->renderLink('unflag', $flagging->getFlag(), $flagging->getFlaggable()); - $linkId = '#' . $link['#attributes']['id']; - $html = drupal_render($link); - $replace = new ReplaceCommand($linkId, $html); - $response->addCommand($replace); - - return $response; - } - // Get the destination. $destination = $request->get('destination', $flagging->getFlaggable()->url()); @@ -44,18 +30,12 @@ public function flag(Request $request, $flag_id, $entity_id) { } public function unflag(Request $request, $flag_id, $entity_id) { - // Get the Flag Service. $flagService = \Drupal::service('flag'); + $flagService->unflag($flag_id, $entity_id); - // Get the Flag and Entity objects. $flag = $flagService->getFlagById($flag_id); $entity = $flagService->getFlaggableById($flag, $entity_id); - $flaggings = \Drupal::service('flag')->getFlaggings($entity, $flag); - foreach ($flaggings as $flagging) { - \Drupal::service('flag')->unflagByObject($flagging); - } - $destination = \Drupal::request()->get('destination', $entity->url()); //@todo SECURITY HOLE. Please fix! diff --git a/lib/Drupal/flag/FlaggingAccessController.php b/lib/Drupal/flag/FlaggingAccessController.php index 906b0f8..e2c0ce1 100644 --- a/lib/Drupal/flag/FlaggingAccessController.php +++ b/lib/Drupal/flag/FlaggingAccessController.php @@ -8,48 +8,37 @@ namespace Drupal\flag; +use Drupal\Core\Access\AccessInterface; +use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Entity\EntityAccessController; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; +use Symfony\Component\HttpFoundation\Request; -class FlaggingAccessController extends EntityAccessController { - protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) { - if ($account->id() == 1) { - return TRUE; - } - - switch ($operation) { - case 'view': - case 'flag': - return user_access('flag ' . $entity->id(), $account); - break; - - case 'delete': - case 'unflag': - return user_access('unflag' . $entity->id(), $account); - break; - } +class FlaggingAccessController extends ControllerBase { - return parent::checkAccess($entity, $operation, $langcode, $account); - } + public function checkFlag(Request $request) { + $entity_id = $request->get('entity_id'); - protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { - if ($account->id() == 1) { - return TRUE; + if (user_access('flag' . $entity_id)) { + return AccessInterface::ALLOW; } - //@todo Figure out how to handle the NULL $entity_bundle case. - return user_access('flag ' . $entity_bundle, $account); + return AccessInterface::DENY; } - public function getRoles() { - $roles = array(); + /** + * + */ + public function checkUnflag(Request $request) { + $entity_id = $request->get('entity_id'); - $roles['flag'] = user_roles(FALSE, 'flag ' . $this->entityTypeId); - $roles['unflag'] = user_roles(FALSE, 'unflag ' . $this->entityTypeId); + if (user_access('unflag' . $entity_id)) { + return AccessInterface::ALLOW; + } - return $roles; + return AccessInterface::DENY; } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php b/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php index b3c8fd1..933b0c0 100644 --- a/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php +++ b/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php @@ -2,7 +2,7 @@ namespace Drupal\flag\Plugin\ActionLink; -use Drupal\flag\Plugin\ActionLink\Reload; +use Drupal\flag\ActionLinkTypeBase; use Drupal\Core\Entity\EntityInterface; use Drupal\flag\FlagInterface; @@ -15,7 +15,15 @@ * description = "An AJAX JavaScript request will be made without reloading the page." * ) */ -class AJAXactionLink extends Reload{ +class AJAXactionLink extends ActionLinkTypeBase{ + + public function routeName($action = NULL) { + if ($action === 'unflag') { + return 'flag.link_unflag.json'; + } + + return 'flag.link_flag.json'; + } public function renderLink($action, FlagInterface $flag, EntityInterface $entity) { $render = parent::renderLink($action, $flag, $entity); From a6a3859ecd2afe52224981cd96af492ced37b6b2 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 25 Apr 2014 19:24:26 -0500 Subject: [PATCH 384/629] Renamed most routes to start with flag.* --- flag.local_actions.yml | 4 ++-- flag.menu_links.yml | 2 +- flag.routing.yml | 22 +++++++++---------- lib/Drupal/flag/Entity/Flag.php | 4 ++-- lib/Drupal/flag/Entity/Flagging.php | 2 +- lib/Drupal/flag/Form/FlagDeleteForm.php | 4 ++-- .../flag/Plugin/ActionLink/ConfirmForm.php | 4 ++-- lib/Drupal/flag/Plugin/ActionLink/Reload.php | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/flag.local_actions.yml b/flag.local_actions.yml index 9b9f593..ea4e830 100644 --- a/flag.local_actions.yml +++ b/flag.local_actions.yml @@ -1,5 +1,5 @@ flag_add_page_action: - route_name: flag_add_page + route_name: flag.add_page title: 'Add New Flag' appears_on: - - flag_list \ No newline at end of file + - flag.list \ No newline at end of file diff --git a/flag.menu_links.yml b/flag.menu_links.yml index 4e8a2c7..e4282e8 100644 --- a/flag.menu_links.yml +++ b/flag.menu_links.yml @@ -2,4 +2,4 @@ flag.admin.structure.flag: title: 'Flags' description: 'Configure flags for marking content with arbitrary information (such as offensive or bookmarked).' parent: system.admin_structure - route_name: flag_list \ No newline at end of file + route_name: flag.list \ No newline at end of file diff --git a/flag.routing.yml b/flag.routing.yml index a007500..01c585c 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -1,4 +1,4 @@ -flag_add_page: +flag.add_page: path: '/admin/structure/flags/add' defaults: _form: '\Drupal\flag\Form\FlagAddPageForm' @@ -6,7 +6,7 @@ flag_add_page: requirements: _permission: 'administer flags' -flag_list: +flag.list: path: '/admin/structure/flags' defaults: _entity_list: 'flag_flag' @@ -14,7 +14,7 @@ flag_list: requirements: _permission: 'administer flags' -flag_add: +flag.add: path: '/admin/structure/flags/add/{entity_type}' defaults: _entity_form: flag_flag.add @@ -22,7 +22,7 @@ flag_add: requirements: _permission: 'administer flags' -flag_edit: +flag.edit: path: '/admin/structure/flags/manage/{flag_flag}' defaults: _entity_form: flag_flag.edit @@ -30,7 +30,7 @@ flag_edit: requirements: _entity_access: 'flag_flag.update' -flag_delete: +flag.delete: path: '/admin/structure/flags/manage/{flag_flag}/delete' defaults: _entity_form: flag_flag.delete @@ -38,7 +38,7 @@ flag_delete: requirements: _entity_access: 'flag_flag.update' -flag_import: +flag.import: path: '/admin/structure/flags/import' defaults: _form: '\Drupal\flag\Form\FlagImportForm' @@ -46,7 +46,7 @@ flag_import: requirements: _permission: 'use flag import' -flag_export: +flag.export: path: '/admin/structure/flags/export' defaults: _form: '\Drupal\flag\Form\FlagExportForm' @@ -54,7 +54,7 @@ flag_export: requirements: _permission: 'use flag import' -flag_link_flag: +flag_link_flag.html: path: '/flag/flag/{flag_id}/{entity_id}' defaults: _controller: '\Drupal\flag\Controller\ReloadLinkController::flag' @@ -70,7 +70,7 @@ flag.link_flag.json: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' _format: 'json' -flag_link_unflag: +flag_link_unflag.html: path: '/flag/unflag/{flag_id}/{entity_id}' defaults: _controller: '\Drupal\flag\Controller\ReloadLinkController::unflag' @@ -86,7 +86,7 @@ flag.link_unflag.json: _custom_access: '\Drupal\flag\FlaggingAccessController::checkUnflag' _format: 'json' -flag_confirm_flag: +flag.confirm_flag: path: '/flag/confirm/flag/{flag_id}/{entity_id}' defaults: _form: '\Drupal\flag\Form\FlaggingConfirmForm' @@ -94,7 +94,7 @@ flag_confirm_flag: requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' -flag_confirm_unflag: +flag.confirm_unflag: path: '/flag/confirm/unflag/{flag_id}/{entity_id}' defaults: _form: '\Drupal\flag\Form\FlaggingConfirmForm' diff --git a/lib/Drupal/flag/Entity/Flag.php b/lib/Drupal/flag/Entity/Flag.php index 6c74265..ea87af2 100644 --- a/lib/Drupal/flag/Entity/Flag.php +++ b/lib/Drupal/flag/Entity/Flag.php @@ -40,8 +40,8 @@ * "label" = "label", * }, * links = { - * "edit-form" = "flag_edit", - * "delete-form" = "flag_delete" + * "edit-form" = "flag.edit", + * "delete-form" = "flag.delete" * } * ) * diff --git a/lib/Drupal/flag/Entity/Flagging.php b/lib/Drupal/flag/Entity/Flagging.php index 6e4fdb2..4147d38 100644 --- a/lib/Drupal/flag/Entity/Flagging.php +++ b/lib/Drupal/flag/Entity/Flagging.php @@ -38,7 +38,7 @@ * "bundle" = "type" * }, * links = { - * "admin-form" = "flag_edit" + * "admin-form" = "flag.edit" * } * ) */ diff --git a/lib/Drupal/flag/Form/FlagDeleteForm.php b/lib/Drupal/flag/Form/FlagDeleteForm.php index 02cb518..fb74c8b 100644 --- a/lib/Drupal/flag/Form/FlagDeleteForm.php +++ b/lib/Drupal/flag/Form/FlagDeleteForm.php @@ -24,7 +24,7 @@ public function getConfirmText() { public function getCancelRoute() { return array( - 'route_name' => 'flag_list', + 'route_name' => 'flag.list', ); } @@ -34,7 +34,7 @@ public function submit(array $form, array &$form_state) { '%label' => $this->entity->label(), ))); - $form_state['redirect_route']['route_name'] = 'flag_list'; + $form_state['redirect_route']['route_name'] = 'flag.list'; } } \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php b/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php index 6b46b88..e92986a 100644 --- a/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php +++ b/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php @@ -24,10 +24,10 @@ class ConfirmForm extends ActionLinkTypeBase { public function routeName($action = NULL) { if ($action == 'unflag') { - return 'flag_confirm_unflag'; + return 'flag.confirm_unflag'; } - return 'flag_confirm_flag'; + return 'flag.confirm_flag'; } public function defaultConfiguration() { diff --git a/lib/Drupal/flag/Plugin/ActionLink/Reload.php b/lib/Drupal/flag/Plugin/ActionLink/Reload.php index 8683e90..69d0de1 100644 --- a/lib/Drupal/flag/Plugin/ActionLink/Reload.php +++ b/lib/Drupal/flag/Plugin/ActionLink/Reload.php @@ -26,10 +26,10 @@ class Reload extends ActionLinkTypeBase { */ public function routeName($action = NULL) { if ($action === 'unflag') { - return 'flag_link_unflag'; + return 'flag_link_unflag.html'; } - return 'flag_link_flag'; + return 'flag_link_flag.html'; } } \ No newline at end of file From 204b4b219e6d307bd663eef3f82fa5571d09fd80 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 25 Apr 2014 22:00:22 -0500 Subject: [PATCH 385/629] Changes due to https://drupal.org/node/2218341 and https://drupal.org/node/2200867 --- lib/Drupal/flag/ActionLinkTypeBase.php | 7 +++++++ lib/Drupal/flag/FlagTypeBase.php | 7 +++++++ lib/Drupal/flag/Form/FlagFormBase.php | 4 ++-- lib/Drupal/flag/Plugin/Flag/EntityFlagType.php | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/lib/Drupal/flag/ActionLinkTypeBase.php index fa32b2f..55ff42a 100644 --- a/lib/Drupal/flag/ActionLinkTypeBase.php +++ b/lib/Drupal/flag/ActionLinkTypeBase.php @@ -77,6 +77,13 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity return $render; } + /** + * {@inhereitdoc} + */ + public function calculateDependencies() { + return array(); + } + /** * Provides a form array for the action link plugin's settings form. * Derived classes will want to override this method. diff --git a/lib/Drupal/flag/FlagTypeBase.php b/lib/Drupal/flag/FlagTypeBase.php index ec2412d..bc5b4f8 100644 --- a/lib/Drupal/flag/FlagTypeBase.php +++ b/lib/Drupal/flag/FlagTypeBase.php @@ -35,6 +35,13 @@ public function defaultConfiguration() { return array(); } + /** + * {@inhereitdoc} + */ + public function calculateDependencies() { + return array(); + } + /** * Returns this flag type plugin's configuration array. * diff --git a/lib/Drupal/flag/Form/FlagFormBase.php b/lib/Drupal/flag/Form/FlagFormBase.php index 257a692..ae8c84f 100644 --- a/lib/Drupal/flag/Form/FlagFormBase.php +++ b/lib/Drupal/flag/Form/FlagFormBase.php @@ -8,10 +8,10 @@ namespace Drupal\flag\Form; -use Drupal\Core\Entity\EntityFormController; +use Drupal\Core\Entity\EntityForm; use Drupal\flag\Handlers\AbstractFlag; -abstract class FlagFormBase extends EntityFormController { +abstract class FlagFormBase extends EntityForm { public function buildForm(array $form, array &$form_state, $entity_type = NULL) { diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php index 98c862f..339d879 100644 --- a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php +++ b/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php @@ -57,7 +57,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { // Add checkboxes to show flag link on each entity view mode. $options = array(); $defaults = array(); - $view_modes = entity_get_view_modes($this->entity_type); + $view_modes = \Drupal::entityManager()->getViewModes($this->entity_type); foreach ($view_modes as $name => $view_mode) { $options[$name] = t('Display on @name view mode', array('@name' => $view_mode['label'])); $defaults[$name] = !empty($this->show_in_links[$name]) ? $name : 0; From 8a9b44ec7b8430aebfd105fa5ee71b9a03396bd0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 27 May 2014 21:25:13 -0500 Subject: [PATCH 386/629] Initial (non-working) views functionality. --- flag.views.inc | 207 ++++++++++++++++++ flag_bookmark/flag_bookmark.install | 67 ------ flag_bookmark/flag_bookmark.module | 10 - .../flag_bookmark.flag_flag.bookmark.yml | 33 +++ lib/Drupal/flag/Form/FlagAddPageForm.php | 2 +- .../Plugin/views/field/FlagViewsLinkField.php | 74 +++++++ .../relationship/FlagViewsRelationship.php | 71 ++++++ 7 files changed, 386 insertions(+), 78 deletions(-) create mode 100644 flag.views.inc delete mode 100644 flag_bookmark/flag_bookmark.install create mode 100644 flag_bookmark/lib/Drupal/flag_bookmark/config/install/flag_bookmark.flag_flag.bookmark.yml create mode 100644 lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php create mode 100644 lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php diff --git a/flag.views.inc b/flag.views.inc new file mode 100644 index 0000000..edcd699 --- /dev/null +++ b/flag.views.inc @@ -0,0 +1,207 @@ + array( + 'type' => 'INNER', + 'left_field' => 'nid', + 'field' => 'entity_id', + ), + ); + $data['flagging']['entity_id'] = array( + 'title' => t('Entity ID'), + 'help' => t('The ID of the entity'), + 'sort' => array( + 'id' => 'standard', + ), + ); + +/* + // Flag content links. + $data['flagging']['ops'] = array( + 'title' => t('Flag link'), + 'help' => t('Display flag/unflag link.'), + 'field' => array( + 'handler' => 'flag_handler_field_ops', + ), + );*/ + + return $data; +} + +function flag_views_data_alter(&$data) { + $flags = \Drupal::service('flag')->getFlags(); + + foreach ($flags as $fid => $flag) { + $flag_type_plugin = $flag->getFlagTypePlugin(); + $flag_type_def = $flag_type_plugin->getPluginDefinition(); + + $info = \Drupal::entityManager()->getDefinition($flag_type_def['entity_type']); + + $base_table = $info->getBaseTable(); + if ($flag_type_def['entity_type'] == 'node') { + $base_table = $info->getDataTable(); + } + + $data[$base_table]['flag_content_rel'] = array( + 'title' => t('@entity_label flag', array('@entity_label' => $flag_type_def['entity_type'])), + 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), + 'relationship' => array( + 'group' => t('Flag'), + 'label' => t('Flags'), + 'base' => 'flagging', + 'base field' => 'entity_id', + 'relationship field' => $info->getKey('id'), + 'id' => 'flag_relationship', + 'flag type' => $fid, + ), + ); + + } +} + + +/* +function flag_views_data() { + $data = array(); + + + + + $data['flagging']['table']['group'] = t('Flags'); + $data['flagging']['table']['base'] = array( + 'field' => 'id', + 'title' => t('Flag Id'), + 'help' => t('The flagging Id.'), + ); + $data['flagging']['table']['entity type'] = 'flagging'; + +// $data['flag_counts']['table']['group'] = t('Flags'); + + $data['flagging']['uid'] = array( + 'title' => t('User uid'), + 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), + 'relationship' => array( + 'title' => t('User'), + 'help' => t('Relate an item to the user that flagged it.'), + 'id' => 'standard', + 'base' => 'users', + 'field' => uid, + 'label' => t('Flag user'), + ), +/* 'filter' => array( + 'handler' => 'views_handler_filter_user_name', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + ), + 'field' => array( + 'handler' => 'views_handler_field_user', + ), + ); + + $data['flagging']['timestamp'] = array( + 'title' => t('Flagged time'), + 'help' => t('Display the time the content was flagged by a user.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'id' => 'date', + ), + 'filter' => array( + 'id' => 'date', + ), +// 'argument' => array( +// 'handler' => 'views_handler_argument_date', +// ), + ); +/* + // Argument for content ID, used for "Who's flagged this" views. + $data['flagging']['entity_id'] = array( + 'title' => t('Content ID'), + 'help' => t('The unique ID of the object that has been flagged.'), + 'argument' => array( + 'handler' => 'flag_handler_argument_entity_id', + ), + ); + + // Specialized is null/is not null filter. + $data['flagging']['flagged'] = array( + 'title' => t('Flagged'), + 'real field' => 'uid', + 'field' => array( + 'handler' => 'flag_handler_field_flagged', + 'label' => t('Flagged'), + 'help' => t('A boolean field to show whether the flag is set or not.'), + ), + 'filter' => array( + 'handler' => 'flag_handler_filter_flagged', + 'label' => t('Flagged'), + 'help' => t('Filter to ensure content has or has not been flagged.'), + ), + 'sort' => array( + 'handler' => 'flag_handler_sort_flagged', + 'label' => t('Flagged'), + 'help' => t('Sort by whether entities have or have not been flagged.'), + ), + ); + + // Flag content links. + $data['flagging']['ops'] = array( + 'title' => t('Flag link'), + 'help' => t('Display flag/unflag link.'), + 'field' => array( + 'handler' => 'flag_handler_field_ops', + ), + ); + + $data['flag_counts']['count'] = array( + 'title' => t('Flag counter'), + 'help' => t('The number of times a piece of content is flagged by any user.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + ), + ); + + $data['flag_counts']['last_updated'] = array( + 'title' => t('Time last flagged'), + 'help' => t('The time a piece of content was most recently flagged by any user.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_date', + ), + ); + + return $data; +} + +*/ \ No newline at end of file diff --git a/flag_bookmark/flag_bookmark.install b/flag_bookmark/flag_bookmark.install deleted file mode 100644 index 284784a..0000000 --- a/flag_bookmark/flag_bookmark.install +++ /dev/null @@ -1,67 +0,0 @@ - 'bookmarks', - 'global' => 0, - 'show_in_links' => array( - 'full' => 1, - 'teaser' => 1, - ), - 'show_on_form' => 1, - // The following UI labels aren't wrapped in t() because they are written - // to the DB in English. They are passed to t() later, thus allowing for - // multilingual sites. - 'title' => 'Bookmarks', - 'flag_short' => 'Bookmark this', - 'flag_long' => 'Add this post to your bookmarks', - 'flag_message' => 'This post has been added to your bookmarks', - 'unflag_short' => 'Unbookmark this', - 'unflag_long' => 'Remove this post from your bookmarks', - 'unflag_message' => 'This post has been removed from your bookmarks', - 'types' => _flag_bookmark_install_get_suggested_node_types(), - ); - $flag->form_input($configuration); - $flag->save(); - - // Clear the flag cache so the new permission is seen by core. - drupal_static_reset('flag_get_flags'); - - // Grant permissions. - $permissions = array('flag bookmarks', 'unflag bookmarks'); - user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, $permissions); - } -} - -/** - * Returns some node types to which the demonstration 'bookmarks' flag will apply. - */ -function _flag_bookmark_install_get_suggested_node_types() { - $preferred = array('article', 'story', 'forum', 'blog'); - $existing = array_intersect($preferred, array_keys(node_type_get_types())); - if (!$existing) { - // As a last resort, take the first preference. - return array($preferred[0]); - } - return $existing; -} - diff --git a/flag_bookmark/flag_bookmark.module b/flag_bookmark/flag_bookmark.module index d182cf4..626ccd8 100644 --- a/flag_bookmark/flag_bookmark.module +++ b/flag_bookmark/flag_bookmark.module @@ -7,13 +7,3 @@ * This module creates a default Flag and associated views when enabled. The * content is intended to be an example and may be deleted afterward. */ - -/** - * Implements hook_views_api(). - */ -function flag_bookmark_views_api() { - return array( - 'api' => 2.0, - 'path' => drupal_get_path('module', 'flag_bookmark') . '/includes', - ); -} diff --git a/flag_bookmark/lib/Drupal/flag_bookmark/config/install/flag_bookmark.flag_flag.bookmark.yml b/flag_bookmark/lib/Drupal/flag_bookmark/config/install/flag_bookmark.flag_flag.bookmark.yml new file mode 100644 index 0000000..6e16e55 --- /dev/null +++ b/flag_bookmark/lib/Drupal/flag_bookmark/config/install/flag_bookmark.flag_flag.bookmark.yml @@ -0,0 +1,33 @@ +id: bookmark +entity_type: node +label: Bookmark +types: + article: article + page: page +flag_short: 'Bookmark this' +flag_long: 'Add this post to your bookmarks' +flag_message: 'This post has been added to your bookmarks' +unflag_short: 'Remove bookmark' +unflag_long: 'Remove this post from your bookmarks' +unflag_message: 'This post has been removed from your bookmarks' +unflag_denied_text: '' +weight: 0 +status: true +langcode: en +dependencies: { } +roles: null +flag_type: flagtype_node +link_type: reload +flagTypeConfig: + show_in_links: + full: full + teaser: teaser + rss: 0 + search_index: 0 + search_result: 0 + show_as_field: 1 + show_on_form: 0 + show_contextual_link: 0 + i18n: null + access_author: '' +linkTypeConfig: { } diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/lib/Drupal/flag/Form/FlagAddPageForm.php index 4a18772..82eaeab 100644 --- a/lib/Drupal/flag/Form/FlagAddPageForm.php +++ b/lib/Drupal/flag/Form/FlagAddPageForm.php @@ -11,7 +11,7 @@ use Drupal\Core\Form\FormBase; use Drupal\flag\Handlers\AbstractFlag; -class FlagAddPageForm extends FormBase{ +class FlagAddPageForm extends FormBase { /** * {@inheritdoc} diff --git a/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php b/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php new file mode 100644 index 0000000..f9f94af --- /dev/null +++ b/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php @@ -0,0 +1,74 @@ + '', + 'translatable' => TRUE, + ); +/* + $options['link_to_entity'] = array( + 'default' => FALSE, + 'bool' => TRUE, + ); +*/ + //@todo return link type + + return $options; + } + + /** + * @param $form + * @param $form_state + */ + public function buildOptionsForm(&$form, &$form_state) { + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Text to display'), + '#default_value' => $this->options['text'], + ); + + parent::buildOptionsForm($form, $form_state); + } + + /** + * @param ResultRow $values + * @return string|void + */ + public function render(ResultRow $values) { + $comment = $this->getEntity($values); + return $this->renderLink($comment, $values); + } + + /** + * @param $data + * @param ResultRow $values + */ + protected function renderLink($data, ResultRow $values) { + if ($node->access('view')) { + $text = !empty($this->options['text']) ? $this->options['text'] : t('View'); + return $text; + } + } + +} \ No newline at end of file diff --git a/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php b/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php new file mode 100644 index 0000000..14cb1fe --- /dev/null +++ b/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php @@ -0,0 +1,71 @@ + NULL); + $options['required'] = array('default' => 1); + $options['user_scope'] = array('default' => 'current'); + return $options; + } + + protected function buildOptionsForm(&$form, &$form_state) { + $entity_type = $this->definition['flag type']; + $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); + $form['flag'] = array( + '#type' => $form_type, + '#title' => t('Flag'), + '#default_value' => $current_flag, + '#required' => TRUE, + ); + + $flags = \Drupal::service('flag')->getFlags($entity_type) + foreach ($flags as $flag) { + $form['flag']['#options'][$flag->label()] = $flag->id(); + } + + $form['user_scope'] = array( + '#type' => 'radios', + '#title' => t('By'), + '#options' => array('current' => t('Current user'), 'any' => t('Any user')), + '#default_value' => $this->options['user_scope'], + ); + + $form['required']['#title'] = t('Include only flagged content'); + $form['required']['#description'] = t('If checked, only content that has this flag will be included. Leave unchecked to include all content; or, in combination with the Flagged filter, to limit the results to specifically unflagged content.', array('@unflagged-url' => 'http://drupal.org/node/299335')); + + if (!$form['flag']['#options']) { + $form = array( + 'error' => array( + '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', array('%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH))) . '

', + ), + ); + $form_state['no flags exist'] = TRUE; + } + + parent::buildOptionsForm($form, $form_state); + } + + public query() { + $this->ensureMyTable(); + + $def = $this->definition; + $def['table'] = 'flag'; + } +} \ No newline at end of file From c4e86d38718c1613f30dd6449013bf652ad723b2 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 28 May 2014 22:57:33 -0500 Subject: [PATCH 387/629] Partially working FlagViewsRelationship. --- flag.views.inc | 47 +++++++++++++++++-- .../Plugin/views/field/FlagViewsLinkField.php | 9 ++++ .../relationship/FlagViewsRelationship.php | 33 ++++++++----- 3 files changed, 75 insertions(+), 14 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index edcd699..90082dc 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -16,6 +16,46 @@ function flag_views_data() { 'field' => 'entity_id', ), ); + + $data['flagging']['uid'] = array( + 'title' => t('User uid'), + 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), + 'relationship' => array( + 'base' => 'users', + 'title' => t('User'), + 'help' => t('Relate an item to the user that flagged it.'), + 'id' => 'standard', + 'label' => t('Flag user'), + ), + 'filter' => array( + 'id' => 'numeric', + ), + 'argument' => array( + 'id' => 'numeric', + ), + 'field' => array( + 'id' => 'user', + ), + ); + + $data['flagging']['timestamp'] = array( + 'title' => t('Flagged time'), + 'help' => t('Display the time the content was flagged by a user.'), + 'field' => array( + 'id' => 'date', + //'click sortable' => TRUE, + ), + 'sort' => array( + 'id' => 'date', + ), + 'filter' => array( + 'id' => 'date', + ), + 'argument' => array( + 'id' => 'date', + ), + ); + $data['flagging']['entity_id'] = array( 'title' => t('Entity ID'), 'help' => t('The ID of the entity'), @@ -43,8 +83,9 @@ function flag_views_data_alter(&$data) { foreach ($flags as $fid => $flag) { $flag_type_plugin = $flag->getFlagTypePlugin(); $flag_type_def = $flag_type_plugin->getPluginDefinition(); + $entity_type = $flag_type_def['entity_type']; - $info = \Drupal::entityManager()->getDefinition($flag_type_def['entity_type']); + $info = \Drupal::entityManager()->getDefinition($entity_type); $base_table = $info->getBaseTable(); if ($flag_type_def['entity_type'] == 'node') { @@ -52,7 +93,7 @@ function flag_views_data_alter(&$data) { } $data[$base_table]['flag_content_rel'] = array( - 'title' => t('@entity_label flag', array('@entity_label' => $flag_type_def['entity_type'])), + 'title' => t('@entity_label flag', array('@entity_label' => $entity_type)), 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), 'relationship' => array( 'group' => t('Flag'), @@ -61,7 +102,7 @@ function flag_views_data_alter(&$data) { 'base field' => 'entity_id', 'relationship field' => $info->getKey('id'), 'id' => 'flag_relationship', - 'flag type' => $fid, + 'flaggable' => $entity_type, ), ); diff --git a/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php b/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php index f9f94af..74e7913 100644 --- a/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php +++ b/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php @@ -19,6 +19,15 @@ */ class FlagViewsLinkField extends FieldPluginBase { + public function getFlag() { + // When editing a view it's possible to delete the relationship (either by + // error or to later recreate it), so we have to guard against a missing + // one. + if (isset($this->view->relationship[$this->options['relationship']])) { + return $this->view->relationship[$this->options['relationship']]->getFlag(); + } + } + protected function defineOptions() { $options = parent::defineOptions(); diff --git a/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php b/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php index 14cb1fe..a3ad58d 100644 --- a/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php +++ b/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php @@ -15,29 +15,40 @@ * * @ViewsRelationship("flag_relationship") */ -public class FlagViewsRelationship extends RelationshipPluginBase { +class FlagViewsRelationship extends RelationshipPluginBase { - protected function defineOptions() { + public function defineOptions() { $options = parent::defineOptions(); - $options['flag'] = array('default' => NULL); + $options['flag'] = array('default' => NULL); // @todo load first defined flag for entity. $options['required'] = array('default' => 1); $options['user_scope'] = array('default' => 'current'); return $options; } - protected function buildOptionsForm(&$form, &$form_state) { - $entity_type = $this->definition['flag type']; + public function buildOptionsForm(&$form, &$form_state) { + $entity_type = $this->definition['flaggable']; $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); + + /*////////////////////////////////////////////////////////////////////////// + @todo Add Flag selection form + + The Flag relationship relates a single flag to a single entity. Since + multiple flags may be configured for the same entity type, we need to + provide a form here that allows us to choose the flag. + //////////////////////////////////////////////////////////////////////////*/ + $flags = \Drupal::service('flag')->getFlags($entity_type); + $form['flag'] = array( - '#type' => $form_type, + '#type' => 'radios', '#title' => t('Flag'), - '#default_value' => $current_flag, + // '#default_value' => current(array_keys($flags)), '#required' => TRUE, ); - $flags = \Drupal::service('flag')->getFlags($entity_type) - foreach ($flags as $flag) { - $form['flag']['#options'][$flag->label()] = $flag->id(); + foreach ($flags as $fid => $flag) { + if (!empty($flag)) { + $form['flag']['#options'][$flag->label()] = $fid; + } } $form['user_scope'] = array( @@ -62,7 +73,7 @@ protected function buildOptionsForm(&$form, &$form_state) { parent::buildOptionsForm($form, $form_state); } - public query() { + public function query() { $this->ensureMyTable(); $def = $this->definition; From 5439724e6ae24905bc87244b550ad439c7221fae Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 3 Jun 2014 10:17:33 -0500 Subject: [PATCH 388/629] Holy mega PSR-4 class move, batman\! --- {lib/Drupal/flag => src}/ActionLinkPluginManager.php | 0 {lib/Drupal/flag => src}/ActionLinkTypeBase.php | 0 {lib/Drupal/flag => src}/ActionLinkTypePluginInterface.php | 0 {lib/Drupal/flag => src}/Annotation/ActionLinkType.php | 0 {lib/Drupal/flag => src}/Annotation/FlagType.php | 0 {lib/Drupal/flag => src}/BrokenFlagType.php | 0 {lib/Drupal/flag => src}/Controller/AJAXLinkController.php | 0 {lib/Drupal/flag => src}/Controller/FlagListController.php | 0 {lib/Drupal/flag => src}/Controller/ReloadLinkController.php | 0 {lib/Drupal/flag => src}/Entity/Flag.php | 0 {lib/Drupal/flag => src}/Entity/Flagging.php | 0 {lib/Drupal/flag => src}/FlagInterface.php | 0 {lib/Drupal/flag => src}/FlagService.php | 0 {lib/Drupal/flag => src}/FlagTypeBase.php | 0 {lib/Drupal/flag => src}/FlagTypePluginInterface.php | 0 {lib/Drupal/flag => src}/FlagTypePluginManager.php | 0 {lib/Drupal/flag => src}/FlaggingAccessController.php | 0 {lib/Drupal/flag => src}/FlaggingInterface.php | 0 {lib/Drupal/flag => src}/Form/FlagAddForm.php | 0 {lib/Drupal/flag => src}/Form/FlagAddPageForm.php | 0 {lib/Drupal/flag => src}/Form/FlagDeleteForm.php | 0 {lib/Drupal/flag => src}/Form/FlagEditForm.php | 0 {lib/Drupal/flag => src}/Form/FlagExportForm.php | 0 {lib/Drupal/flag => src}/Form/FlagFormBase.php | 0 {lib/Drupal/flag => src}/Form/FlagImportForm.php | 0 {lib/Drupal/flag => src}/Form/FlaggingConfirmForm.php | 0 {lib/Drupal/flag => src}/Plugin/ActionLink/AJAXactionLink.php | 0 {lib/Drupal/flag => src}/Plugin/ActionLink/ConfirmForm.php | 0 {lib/Drupal/flag => src}/Plugin/ActionLink/Reload.php | 0 {lib/Drupal/flag => src}/Plugin/Derivative/EntityFlagType.php | 0 {lib/Drupal/flag => src}/Plugin/Flag/CommentFlagType.php | 0 {lib/Drupal/flag => src}/Plugin/Flag/EntityFlagType.php | 0 {lib/Drupal/flag => src}/Plugin/Flag/NodeFlagType.php | 0 {lib/Drupal/flag => src}/Plugin/Flag/UserFlagType.php | 0 .../Drupal/flag => src}/Plugin/views/field/FlagViewsLinkField.php | 0 .../Plugin/views/relationship/FlagViewsRelationship.php | 0 {lib/Drupal/flag => src}/config/schema/flag.schema.yml | 0 37 files changed, 0 insertions(+), 0 deletions(-) rename {lib/Drupal/flag => src}/ActionLinkPluginManager.php (100%) rename {lib/Drupal/flag => src}/ActionLinkTypeBase.php (100%) rename {lib/Drupal/flag => src}/ActionLinkTypePluginInterface.php (100%) rename {lib/Drupal/flag => src}/Annotation/ActionLinkType.php (100%) rename {lib/Drupal/flag => src}/Annotation/FlagType.php (100%) rename {lib/Drupal/flag => src}/BrokenFlagType.php (100%) rename {lib/Drupal/flag => src}/Controller/AJAXLinkController.php (100%) rename {lib/Drupal/flag => src}/Controller/FlagListController.php (100%) rename {lib/Drupal/flag => src}/Controller/ReloadLinkController.php (100%) rename {lib/Drupal/flag => src}/Entity/Flag.php (100%) rename {lib/Drupal/flag => src}/Entity/Flagging.php (100%) rename {lib/Drupal/flag => src}/FlagInterface.php (100%) rename {lib/Drupal/flag => src}/FlagService.php (100%) rename {lib/Drupal/flag => src}/FlagTypeBase.php (100%) rename {lib/Drupal/flag => src}/FlagTypePluginInterface.php (100%) rename {lib/Drupal/flag => src}/FlagTypePluginManager.php (100%) rename {lib/Drupal/flag => src}/FlaggingAccessController.php (100%) rename {lib/Drupal/flag => src}/FlaggingInterface.php (100%) rename {lib/Drupal/flag => src}/Form/FlagAddForm.php (100%) rename {lib/Drupal/flag => src}/Form/FlagAddPageForm.php (100%) rename {lib/Drupal/flag => src}/Form/FlagDeleteForm.php (100%) rename {lib/Drupal/flag => src}/Form/FlagEditForm.php (100%) rename {lib/Drupal/flag => src}/Form/FlagExportForm.php (100%) rename {lib/Drupal/flag => src}/Form/FlagFormBase.php (100%) rename {lib/Drupal/flag => src}/Form/FlagImportForm.php (100%) rename {lib/Drupal/flag => src}/Form/FlaggingConfirmForm.php (100%) rename {lib/Drupal/flag => src}/Plugin/ActionLink/AJAXactionLink.php (100%) rename {lib/Drupal/flag => src}/Plugin/ActionLink/ConfirmForm.php (100%) rename {lib/Drupal/flag => src}/Plugin/ActionLink/Reload.php (100%) rename {lib/Drupal/flag => src}/Plugin/Derivative/EntityFlagType.php (100%) rename {lib/Drupal/flag => src}/Plugin/Flag/CommentFlagType.php (100%) rename {lib/Drupal/flag => src}/Plugin/Flag/EntityFlagType.php (100%) rename {lib/Drupal/flag => src}/Plugin/Flag/NodeFlagType.php (100%) rename {lib/Drupal/flag => src}/Plugin/Flag/UserFlagType.php (100%) rename {lib/Drupal/flag => src}/Plugin/views/field/FlagViewsLinkField.php (100%) rename {lib/Drupal/flag => src}/Plugin/views/relationship/FlagViewsRelationship.php (100%) rename {lib/Drupal/flag => src}/config/schema/flag.schema.yml (100%) diff --git a/lib/Drupal/flag/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php similarity index 100% rename from lib/Drupal/flag/ActionLinkPluginManager.php rename to src/ActionLinkPluginManager.php diff --git a/lib/Drupal/flag/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php similarity index 100% rename from lib/Drupal/flag/ActionLinkTypeBase.php rename to src/ActionLinkTypeBase.php diff --git a/lib/Drupal/flag/ActionLinkTypePluginInterface.php b/src/ActionLinkTypePluginInterface.php similarity index 100% rename from lib/Drupal/flag/ActionLinkTypePluginInterface.php rename to src/ActionLinkTypePluginInterface.php diff --git a/lib/Drupal/flag/Annotation/ActionLinkType.php b/src/Annotation/ActionLinkType.php similarity index 100% rename from lib/Drupal/flag/Annotation/ActionLinkType.php rename to src/Annotation/ActionLinkType.php diff --git a/lib/Drupal/flag/Annotation/FlagType.php b/src/Annotation/FlagType.php similarity index 100% rename from lib/Drupal/flag/Annotation/FlagType.php rename to src/Annotation/FlagType.php diff --git a/lib/Drupal/flag/BrokenFlagType.php b/src/BrokenFlagType.php similarity index 100% rename from lib/Drupal/flag/BrokenFlagType.php rename to src/BrokenFlagType.php diff --git a/lib/Drupal/flag/Controller/AJAXLinkController.php b/src/Controller/AJAXLinkController.php similarity index 100% rename from lib/Drupal/flag/Controller/AJAXLinkController.php rename to src/Controller/AJAXLinkController.php diff --git a/lib/Drupal/flag/Controller/FlagListController.php b/src/Controller/FlagListController.php similarity index 100% rename from lib/Drupal/flag/Controller/FlagListController.php rename to src/Controller/FlagListController.php diff --git a/lib/Drupal/flag/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php similarity index 100% rename from lib/Drupal/flag/Controller/ReloadLinkController.php rename to src/Controller/ReloadLinkController.php diff --git a/lib/Drupal/flag/Entity/Flag.php b/src/Entity/Flag.php similarity index 100% rename from lib/Drupal/flag/Entity/Flag.php rename to src/Entity/Flag.php diff --git a/lib/Drupal/flag/Entity/Flagging.php b/src/Entity/Flagging.php similarity index 100% rename from lib/Drupal/flag/Entity/Flagging.php rename to src/Entity/Flagging.php diff --git a/lib/Drupal/flag/FlagInterface.php b/src/FlagInterface.php similarity index 100% rename from lib/Drupal/flag/FlagInterface.php rename to src/FlagInterface.php diff --git a/lib/Drupal/flag/FlagService.php b/src/FlagService.php similarity index 100% rename from lib/Drupal/flag/FlagService.php rename to src/FlagService.php diff --git a/lib/Drupal/flag/FlagTypeBase.php b/src/FlagTypeBase.php similarity index 100% rename from lib/Drupal/flag/FlagTypeBase.php rename to src/FlagTypeBase.php diff --git a/lib/Drupal/flag/FlagTypePluginInterface.php b/src/FlagTypePluginInterface.php similarity index 100% rename from lib/Drupal/flag/FlagTypePluginInterface.php rename to src/FlagTypePluginInterface.php diff --git a/lib/Drupal/flag/FlagTypePluginManager.php b/src/FlagTypePluginManager.php similarity index 100% rename from lib/Drupal/flag/FlagTypePluginManager.php rename to src/FlagTypePluginManager.php diff --git a/lib/Drupal/flag/FlaggingAccessController.php b/src/FlaggingAccessController.php similarity index 100% rename from lib/Drupal/flag/FlaggingAccessController.php rename to src/FlaggingAccessController.php diff --git a/lib/Drupal/flag/FlaggingInterface.php b/src/FlaggingInterface.php similarity index 100% rename from lib/Drupal/flag/FlaggingInterface.php rename to src/FlaggingInterface.php diff --git a/lib/Drupal/flag/Form/FlagAddForm.php b/src/Form/FlagAddForm.php similarity index 100% rename from lib/Drupal/flag/Form/FlagAddForm.php rename to src/Form/FlagAddForm.php diff --git a/lib/Drupal/flag/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php similarity index 100% rename from lib/Drupal/flag/Form/FlagAddPageForm.php rename to src/Form/FlagAddPageForm.php diff --git a/lib/Drupal/flag/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php similarity index 100% rename from lib/Drupal/flag/Form/FlagDeleteForm.php rename to src/Form/FlagDeleteForm.php diff --git a/lib/Drupal/flag/Form/FlagEditForm.php b/src/Form/FlagEditForm.php similarity index 100% rename from lib/Drupal/flag/Form/FlagEditForm.php rename to src/Form/FlagEditForm.php diff --git a/lib/Drupal/flag/Form/FlagExportForm.php b/src/Form/FlagExportForm.php similarity index 100% rename from lib/Drupal/flag/Form/FlagExportForm.php rename to src/Form/FlagExportForm.php diff --git a/lib/Drupal/flag/Form/FlagFormBase.php b/src/Form/FlagFormBase.php similarity index 100% rename from lib/Drupal/flag/Form/FlagFormBase.php rename to src/Form/FlagFormBase.php diff --git a/lib/Drupal/flag/Form/FlagImportForm.php b/src/Form/FlagImportForm.php similarity index 100% rename from lib/Drupal/flag/Form/FlagImportForm.php rename to src/Form/FlagImportForm.php diff --git a/lib/Drupal/flag/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php similarity index 100% rename from lib/Drupal/flag/Form/FlaggingConfirmForm.php rename to src/Form/FlaggingConfirmForm.php diff --git a/lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php b/src/Plugin/ActionLink/AJAXactionLink.php similarity index 100% rename from lib/Drupal/flag/Plugin/ActionLink/AJAXactionLink.php rename to src/Plugin/ActionLink/AJAXactionLink.php diff --git a/lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php similarity index 100% rename from lib/Drupal/flag/Plugin/ActionLink/ConfirmForm.php rename to src/Plugin/ActionLink/ConfirmForm.php diff --git a/lib/Drupal/flag/Plugin/ActionLink/Reload.php b/src/Plugin/ActionLink/Reload.php similarity index 100% rename from lib/Drupal/flag/Plugin/ActionLink/Reload.php rename to src/Plugin/ActionLink/Reload.php diff --git a/lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php b/src/Plugin/Derivative/EntityFlagType.php similarity index 100% rename from lib/Drupal/flag/Plugin/Derivative/EntityFlagType.php rename to src/Plugin/Derivative/EntityFlagType.php diff --git a/lib/Drupal/flag/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php similarity index 100% rename from lib/Drupal/flag/Plugin/Flag/CommentFlagType.php rename to src/Plugin/Flag/CommentFlagType.php diff --git a/lib/Drupal/flag/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php similarity index 100% rename from lib/Drupal/flag/Plugin/Flag/EntityFlagType.php rename to src/Plugin/Flag/EntityFlagType.php diff --git a/lib/Drupal/flag/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php similarity index 100% rename from lib/Drupal/flag/Plugin/Flag/NodeFlagType.php rename to src/Plugin/Flag/NodeFlagType.php diff --git a/lib/Drupal/flag/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php similarity index 100% rename from lib/Drupal/flag/Plugin/Flag/UserFlagType.php rename to src/Plugin/Flag/UserFlagType.php diff --git a/lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php similarity index 100% rename from lib/Drupal/flag/Plugin/views/field/FlagViewsLinkField.php rename to src/Plugin/views/field/FlagViewsLinkField.php diff --git a/lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php similarity index 100% rename from lib/Drupal/flag/Plugin/views/relationship/FlagViewsRelationship.php rename to src/Plugin/views/relationship/FlagViewsRelationship.php diff --git a/lib/Drupal/flag/config/schema/flag.schema.yml b/src/config/schema/flag.schema.yml similarity index 100% rename from lib/Drupal/flag/config/schema/flag.schema.yml rename to src/config/schema/flag.schema.yml From ba21da1e92e6af76966ae9528db4f13913dd75b8 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 3 Jun 2014 17:58:09 -0500 Subject: [PATCH 389/629] Updated the signature of hook_entity_view() due to https://drupal.org/node/2246681 --- flag.module | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 4e823d2..84569ba 100644 --- a/flag.module +++ b/flag.module @@ -10,9 +10,10 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); -use Drupal\flag\Handlers\AbstractFlag; use Drupal\flag\Flag; use Drupal\node\NodeInterface; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Display\EntityViewDisplayInterface; // @todo: Implement flagging_view(). Not extremely useful. I already have it. @@ -578,7 +579,10 @@ function flag_field_attach_save($entity_type, $entity) { * * Note this is broken for taxonomy terms for version of Drupal core < 7.17. */ -function flag_entity_view($entity, $display, $view_mode, $langcode) { +function flag_entity_view(array &$build, EntityInterface $entity, + EntityViewDisplayInterface $display, + $view_mode, $langcode) { + //@todo Check $type->getComponent('flag_whateverHookFieldExtraFieldsIS'). // if not NULL, display it. From 546b61534ea3a7094cbcc4af5acf08d50e535298 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 4 Jun 2014 09:31:30 -0500 Subject: [PATCH 390/629] Fixes for https://github.com/socketwench/flag-drupal8/issues/7 and changes to Drupal core. --- flag.install | 2 +- flag.module | 2 +- src/Entity/Flag.php | 2 ++ src/Entity/Flagging.php | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/flag.install b/flag.install index 364686b..91f8ba8 100644 --- a/flag.install +++ b/flag.install @@ -109,7 +109,7 @@ function flag_schema() { 'not null' => TRUE, 'default' => 0, ), - 'timestamp' => array( + 'created' => array( 'description' => 'The UNIX time stamp representing when the flag was set.', 'type' => 'int', 'unsigned' => TRUE, diff --git a/flag.module b/flag.module index 84569ba..c2fa936 100644 --- a/flag.module +++ b/flag.module @@ -601,7 +601,7 @@ function flag_entity_view(array &$build, EntityInterface $entity, } $link = $linkTypePlugin->renderLink($action, $flag, $entity); - $entity->content['flag_' . $flag->id] = $link; + $build['flag_' . $flag->id] = $link; } /** diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index ea87af2..2c93152 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -320,6 +320,8 @@ public function preSave(EntityStorageInterface $storage_controller) { \Drupal::entityManager() ->getViewBuilder($this->getFlaggableEntityType()) ->resetCache(); + + entity_render_cache_clear(); } public function toArray() { diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 4147d38..9ab2ab8 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -75,7 +75,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The flagging UUID.')) ->setReadOnly(TRUE); - $fields['fid'] = FieldDefinition::create('integer') + $fields['fid'] = FieldDefinition::create('string') ->setLabel(t('Flag ID')) ->setDescription(t('The Flag ID.')) ->setReadOnly(TRUE); From 0552c5b0035da2b0e9d09ac9a31e909771b28887 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 4 Jun 2014 09:35:05 -0500 Subject: [PATCH 391/629] Removed unnecessary entity cache clear all in Flag::preSave(). --- src/Entity/Flag.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 2c93152..ea87af2 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -320,8 +320,6 @@ public function preSave(EntityStorageInterface $storage_controller) { \Drupal::entityManager() ->getViewBuilder($this->getFlaggableEntityType()) ->resetCache(); - - entity_render_cache_clear(); } public function toArray() { From f2e32d7bda9adb56746cbf481b1ac71ea18f7f05 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 4 Jun 2014 13:49:39 -0500 Subject: [PATCH 392/629] Fixed some breakage with the AJAX link type. --- flag.module | 60 ++++----------------------------------- src/Entity/Flagging.php | 2 +- src/Form/FlagFormBase.php | 8 ++++-- 3 files changed, 11 insertions(+), 59 deletions(-) diff --git a/flag.module b/flag.module index c2fa936..d65bdc3 100644 --- a/flag.module +++ b/flag.module @@ -603,56 +603,6 @@ function flag_entity_view(array &$build, EntityInterface $entity, $link = $linkTypePlugin->renderLink($action, $flag, $entity); $build['flag_' . $flag->id] = $link; } - - /** - foreach ($flags as $flag) { - // Check if the flag outputs on entity view. - if (!($flag->show_as_field)) { //} || $flag->shows_in_entity_links($view_mode))) { - // Flag is not configured to output on entity view, so skip it to save on - // calls to access checks. - continue; - } - - $entity_id = $flag->get_entity_id($entity); - // For a new, unsaved entity, make a dummy entity ID so that the flag - // handler can remember the entity. This allows access to the flag to be - // correctly handled in node and comment preview. - if (is_null($entity_id)) { - $entity_id = 'new'; - } - $flag->remember_entity($entity_id, $entity); - - if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { - // User has no permission to use this flag or flag does not apply to this - // entity. The link is not skipped if the user has "flag" access but - // not "unflag" access (this way the unflag denied message is shown). - continue; - } - - // We're good to go. Output the flag in the appropriate manner(s). - - // The old-style entity links output. - if ($flag->shows_in_entity_links($view_mode)) { - // The flag links are actually fully rendered theme functions. - // The HTML attribute is set to TRUE to allow whatever the themer desires. - $links['flag-' . $flag->name] = array( - 'title' => $flag->flag_short, //theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id), - 'html' => TRUE, - ); - } - - // The pseudofield output. - if ($flag->show_as_field) { - $entity->content['flag_' . $flag->name] = array( - '#markup' => $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id, array('needs_wrapping_element' => TRUE)), - ); - } - } - */ - // If any links were made, add them to the entity's links array. -// if (isset($links)) { -// $entity->content['links']['flag'] = $links; - // } } /** @@ -836,7 +786,7 @@ function flag_user_delete($account) { /** * Shared helper for user account cancellation or deletion. - */ + *//* function flag_user_account_removal($account) { // Remove flags by this user. $query = db_select('flagging', 'fc'); @@ -872,11 +822,11 @@ function flag_user_account_removal($account) { // Remove flags that have been done to this user. _flag_entity_delete('user', $account->uid); -} +}*/ /** * Implements hook_user_view(). - */ + *//* function flag_user_view($account, $view_mode) { $flags = flag_get_flags('user'); $flag_items = array(); @@ -885,7 +835,7 @@ function flag_user_view($account, $view_mode) { // User has no permission to use this flag. continue; } - if (!$flag->show_on_profile) { + if (empty($flag->show_on_profile)) { // Flag not set to appear on profile. continue; } @@ -904,7 +854,7 @@ function flag_user_view($account, $view_mode) { '#attributes' => array('class' => array('flag-profile')), ); } -} +}*/ /** * Implements hook_session_api_cleanup(). diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 9ab2ab8..debe1a4 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -49,7 +49,7 @@ public function getFlagId() { } public function getFlag() { - return entity_load($this->bundle, $this->getFlagId()); + return entity_load('flag_flag', $this->getFlagId()); } public function getFlaggableType() { diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index ae8c84f..7d39287 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -188,14 +188,16 @@ public function validate(array $form, array &$form_state) { $form_state['values']['label'] = trim($form_state['values']['label']); $form_values = $form_state['values']; + //@todo Move this to the validation method for the confirm form plugin + /* if ($form_values['link_type'] == 'confirm') { if (empty($form_values['flag_confirmation'])) { - form_set_error('flag_confirmation', array(t('A flag confirmation message is required when using the confirmation link type.'))); + $this->setFormError('flag_confirmation', $form_state, $this->t('A flag confirmation message is required when using the confirmation link type.')); } if (empty($form_values['unflag_confirmation'])) { - form_set_error('unflag_confirmation', array(t('An unflag confirmation message is required when using the confirmation link type.'))); + $this->setFormError('unflag_confirmation', $form_state, $this->t('An unflag confirmation message is required when using the confirmation link type.')); } - } + }*/ /* if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { form_set_error('label', t('The flag name may only contain lowercase letters, underscores, and numbers.')); From 1c7bdeab40ec6825034a90ef63ea09e868ddec8c Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 4 Jun 2014 14:53:48 -0500 Subject: [PATCH 393/629] Fixed confirm form, some API cleanup in FlagService. --- src/FlagService.php | 37 ++++++++++++++++++++++----- src/Plugin/ActionLink/ConfirmForm.php | 4 +-- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index 17bbcd1..a8352e8 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -146,6 +146,15 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou return $flagging; } + /** + * + * @api + * + * @param $flag_id + * @param $entity_id + * @param AccountInterface $account + * @return EntityInterface + */ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { $account = \Drupal::currentUser(); @@ -157,10 +166,15 @@ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { return $this->flagByObject($flag, $entity, $account); } - public function unflagByObject(FlaggingInterface $flagging) { - $flagging->delete(); - } - + /** + * + * @api + * + * @param $flag_id + * @param $entity_id + * @param AccountInterface $account + * @return array + */ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { $account = \Drupal::currentUser(); @@ -169,13 +183,24 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { $flag = $this->getFlagById($flag_id); $entity = $this->getFlaggableById($flag, $entity_id); + return $this->unflagByObject($flag, $entity, $account); + } + + + public function unflagByObject(FlagInterface $flag, + EntityInterface $entity, + AccountInterface $account = NULL) { $out = array(); $flaggings = $this->getFlaggings($entity, $flag); foreach ($flaggings as $flagging) { - $out[] = $this->unflagByObject($flagging); + $out[] = $this->unflagByFlagging($flagging); } return $out; } -} \ No newline at end of file + public function unflagByFlagging(FlaggingInterface $flagging) { + $flagging->delete(); + } + +} \ No newline at end of file diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index e92986a..5ebfa8c 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -34,8 +34,8 @@ public function defaultConfiguration() { $options = parent::defaultConfiguration(); $options += array( - 'flag_confirmation' => '', - 'unflag_confirmation' => '', + 'flag_confirmation' => 'Flag this content?', + 'unflag_confirmation' => 'Unflag this content?', ); return $options; From 04afa6f1706569c166c66b9e7d70f83bae93cdb4 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 5 Jun 2014 11:01:57 -0500 Subject: [PATCH 394/629] Updated hook_schema() due to https://drupal.org/node/2259243. --- flag.install | 78 ++-------------------------------------------------- 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/flag.install b/flag.install index 91f8ba8..613a23b 100644 --- a/flag.install +++ b/flag.install @@ -11,56 +11,6 @@ function flag_schema() { $schema = array(); /* - $schema['flag'] = array( - 'description' => 'All available flags in the system.', - 'fields' => array( - 'fid' => array( - 'description' => 'The unique ID for this particular flag.', - 'type' => 'serial', - 'size' => 'small', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'entity_type' => array( - 'description' => 'The flag type, such as one of "node", "comment", or "user".', - 'type' => 'varchar', - 'length' => '128', - 'not null' => TRUE, - 'default' => '', - ), - 'name' => array( - 'description' => 'The machine-name for this flag.', - 'type' => 'varchar', - 'length' => '32', - 'not null' => FALSE, - 'default' => '', - ), - 'title' => array( - 'description' => 'The human-readable title for this flag.', - 'type' => 'varchar', - 'length' => '255', - 'not null' => FALSE, - 'default' => '', - ), - 'global' => array( - 'description' => 'Whether this flag state should act as a single toggle to all users across the site.', - 'type' => 'int', - 'size' => 'tiny', - 'not null' => FALSE, - 'default' => 0, - ), - 'options' => array( - 'description' => 'The options and configuration of this flag.', - 'type' => 'text', - 'not null' => FALSE, - ), - ), - 'primary key' => array('fid'), - 'unique keys' => array( - 'name' => array('name'), - ), - ); -*/ $schema['flagging'] = array( 'description' => 'Objects that have been flagged.', 'fields' => array( @@ -135,31 +85,7 @@ function flag_schema() { 'entity_id_fid' => array('entity_id', 'fid'), ), ); -/* - $schema['flag_types'] = array( - 'description' => 'The entity bundles that are affected by a flag.', - 'fields' => array( - 'fid' => array( - 'description' => 'The unqiue flag ID as defined for the flag in {flag}.', - 'type' => 'int', - 'size' => 'small', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'type' => array( - 'description' => 'The entity bundles that can be flagged by this fid.', - 'type' => 'varchar', - 'length' => '128', - 'not null' => TRUE, - 'default' => '', - ), - ), - 'indexes' => array( - 'fid' => array('fid'), - ), - ); - +*/ $schema['flag_counts'] = array( 'description' => 'The number of times an item has been flagged.', 'fields' => array( @@ -210,7 +136,7 @@ function flag_schema() { 'fid_last_updated' => array('fid', 'last_updated'), ), ); -*/ + return $schema; } From cdc9b1bc11876212d58297e024e1e534366bc5ff Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 7 Jun 2014 12:41:36 -0500 Subject: [PATCH 395/629] Changes due to https://drupal.org/node/2259243, fixes to views functionality. --- flag.install | 88 +------------------ flag.views.inc | 2 +- .../relationship/FlagViewsRelationship.php | 13 ++- 3 files changed, 14 insertions(+), 89 deletions(-) diff --git a/flag.install b/flag.install index 613a23b..3e7100b 100644 --- a/flag.install +++ b/flag.install @@ -10,82 +10,7 @@ */ function flag_schema() { $schema = array(); -/* - $schema['flagging'] = array( - 'description' => 'Objects that have been flagged.', - 'fields' => array( - 'id' => array( - 'description' => 'The unique ID for this particular tag.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'uuid' => array( - 'description' => 'Unique Key: Universally unique identifier for this entity.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - ), - 'fid' => array( - 'description' => 'The unique flag ID this object has been flagged with, from {flag}.', - 'type' => 'varchar', - 'length' => 32, - 'not null' => FALSE, - ), - 'entity_type' => array( - 'description' => 'The flag type, eg "node", "comment", "user".', - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - ), - 'entity_id' => array( - 'description' => 'The unique ID of the object, such as either the {cid}, {uid}, or {nid}.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'uid' => array( - 'description' => 'The user ID by whom this object was flagged.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'sid' => array( - 'description' => "The user's session id as stored in the session table.", - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'created' => array( - 'description' => 'The UNIX time stamp representing when the flag was set.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'disp-size' => 11, - ), - 'type' => array( - 'description' => 'The type of this node.', - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - 'default' => '', - ), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'fid_entity_id_uid_sid' => array('fid', 'entity_id', 'uid', 'sid'), - ), - 'indexes' => array( - 'entity_type_uid_sid' => array('entity_type', 'uid', 'sid'), - 'entity_type_entity_id_uid_sid' => array('entity_type', 'entity_id', 'uid', 'sid'), - 'entity_id_fid' => array('entity_id', 'fid'), - ), - ); -*/ + $schema['flag_counts'] = array( 'description' => 'The number of times an item has been flagged.', 'fields' => array( @@ -144,15 +69,6 @@ function flag_schema() { * Implements hook_uninstall(). */ function flag_uninstall() { - /* - $result = db_select('variable', 'v') - ->fields('v', array('name')) - ->condition('name', 'flag_%', 'LIKE') - ->execute(); - foreach ($result as $row) { - variable_del($row->name); - } - */ drupal_set_message(t('Flag has been uninstalled.')); } @@ -160,6 +76,7 @@ function flag_uninstall() { * Implements hook_requirements(). */ function flag_requirements($phase) { + /* $requirements = array(); if ($phase == 'runtime') { @@ -191,4 +108,5 @@ function flag_requirements($phase) { } } return $requirements; + */ } diff --git a/flag.views.inc b/flag.views.inc index 90082dc..7488d59 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -38,7 +38,7 @@ function flag_views_data() { ), ); - $data['flagging']['timestamp'] = array( + $data['flagging']['created'] = array( 'title' => t('Flagged time'), 'help' => t('Display the time the content was flagged by a user.'), 'field' => array( diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index a3ad58d..18a6831 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -74,9 +74,16 @@ public function buildOptionsForm(&$form, &$form_state) { } public function query() { - $this->ensureMyTable(); + if (!($flag = $this->getFlag())) { + return; + } + + parent::query(); + + } - $def = $this->definition; - $def['table'] = 'flag'; + protected function getFlag() { + $flaggable = $this->options['flaggable']; + $this->options['flag'] = \Drupal::service('flag')->getFlag($flaggable); } } \ No newline at end of file From d7543bbc34aa6fc8e2224bef86bb79cb54d17e8c Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 7 Jun 2014 14:07:39 -0500 Subject: [PATCH 396/629] Ported FlagViewsRelationship. Maybe it even works\! --- flag.views.inc | 7 ++-- .../relationship/FlagViewsRelationship.php | 34 ++++++++++++++++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 7488d59..9775e38 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -11,7 +11,7 @@ function flag_views_data() { $data['flagging']['table']['group'] = t('Flag'); $data['flagging']['table']['join'] = array( 'node' => array( - 'type' => 'INNER', + 'type' => 'LEFT', 'left_field' => 'nid', 'field' => 'entity_id', ), @@ -39,11 +39,10 @@ function flag_views_data() { ); $data['flagging']['created'] = array( - 'title' => t('Flagged time'), - 'help' => t('Display the time the content was flagged by a user.'), + 'title' => t('Last Flagged Time'), + 'help' => t('Display latest time the content was flagged by a user.'), 'field' => array( 'id' => 'date', - //'click sortable' => TRUE, ), 'sort' => array( 'id' => 'date', diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 18a6831..bd495ae 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -27,7 +27,7 @@ public function defineOptions() { public function buildOptionsForm(&$form, &$form_state) { $entity_type = $this->definition['flaggable']; - $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); + //$form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); /*////////////////////////////////////////////////////////////////////////// @todo Add Flag selection form @@ -78,12 +78,38 @@ public function query() { return; } - parent::query(); + $this->definition['extra'][] = array( + 'field' => 'fid', + 'value' => $flag->id, + 'numeric' => TRUE, + ); + + if ($this->definition['user_scope'] == 'current' && !$flag->isGlobal()) { + $this->definition['extra'][] = array( + 'field' => 'uid', + 'value' => '***CURRENT_USER***', + 'numeric' => TRUE, + ); + $flag_roles = user_roles(FALSE, "flag $flag->name"); + if (isset($flag_roles[DRUPAL_ANONYMOUS_RID])) { + // Disable page caching for anonymous users. + drupal_page_is_cacheable(FALSE); + + // Add in the SID from Session API for anonymous users. + $this->definition['extra'][] = array( + 'field' => 'sid', + 'value' => '***FLAG_CURRENT_USER_SID***', + 'numeric' => TRUE, + ); + } + } + +// parent::query(); } protected function getFlag() { - $flaggable = $this->options['flaggable']; - $this->options['flag'] = \Drupal::service('flag')->getFlag($flaggable); + $flaggable = $this->definition['flaggable']; + $this->options['flag'] = \Drupal::service('flag')->getFlags($flaggable); } } \ No newline at end of file From a6f39adc21c632406b2d7709ac6e75a44fdf116d Mon Sep 17 00:00:00 2001 From: Fernando Paredes Garcia Date: Sat, 7 Jun 2014 16:09:26 -0500 Subject: [PATCH 397/629] #5 Remove Import/export functionality. --- flag.api.php | 12 ---- flag.module | 5 -- flag.routing.yml | 16 ------ src/Form/FlagExportForm.php | 78 -------------------------- src/Form/FlagImportForm.php | 108 ------------------------------------ 5 files changed, 219 deletions(-) delete mode 100644 src/Form/FlagExportForm.php delete mode 100644 src/Form/FlagImportForm.php diff --git a/flag.api.php b/flag.api.php index 88aef7a..9eaea26 100644 --- a/flag.api.php +++ b/flag.api.php @@ -360,15 +360,3 @@ function hook_flag_reset($flag, $entity_id, $rows) { function hook_flag_javascript_info_alter() { } - -/** - * Alter a flag object that is being prepared for exporting. - * - * @param $flag - * The flag object. - * - * @see flag_export_flags() - */ -function hook_flag_export_alter($flag) { - -} diff --git a/flag.module b/flag.module index d65bdc3..009bb16 100644 --- a/flag.module +++ b/flag.module @@ -283,11 +283,6 @@ function flag_permission() { 'title' => t('Administer flags'), 'description' => t('Create and edit site-wide flags.'), ), - 'use flag import' => array( - 'title' => t('Use flag importer'), - 'description' => t('Access the flag import functionality.'), - 'restrict access' => TRUE, - ), ); $flags = \Drupal::service('flag')->getFlags(); diff --git a/flag.routing.yml b/flag.routing.yml index 01c585c..a259e8c 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -38,22 +38,6 @@ flag.delete: requirements: _entity_access: 'flag_flag.update' -flag.import: - path: '/admin/structure/flags/import' - defaults: - _form: '\Drupal\flag\Form\FlagImportForm' - _title: 'Import Flags' - requirements: - _permission: 'use flag import' - -flag.export: - path: '/admin/structure/flags/export' - defaults: - _form: '\Drupal\flag\Form\FlagExportForm' - _title: 'Export Flags' - requirements: - _permission: 'use flag import' - flag_link_flag.html: path: '/flag/flag/{flag_id}/{entity_id}' defaults: diff --git a/src/Form/FlagExportForm.php b/src/Form/FlagExportForm.php deleted file mode 100644 index 93acc6b..0000000 --- a/src/Form/FlagExportForm.php +++ /dev/null @@ -1,78 +0,0 @@ - 'checkboxes', - '#title' => t('Flags to export'), - '#options' => drupal_map_assoc(array_keys(flag_get_flags())), - '#description' => t('Exporting your flags is useful for moving flags from one site to another, or when including your flag definitions in a module.'), - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Export'), - ); - } - } - - // @todo: Move to another controller - if (isset($flags)) { - $code = flag_export_flags($flags); - - // Link to the Features page if module is present, otherwise link to the - // Drupal project page. - $features_link = module_exists('features') ? url('admin/build/features') : url('http://drupal.org/project/features'); - - $form['export'] = array( - '#type' => 'textarea', - '#title' => t('Flag exports'), - '#description' => t('Use the exported code to later import it. Exports can be included in modules using hook_flag_default_flags() or using the Features module.', array('@import-flag' => url(FLAG_ADMIN_PATH . '/import'), '@features-url' => $features_link)), - '#value' => $code, - '#rows' => 15, - ); - } - - return $form; - - } - - public function submitForm(array &$form, array &$form_state) { - $form_state['rebuild'] = TRUE; - } - -} \ No newline at end of file diff --git a/src/Form/FlagImportForm.php b/src/Form/FlagImportForm.php deleted file mode 100644 index 3b20956..0000000 --- a/src/Form/FlagImportForm.php +++ /dev/null @@ -1,108 +0,0 @@ - t('Flag import code'), - '#type' => 'textarea', - '#default_value' => '', - '#rows' => 15, - '#required' => TRUE, - '#description' => t('Paste the code from a flag export here to import it into you site. Flags imported with the same name will update existing flags. Flags with a new name will be created.', array('@export-url' => url(FLAG_ADMIN_PATH . '/export'))), - ); - $form['submit'] = array( - '#value' => t('Import'), - '#type' => 'submit', - ); - - return $form; - } - - public function validateForm(array &$form, array &$form_state) { - $flags = array(); - ob_start(); - eval($form_state['values']['import']); - ob_end_clean(); - - if (!isset($flags) || !is_array($flags)) { - form_set_error('import', t('A valid list of flags could not be found in the import code.')); - return; - } - - // Create the flag object. - foreach ($flags as $flag_name => $flag_info) { - // Backward compatibility: old exported flags have their names in $flag_info - // instead, so we use the += operator to not overwrite it. - $flag_info += array( - 'name' => $flag_name, - ); - $new_flag = AbstractFlag::factory_by_array($flag_info); - - // Give new flags with the same name a matching FID, which tells Flag to - // update the existing flag, rather than creating a new one. - if ($existing_flag = flag_get_flag($new_flag->name)) { - $new_flag->fid = $existing_flag->fid; - } - - if ($errors = $new_flag->validate()) { - $message = t('The import of the %flag flag failed because the following errors were encountered during the import:', array('%flag' => $new_flag->name)); - $message_errors = array(); - foreach ($errors as $field => $field_errors) { - foreach ($field_errors as $error) { - $message_errors[] = $error['message']; - } - } - form_set_error('import', $message . theme('item_list', array('items' => $message_errors))); - } - else { - // Save the new flag for the submit handler. - $form_state['flags'][] = $new_flag; - } - } - } - - public function submitForm(array &$form, array &$form_state) { - module_load_include('inc', 'flag', 'includes/flag.admin'); - - // Build up values for the cache clear. - $entity_types = array(); - $new = FALSE; - - foreach ($form_state['flags'] as $flag) { - $flag->save(); - if (!empty($flag->status)) { - $flag->enable(); - } - if ($flag->is_new) { - drupal_set_message(t('Flag @name has been imported.', array('@name' => $flag->name))); - $new = TRUE; - } - else { - drupal_set_message(t('Flag @name has been updated.', array('@name' => $flag->name))); - } - $entity_types[] = $flag->entity_type; - } - _flag_clear_cache($entity_types, $new); - - $form_state['redirect'] = FLAG_ADMIN_PATH; - } - -} \ No newline at end of file From 95d0176d792622784e70e38af2ee3a55ab408637 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 7 Jun 2014 16:31:47 -0500 Subject: [PATCH 398/629] Working flag views relationship and link field. --- flag.views.inc | 11 ++++---- src/Plugin/views/field/FlagViewsLinkField.php | 28 +++++++++++++++---- .../relationship/FlagViewsRelationship.php | 8 ++++-- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 9775e38..9910896 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -63,15 +63,14 @@ function flag_views_data() { ), ); -/* // Flag content links. - $data['flagging']['ops'] = array( - 'title' => t('Flag link'), - 'help' => t('Display flag/unflag link.'), + $data['flagging']['link_flag'] = array( 'field' => array( - 'handler' => 'flag_handler_field_ops', + 'title' => t('Flag Links'), + 'help' => t('Display flag/unflag link.'), + 'id' => 'flag_link', ), - );*/ + ); return $data; } diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index 74e7913..182f71d 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -60,24 +60,40 @@ public function buildOptionsForm(&$form, &$form_state) { parent::buildOptionsForm($form, $form_state); } + public function query() { + // Intentionally do nothing here since we're only providing a link and not + // querying against a real table column. + } + /** * @param ResultRow $values * @return string|void */ public function render(ResultRow $values) { - $comment = $this->getEntity($values); - return $this->renderLink($comment, $values); + //$entity = $this->getEntity($values); + return $this->renderLink($values->_entity, $values); } /** * @param $data * @param ResultRow $values */ - protected function renderLink($data, ResultRow $values) { - if ($node->access('view')) { - $text = !empty($this->options['text']) ? $this->options['text'] : t('View'); - return $text; + protected function renderLink($entity, ResultRow $values) { + if (empty($entity)) { // || !$entity->access('view')) { + return t('N/A'); } + + $flag = $this->getFlag(); + $linkTypePlugin = $flag->getLinkTypePlugin(); + $action = 'flag'; + + if ($flag->isFlagged($entity)) { + $action = 'unflag'; + } + + $link = $linkTypePlugin->renderLink($action, $flag, $entity); + + return $link; } } \ No newline at end of file diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index bd495ae..6ff8cd3 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -84,7 +84,7 @@ public function query() { 'numeric' => TRUE, ); - if ($this->definition['user_scope'] == 'current' && !$flag->isGlobal()) { + if ($this->options['user_scope'] == 'current' && !$flag->isGlobal()) { $this->definition['extra'][] = array( 'field' => 'uid', 'value' => '***CURRENT_USER***', @@ -108,8 +108,10 @@ public function query() { } - protected function getFlag() { + public function getFlag() { $flaggable = $this->definition['flaggable']; - $this->options['flag'] = \Drupal::service('flag')->getFlags($flaggable); + $flag = \Drupal::service('flag')->getFlags($flaggable); + $this->options['flag'] = $flag; + return current($flag); } } \ No newline at end of file From d90a60550670af15c3c9f755acabbc9b1cba1497 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 7 Jun 2014 17:59:59 -0500 Subject: [PATCH 399/629] Additional non-working flag view handlers. --- flag.views.inc | 21 +++++++++ .../views/field/FlagViewsFlaggedField.php | 44 +++++++++++++++++ .../views/sort/FlagViewsSortFlagged.php | 47 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 src/Plugin/views/field/FlagViewsFlaggedField.php create mode 100644 src/Plugin/views/sort/FlagViewsSortFlagged.php diff --git a/flag.views.inc b/flag.views.inc index 9910896..dcb5860 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -72,6 +72,27 @@ function flag_views_data() { ), ); + // Specialized is null/is not null filter. + $data['flagging']['flagged'] = array( + 'title' => t('Flagged'), + 'real field' => 'uid', + 'field' => array( + 'id' => 'flag_flagged', + 'label' => t('Flagged'), + 'help' => t('A boolean field to show whether the flag is set or not.'), + ), /* + 'filter' => array( + 'handler' => 'flag_handler_filter_flagged', + 'label' => t('Flagged'), + 'help' => t('Filter to ensure content has or has not been flagged.'), + ),*/ + 'sort' => array( + 'id' => 'flag_sort', + 'label' => t('Flagged'), + 'help' => t('Sort by whether entities have or have not been flagged.'), + ), + ); + return $data; } diff --git a/src/Plugin/views/field/FlagViewsFlaggedField.php b/src/Plugin/views/field/FlagViewsFlaggedField.php new file mode 100644 index 0000000..0056aa4 --- /dev/null +++ b/src/Plugin/views/field/FlagViewsFlaggedField.php @@ -0,0 +1,44 @@ + 1); + return $options; + } + + public function buildOptionsForm(&$form, &$form_state) { + parent::buildOptionsForm($form, $form_state); + $form['value']['#type'] = 'radios'; + $form['value']['#title'] = t('Status'); + $form['value']['#options'] = array( + 1 => t('Flagged'), + 0 => t('Not flagged'), + 'All' => t('All'), + ); + $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; + $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; + } + + public function query() { + $operator = $this->value ? 'IS NOT' : 'IS'; + $this->query->addWhere($this->options['group'], $this->relationship . '.uid', NULL, $operator . ' NULL'); + } +} \ No newline at end of file diff --git a/src/Plugin/views/sort/FlagViewsSortFlagged.php b/src/Plugin/views/sort/FlagViewsSortFlagged.php new file mode 100644 index 0000000..2b763c1 --- /dev/null +++ b/src/Plugin/views/sort/FlagViewsSortFlagged.php @@ -0,0 +1,47 @@ + t('Unflagged first'), + 'DESC' => t('Flagged first'), + ); + } + + /** + * Display whether or not the sort order is ascending or descending + */ + function adminSummary() { + if (!empty($this->options['exposed'])) { + return t('Exposed'); + } + + // Get the labels defined in sortOptions(). + $sort_options = $this->sortOptions(); + return $sort_options[strtoupper($this->options['order'])]; + } + + public function query() { + $this->ensureMyTable(); + + $this->query->addOrderBy(NULL, "($this->tableAlias.uid IS NOT NULL)", $this->options['order']); + } +} \ No newline at end of file From 91d7d8fee3aecd8e2e5708f82d346aa8f0486180 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Jun 2014 13:42:09 -0500 Subject: [PATCH 400/629] Working views flagged field. --- flag.views.inc | 176 ++++-------------- .../views/field/FlagViewsFlaggedField.php | 30 +-- 2 files changed, 47 insertions(+), 159 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index dcb5860..54068a0 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -9,6 +9,8 @@ function flag_views_data() { $data = array(); $data['flagging']['table']['group'] = t('Flag'); + $data['flag_counts']['table']['group'] = t('Flaggings'); + $data['flagging']['table']['join'] = array( 'node' => array( 'type' => 'LEFT', @@ -93,6 +95,42 @@ function flag_views_data() { ), ); + $data['flag_counts']['count'] = array( + 'title' => t('Flag counter'), + 'help' => t('The number of times a piece of content is flagged by any user.'), + 'field' => array( + 'id' => 'numeric', +// 'click sortable' => TRUE, + ), + /*'sort' => array( + 'id' => 'groupby_numeric', + ), + 'filter' => array( + 'id' => 'numeric', + ), + 'argument' => array( + 'id' => 'numeric', + ),*/ + ); + + $data['flag_counts']['last_updated'] = array( + 'title' => t('Time last flagged'), + 'help' => t('The time a piece of content was most recently flagged by any user.'), + 'field' => array( + 'id' => 'date', + //'click sortable' => TRUE, + ), + /*'sort' => array( + 'id' => 'date', + ), + 'filter' => array( + 'id' => 'date', + ), + 'argument' => array( + 'id' => 'date', + ),*/ + ); + return $data; } @@ -127,141 +165,3 @@ function flag_views_data_alter(&$data) { } } - - -/* -function flag_views_data() { - $data = array(); - - - - - $data['flagging']['table']['group'] = t('Flags'); - $data['flagging']['table']['base'] = array( - 'field' => 'id', - 'title' => t('Flag Id'), - 'help' => t('The flagging Id.'), - ); - $data['flagging']['table']['entity type'] = 'flagging'; - -// $data['flag_counts']['table']['group'] = t('Flags'); - - $data['flagging']['uid'] = array( - 'title' => t('User uid'), - 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), - 'relationship' => array( - 'title' => t('User'), - 'help' => t('Relate an item to the user that flagged it.'), - 'id' => 'standard', - 'base' => 'users', - 'field' => uid, - 'label' => t('Flag user'), - ), -/* 'filter' => array( - 'handler' => 'views_handler_filter_user_name', - ), - 'argument' => array( - 'handler' => 'views_handler_argument_numeric', - ), - 'field' => array( - 'handler' => 'views_handler_field_user', - ), - ); - - $data['flagging']['timestamp'] = array( - 'title' => t('Flagged time'), - 'help' => t('Display the time the content was flagged by a user.'), - 'field' => array( - 'handler' => 'views_handler_field_date', - 'click sortable' => TRUE, - ), - 'sort' => array( - 'id' => 'date', - ), - 'filter' => array( - 'id' => 'date', - ), -// 'argument' => array( -// 'handler' => 'views_handler_argument_date', -// ), - ); -/* - // Argument for content ID, used for "Who's flagged this" views. - $data['flagging']['entity_id'] = array( - 'title' => t('Content ID'), - 'help' => t('The unique ID of the object that has been flagged.'), - 'argument' => array( - 'handler' => 'flag_handler_argument_entity_id', - ), - ); - - // Specialized is null/is not null filter. - $data['flagging']['flagged'] = array( - 'title' => t('Flagged'), - 'real field' => 'uid', - 'field' => array( - 'handler' => 'flag_handler_field_flagged', - 'label' => t('Flagged'), - 'help' => t('A boolean field to show whether the flag is set or not.'), - ), - 'filter' => array( - 'handler' => 'flag_handler_filter_flagged', - 'label' => t('Flagged'), - 'help' => t('Filter to ensure content has or has not been flagged.'), - ), - 'sort' => array( - 'handler' => 'flag_handler_sort_flagged', - 'label' => t('Flagged'), - 'help' => t('Sort by whether entities have or have not been flagged.'), - ), - ); - - // Flag content links. - $data['flagging']['ops'] = array( - 'title' => t('Flag link'), - 'help' => t('Display flag/unflag link.'), - 'field' => array( - 'handler' => 'flag_handler_field_ops', - ), - ); - - $data['flag_counts']['count'] = array( - 'title' => t('Flag counter'), - 'help' => t('The number of times a piece of content is flagged by any user.'), - 'field' => array( - 'handler' => 'views_handler_field_numeric', - 'click sortable' => TRUE, - ), - 'sort' => array( - 'handler' => 'views_handler_sort', - ), - 'filter' => array( - 'handler' => 'views_handler_filter_numeric', - ), - 'argument' => array( - 'handler' => 'views_handler_argument_numeric', - ), - ); - - $data['flag_counts']['last_updated'] = array( - 'title' => t('Time last flagged'), - 'help' => t('The time a piece of content was most recently flagged by any user.'), - 'field' => array( - 'handler' => 'views_handler_field_date', - 'click sortable' => TRUE, - ), - 'sort' => array( - 'handler' => 'views_handler_sort_date', - ), - 'filter' => array( - 'handler' => 'views_handler_filter_date', - ), - 'argument' => array( - 'handler' => 'views_handler_argument_date', - ), - ); - - return $data; -} - -*/ \ No newline at end of file diff --git a/src/Plugin/views/field/FlagViewsFlaggedField.php b/src/Plugin/views/field/FlagViewsFlaggedField.php index 0056aa4..eb267c5 100644 --- a/src/Plugin/views/field/FlagViewsFlaggedField.php +++ b/src/Plugin/views/field/FlagViewsFlaggedField.php @@ -8,6 +8,8 @@ namespace Drupal\flag\Plugin\views\field; +use Drupal\views\ViewExecutable; +use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\field\Boolean; /** @@ -18,27 +20,13 @@ */ class FlagViewsFlaggedField extends Boolean { - public function defineOptions() { - $options = parent::defineOptions(); - $options['value'] = array('default' => 1); - return $options; - } - - public function buildOptionsForm(&$form, &$form_state) { - parent::buildOptionsForm($form, $form_state); - $form['value']['#type'] = 'radios'; - $form['value']['#title'] = t('Status'); - $form['value']['#options'] = array( - 1 => t('Flagged'), - 0 => t('Not flagged'), - 'All' => t('All'), - ); - $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; - $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; - } + public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + parent::init($view, $display, $options); - public function query() { - $operator = $this->value ? 'IS NOT' : 'IS'; - $this->query->addWhere($this->options['group'], $this->relationship . '.uid', NULL, $operator . ' NULL'); + // Add our boolean labels. + $this->formats['flag'] = array(t('Flagged'), t('Not flagged')); + // TODO: We could probably lift the '(Un)Flagged message' strings from the + // flag object, but a) we need to lift that from the relationship we're on + // and b) they will not necessarily make sense in a static context. } } \ No newline at end of file From f5f28f4f115ab9ac5cb345264043a0ea8f08d1c4 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Jun 2014 14:28:10 -0500 Subject: [PATCH 401/629] Working flag views sort handler. --- flag.views.inc | 8 ++++---- src/Plugin/views/relationship/FlagViewsRelationship.php | 2 +- src/Plugin/views/sort/FlagViewsSortFlagged.php | 6 ++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 54068a0..d61fdbe 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -82,12 +82,12 @@ function flag_views_data() { 'id' => 'flag_flagged', 'label' => t('Flagged'), 'help' => t('A boolean field to show whether the flag is set or not.'), - ), /* - 'filter' => array( - 'handler' => 'flag_handler_filter_flagged', + ), + 'id' => array( + 'handler' => 'flag_filter', 'label' => t('Flagged'), 'help' => t('Filter to ensure content has or has not been flagged.'), - ),*/ + ), 'sort' => array( 'id' => 'flag_sort', 'label' => t('Flagged'), diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 6ff8cd3..05e4d28 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -90,7 +90,7 @@ public function query() { 'value' => '***CURRENT_USER***', 'numeric' => TRUE, ); - $flag_roles = user_roles(FALSE, "flag $flag->name"); + $flag_roles = user_roles(FALSE, "flag $flag->label"); if (isset($flag_roles[DRUPAL_ANONYMOUS_RID])) { // Disable page caching for anonymous users. drupal_page_is_cacheable(FALSE); diff --git a/src/Plugin/views/sort/FlagViewsSortFlagged.php b/src/Plugin/views/sort/FlagViewsSortFlagged.php index 2b763c1..5253a28 100644 --- a/src/Plugin/views/sort/FlagViewsSortFlagged.php +++ b/src/Plugin/views/sort/FlagViewsSortFlagged.php @@ -5,6 +5,8 @@ * Contains the flagged content sort handler. */ +namespace Drupal\flag\Plugin\views\sort; + use Drupal\views\Plugin\views\sort\SortPluginBase; /** @@ -12,7 +14,7 @@ * * @ViewsSort("flag_sort") */ -class FlagViewsSortFlagged extends SortPluginBase { +class FlagViewsSortFlagged extends SortPluginBase { /** * Provide a list of options for the default sort form. @@ -42,6 +44,6 @@ function adminSummary() { public function query() { $this->ensureMyTable(); - $this->query->addOrderBy(NULL, "($this->tableAlias.uid IS NOT NULL)", $this->options['order']); + $this->query->addOrderBy(NULL, "$this->tableAlias.uid", $this->options['order']); } } \ No newline at end of file From d973c0cd6d3274cc42f50b742908da01fe4b983b Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Jun 2014 15:30:37 -0500 Subject: [PATCH 402/629] Working flag views filter. --- flag.views.inc | 4 +- src/Plugin/views/filter/FlagViewsFilter.php | 47 +++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/Plugin/views/filter/FlagViewsFilter.php diff --git a/flag.views.inc b/flag.views.inc index d61fdbe..e1adf4f 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -83,8 +83,8 @@ function flag_views_data() { 'label' => t('Flagged'), 'help' => t('A boolean field to show whether the flag is set or not.'), ), - 'id' => array( - 'handler' => 'flag_filter', + 'filter' => array( + 'id' => 'flag_filter', 'label' => t('Flagged'), 'help' => t('Filter to ensure content has or has not been flagged.'), ), diff --git a/src/Plugin/views/filter/FlagViewsFilter.php b/src/Plugin/views/filter/FlagViewsFilter.php new file mode 100644 index 0000000..c3fb36c --- /dev/null +++ b/src/Plugin/views/filter/FlagViewsFilter.php @@ -0,0 +1,47 @@ + 1); + return $options; + } + + public function buildOptionsForm(&$form, &$form_state) { + parent::buildOptionsForm($form, $form_state); + $form['value']['#type'] = 'radios'; + $form['value']['#title'] = t('Status'); + $form['value']['#options'] = array( + 1 => t('Flagged'), + 0 => t('Not flagged'), + // @todo Find out what in the hell filter type ALL is supposed to do. + //'All' => t('All'), + ); + $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; + $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; + } + + + public function query() { + $this->ensureMyTable(); + + $operator = $this->options['value'] ? 'IS NOT' : 'IS'; + $operator .= ' NULL'; + + $this->query->addWhere($this->options['group'], "$this->tableAlias.uid", NULL, $operator); + } +} \ No newline at end of file From 67ea08182098913165e1c728dae5f8cc9ccbaca1 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Jun 2014 15:53:57 -0500 Subject: [PATCH 403/629] PSR-4 for flag_bookmark. --- .../config/install/flag_bookmark.flag_flag.bookmark.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename flag_bookmark/{lib/Drupal/flag_bookmark => src}/config/install/flag_bookmark.flag_flag.bookmark.yml (100%) diff --git a/flag_bookmark/lib/Drupal/flag_bookmark/config/install/flag_bookmark.flag_flag.bookmark.yml b/flag_bookmark/src/config/install/flag_bookmark.flag_flag.bookmark.yml similarity index 100% rename from flag_bookmark/lib/Drupal/flag_bookmark/config/install/flag_bookmark.flag_flag.bookmark.yml rename to flag_bookmark/src/config/install/flag_bookmark.flag_flag.bookmark.yml From 7693590b31f7374d56e253d790ed3fc01382d1ad Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Jun 2014 15:58:53 -0500 Subject: [PATCH 404/629] Added default flag_bookmark view. --- .../flag_bookmark.view.flag_bookmark.yml | 500 ++++++++++++++++++ 1 file changed, 500 insertions(+) create mode 100644 flag_bookmark/src/config/install/flag_bookmark.view.flag_bookmark.yml diff --git a/flag_bookmark/src/config/install/flag_bookmark.view.flag_bookmark.yml b/flag_bookmark/src/config/install/flag_bookmark.view.flag_bookmark.yml new file mode 100644 index 0000000..f97277d --- /dev/null +++ b/flag_bookmark/src/config/install/flag_bookmark.view.flag_bookmark.yml @@ -0,0 +1,500 @@ +base_field: nid +base_table: node +core: 8.x +description: '' +status: true +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + provider: views + display_options: + access: + type: perm + options: + perm: 'access content' + provider: user + dependencies: { } + cache: + type: none + options: { } + provider: views + dependencies: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + slave: false + query_comment: false + query_tags: { } + provider: views + dependencies: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + provider: views + dependencies: { } + pager: + type: full + options: + items_per_page: 25 + offset: 0 + id: 0 + total_pages: null + tags: + previous: '‹ previous' + next: 'next ›' + first: '« first' + last: 'last »' + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 20, 40, 60' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + title: title + created: created + changed: changed + created_1: created_1 + info: + title: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + created: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + changed: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + created_1: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: '-1' + empty_table: false + row: + type: fields + fields: + type: + id: type + table: node_field_data + field: type + relationship: none + group_type: group + admin_label: '' + dependencies: + module: + - node + label: Type + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: '' + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_node: false + machine_name: '0' + plugin_id: node_type + provider: node + title: + id: title + table: node_field_data + field: title + provider: node + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + link_to_node: 1 + relationship: none + group_type: group + admin_label: '' + dependencies: { } + label: Title + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + name: + id: name + table: users + field: name + relationship: uid + group_type: group + admin_label: '' + dependencies: + module: + - user + label: Author + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: '' + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + link_to_user: true + overwrite_anonymous: false + anonymous_text: '' + format_username: true + plugin_id: user_name + provider: user + comment_count: + id: comment_count + table: comment_entity_statistics + field: comment_count + relationship: none + group_type: group + admin_label: '' + dependencies: + module: + - views + - views + - views + label: Replies + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: '' + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '0' + hide_empty: false + empty_zero: true + hide_alter_empty: false + set_precision: false + precision: 0 + decimal: . + separator: ',' + format_plural: false + format_plural_singular: '1' + format_plural_plural: '@count' + prefix: '' + suffix: '' + plugin_id: numeric + provider: views + link_flag: + id: link_flag + table: flagging + field: link_flag + relationship: flag_content_rel + group_type: group + admin_label: '' + dependencies: + module: + - flag + - flag + label: Ops + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: '' + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + text: '' + plugin_id: flag_link + provider: flag + filters: + status: + value: true + table: node_field_data + field: status + provider: node + id: status + expose: + operator: '' + group: 1 + flagged: + id: flagged + table: flagging + field: flagged + relationship: flag_content_rel + group_type: group + admin_label: '' + dependencies: + module: + - flag + - flag + - flag + - flag + - flag + - flag + - flag + - flag + - flag + operator: '=' + value: '1' + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: flag_filter + provider: flag + sorts: { } + title: 'My Bookmarks' + header: { } + footer: { } + empty: { } + relationships: + flag_content_rel: + id: flag_content_rel + table: node_field_data + field: flag_content_rel + relationship: none + group_type: group + admin_label: Flags + dependencies: + module: + - flag + - flag + required: false + flag: 'Stuff! custom' + user_scope: current + plugin_id: flag_relationship + provider: flag + uid: + id: uid + table: node_field_data + field: uid + relationship: none + group_type: group + admin_label: author + dependencies: + module: + - views + required: true + plugin_id: standard + provider: views + arguments: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + provider: views + display_options: + path: bookmarks + menu: + type: normal + title: 'My Bookmarks' + description: '' + name: main + weight: 0 + context: '0' +label: flag_bookmark +module: views +id: flag_bookmark +tag: '' +langcode: en +dependencies: + module: + - flag + - node + - user From 45e2b240c7d9068bc6739ee6337469e444a62c4a Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 8 Jun 2014 15:59:51 -0500 Subject: [PATCH 405/629] Removed flag_bookmark.views_default.inc --- .../includes/flag_bookmark.views_default.inc | 284 ------------------ 1 file changed, 284 deletions(-) delete mode 100644 flag_bookmark/includes/flag_bookmark.views_default.inc diff --git a/flag_bookmark/includes/flag_bookmark.views_default.inc b/flag_bookmark/includes/flag_bookmark.views_default.inc deleted file mode 100644 index e656ca3..0000000 --- a/flag_bookmark/includes/flag_bookmark.views_default.inc +++ /dev/null @@ -1,284 +0,0 @@ - array( - 'id' => 'type', - 'table' => 'node', - 'field' => 'type', - 'label' => 'Type', - ), - 'title' => array( - 'id' => 'title', - 'table' => 'node', - 'field' => 'title', - 'label' => 'Title', - 'link_to_node' => 1, - ), - 'name' => array( - 'label' => 'Author', - 'link_to_user' => 1, - 'id' => 'name', - 'table' => 'users', - 'field' => 'name', - 'relationship' => 'uid_1', - ), - ); - - $style_options = array( - 'grouping' => '', - 'override' => 0, - 'sticky' => 1, - 'columns' => array(), - 'default' => 'title', - 'order' => 'asc', - 'columns' => array( - 'type' => 'type', - 'title' => 'title', - 'name' => 'name', - ), - 'info' => array( - 'type' => array( - 'sortable' => TRUE, - ), - 'title' => array( - 'sortable' => TRUE, - ), - 'name' => array( - 'sortable' => TRUE, - ), - ), - 'override' => FALSE, - 'order' => 'asc', - ); - - $filters = array( - 'status' => array( - 'operator' => '=', - 'value' => 1, - 'group' => '0', - 'exposed' => FALSE, - 'expose' => array( - 'operator' => FALSE, - 'label' => '', - ), - 'id' => 'status', - 'table' => 'node', - 'field' => 'status', - 'relationship' => 'none', - ), - ); - - $relationships = array( - 'flag_content_rel' => array( - 'label' => 'bookmarks', - 'required' => 1, - 'flag' => 'bookmarks', - 'user_scope' => 'current', - 'id' => 'flag_content_rel', - 'table' => 'node', - 'field' => 'flag_content_rel', - 'relationship' => 'none', - 'override' => array( - 'button' => 'Override', - ), - ), - 'uid_1' => array( - 'label' => 'author', - 'required' => 0, - 'id' => 'uid_1', - 'table' => 'node', - 'field' => 'uid', - ), - ); - - $access = array( - 'type' => 'perm', - 'perm' => 'flag bookmarks', - ); - - // Additional fields and style options if comment exists. - if (module_exists('comment')) { - $fields += array( - 'comment_count' => array( - 'id' => 'comment_count', - 'table' => 'node_comment_statistics', - 'field' => 'comment_count', - 'label' => 'Replies', - ), - 'last_comment_timestamp' => array( - 'id' => 'last_comment_timestamp', - 'table' => 'node_comment_statistics', - 'field' => 'last_comment_timestamp', - 'label' => 'Last Post', - ), - ); - - $style_options['default'] = 'last_comment_timestamp'; - $style_options['order'] = 'desc'; - $style_options['info'] += array( - 'comment_count' => array( - 'sortable' => TRUE, - ), - 'last_comment_timestamp' => array( - 'sortable' => TRUE, - ), - ); - $style_options['columns'] += array( - 'comment_count' => 'comment_count', - 'last_comment_timestamp' => 'last_comment_timestamp', - ); - } - - /* Individual users user/%/bookmarks tab. */ - - // Additional relationship for this view. - $relationships_tab = $relationships; - $relationships_tab['flag_content_rel']['user_scope'] = 'any'; - $relationships_tab += array( - 'uid' => array( - 'label' => 'bookmarks_user', - 'required' => 1, - 'id' => 'uid', - 'table' => 'flagging', - 'field' => 'uid', - 'relationship' => 'flag_content_rel', - ), - ); - - // Additional argument for this view. - $arguments_tab = array( - 'uid' => array( - 'default_action' => 'empty', - 'style_plugin' => 'default_summary', - 'style_options' => array(), - 'wildcard' => 'all', - 'wildcard_substitution' => 'All', - 'title' => '%1\'s bookmarks', - 'default_argument_type' => 'fixed', - 'default_argument' => '', - 'validate_type' => 'none', - 'validate_fail' => 'not found', - 'break_phrase' => 0, - 'not' => 0, - 'id' => 'uid', - 'table' => 'users', - 'field' => 'uid', - 'override' => array( - 'button' => 'Override', - ), - 'relationship' => 'uid', - 'default_options_div_prefix' => '', - 'default_argument_user' => 0, - 'default_argument_fixed' => '', - 'default_argument_php' => '', - ), - ); - - $view = new view; - $view->name = 'flag_bookmarks_tab'; - $view->description = "Provides a tab on all users' profile pages containing bookmarks for that user."; - $view->tag = 'flag'; - $view->view_php = ''; - $view->base_table = 'node'; - $view->is_cacheable = FALSE; - $view->api_version = 2; - $view->disabled = FALSE; - $handler = $view->new_display('default', 'Defaults', 'default'); - $handler->override_option('relationships', $relationships_tab); - $handler->override_option('fields', $fields); - $handler->override_option('arguments', $arguments_tab); - $handler->override_option('filters', $filters); - $handler->override_option('access', $access); - $handler->override_option('title', 'User bookmarks'); - $handler->override_option('empty', 'This user has not yet bookmarked any content.'); - $handler->override_option('empty_format', filter_fallback_format()); - $handler->override_option('items_per_page', '25'); - $handler->override_option('use_pager', TRUE); - $handler->override_option('style_plugin', 'table'); - $handler->override_option('style_options', $style_options); - - $handler = $view->new_display('page', 'Page', 'page'); - $handler->override_option('path', 'user/%/bookmarks'); - $handler->override_option('menu', array( - 'type' => 'tab', - 'title' => 'Bookmarks', - 'weight' => '0', - 'name' => 'navigation', - )); - $handler->override_option('tab_options', array( - 'type' => 'none', - 'title' => NULL, - 'weight' => NULL, - )); - - $views[$view->name] = $view; - - /* User bookmarks page with Ops. */ - - // Add some unique options for this view. - $style_options['columns'] += array('ops' => 'ops'); - $fields += array( - 'ops' => array( - 'label' => 'Ops', - 'id' => 'ops', - 'table' => 'flagging', - 'field' => 'ops', - 'relationship' => 'flag_content_rel', - ), - ); - - $view = new view; - $view->name = 'flag_' . $flag->name; - $view->description = "A page listing the current user's bookmarks at /bookmarks."; - $view->tag = 'flag'; - $view->view_php = ''; - $view->base_table = 'node'; - $view->is_cacheable = '0'; - $view->api_version = 2; - $view->disabled = FALSE; - $handler = $view->new_display('default', 'Defaults', 'default'); - $handler->override_option('relationships', $relationships); - $handler->override_option('fields', $fields); - $handler->override_option('filters', $filters); - $handler->override_option('access', $access); - $handler->override_option('title', t('My bookmarks')); - $handler->override_option('items_per_page', '25'); - $handler->override_option('use_pager', TRUE); - $handler->override_option('empty', 'You have not yet bookmarked any content. Click the "' . $flag->flag_short . '" link when viewing a piece of content to add it to this list.'); - $handler->override_option('empty_format', filter_fallback_format()); - $handler->override_option('style_plugin', 'table'); - $handler->override_option('style_options', $style_options); - $handler = $view->new_display('page', 'Page', 'page'); - $handler->override_option('path', 'bookmarks'); - $handler->override_option('menu', array( - 'type' => 'normal', - 'title' => t('My bookmarks'), - 'weight' => '0', - )); - $handler->override_option('tab_options', array( - 'type' => 'none', - 'title' => NULL, - 'weight' => NULL, - )); - - $views[$view->name] = $view; - - return $views; -} From 934ab3ad7734bb794f82465e95f2cf13ba6dac22 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 10 Jun 2014 17:18:01 -0500 Subject: [PATCH 406/629] Moved and renamed default yml files. --- .../install/flag.flag_flag.bookmark.yml} | 0 .../install/views.view.flag_bookmark.yml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename flag_bookmark/{src/config/install/flag_bookmark.flag_flag.bookmark.yml => config/install/flag.flag_flag.bookmark.yml} (100%) rename flag_bookmark/{src/config/install/flag_bookmark.view.flag_bookmark.yml => config/install/views.view.flag_bookmark.yml} (100%) diff --git a/flag_bookmark/src/config/install/flag_bookmark.flag_flag.bookmark.yml b/flag_bookmark/config/install/flag.flag_flag.bookmark.yml similarity index 100% rename from flag_bookmark/src/config/install/flag_bookmark.flag_flag.bookmark.yml rename to flag_bookmark/config/install/flag.flag_flag.bookmark.yml diff --git a/flag_bookmark/src/config/install/flag_bookmark.view.flag_bookmark.yml b/flag_bookmark/config/install/views.view.flag_bookmark.yml similarity index 100% rename from flag_bookmark/src/config/install/flag_bookmark.view.flag_bookmark.yml rename to flag_bookmark/config/install/views.view.flag_bookmark.yml From fd39acbd8708c20c708d86f13bec5d825bfd6433 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 17 Jun 2014 20:40:24 -0500 Subject: [PATCH 407/629] Plugin manager changes due to https://drupal.org/node/2281905 --- .../config/install/views.view.flag_bookmark.yml | 1 - src/ActionLinkPluginManager.php | 2 +- src/FlagTypePluginManager.php | 2 +- tests/src/FlagTestBase.php | 16 ++++++++++++++++ 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 tests/src/FlagTestBase.php diff --git a/flag_bookmark/config/install/views.view.flag_bookmark.yml b/flag_bookmark/config/install/views.view.flag_bookmark.yml index f97277d..7224fb8 100644 --- a/flag_bookmark/config/install/views.view.flag_bookmark.yml +++ b/flag_bookmark/config/install/views.view.flag_bookmark.yml @@ -9,7 +9,6 @@ display: id: default display_title: Master position: 0 - provider: views display_options: access: type: perm diff --git a/src/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php index 89ad00d..600d17a 100644 --- a/src/ActionLinkPluginManager.php +++ b/src/ActionLinkPluginManager.php @@ -23,7 +23,7 @@ class ActionLinkPluginManager extends DefaultPluginManager { public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { parent::__construct('Plugin/ActionLink', $namespaces, $module_handler, 'Drupal\flag\Annotation\ActionLinkType'); $this->alterInfo('flag_link_type_info'); - $this->setCacheBackend($cache_backend, $language_manager, 'flag_link_type_plugins'); + $this->setCacheBackend($cache_backend, 'flag_link_type_plugins'); } public function getAllLinkTypes() { diff --git a/src/FlagTypePluginManager.php b/src/FlagTypePluginManager.php index 35ccadf..3dd7d9b 100644 --- a/src/FlagTypePluginManager.php +++ b/src/FlagTypePluginManager.php @@ -32,7 +32,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac parent::__construct('Plugin/Flag', $namespaces, $module_handler, 'Drupal\flag\Annotation\FlagType'); //$this->alterInfo('flag_type_info'); - $this->setCacheBackend($cache_backend, $language_manager, 'flag'); + $this->setCacheBackend($cache_backend, 'flag'); } public function getAllFlagTypes() { diff --git a/tests/src/FlagTestBase.php b/tests/src/FlagTestBase.php new file mode 100644 index 0000000..7bdb96c --- /dev/null +++ b/tests/src/FlagTestBase.php @@ -0,0 +1,16 @@ + Date: Tue, 17 Jun 2014 20:59:35 -0500 Subject: [PATCH 408/629] Moved and fixed flag schema due to https://drupal.org/node/2016679. --- {src/config => config}/schema/flag.schema.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename {src/config => config}/schema/flag.schema.yml (95%) diff --git a/src/config/schema/flag.schema.yml b/config/schema/flag.schema.yml similarity index 95% rename from src/config/schema/flag.schema.yml rename to config/schema/flag.schema.yml index 9bc3030..4ed192b 100644 --- a/src/config/schema/flag.schema.yml +++ b/config/schema/flag.schema.yml @@ -1,5 +1,5 @@ -flag.flag.*: - type: mapping +flag.flag_flag.*: + type: config_entity label: 'Flag' mapping: id: From 6d4bcd39d47501b540998e764725cf76310093e7 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Thu, 19 Jun 2014 11:17:42 +0200 Subject: [PATCH 409/629] Fixed linktype settings form in administration. Now functioning using ajax sub forms. --- src/Form/FlagFormBase.php | 58 ++++++++++++++++++++++++++- src/Form/FlaggingConfirmForm.php | 2 +- src/Plugin/ActionLink/ConfirmForm.php | 10 ++--- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 7d39287..f50b0e9 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -44,6 +44,14 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) 'exists' => 'flag_load_by_id', ), '#disabled' => !$flag->isNew(), + '#submit' => array(array($this, 'submitSelectPlugin')), + '#required' => TRUE, + '#executes_submit_callback' => TRUE, + '#ajax' => array( + 'callback' => array($this, 'updateSelectedPluginType'), + 'wrapper' => 'monitoring-sensor-plugin', + 'method' => 'replace', + ), ); $form['is_global'] = array( @@ -110,6 +118,8 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#weight' => 10, ); + // Switch plugin type in case a different is chosen. + $flag_type_plugin = $flag->getFlagTypePlugin(); $flag_type_def = $flag_type_plugin->getPluginDefinition(); @@ -148,6 +158,13 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) // '#after_build' => array('flag_link_type_options_states'), ); + $form['display']['settings'] = array( + '#type' => 'container', + '#prefix' => '', + '#weight' => 21, + ); + $form = $flag_type_plugin->buildConfigurationForm($form, $form_state); $form['display']['link_type'] = array( @@ -165,12 +182,32 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#attributes' => array( 'class' => array('flag-link-options'), ), + '#limit_validation_errors' => array(array('link_type')), + '#submit' => array(array($this, 'submitSelectPlugin')), + '#required' => TRUE, + '#executes_submit_callback' => TRUE, + '#ajax' => array( + 'callback' => array($this, 'updateSelectedPluginType'), + 'wrapper' => 'link-type-settings-wrapper', + 'event' => 'change', + 'method' => 'replace', + ), + ); + $form['display']['link_type_submit'] = array( + '#type' => 'submit', + '#value' => $this->t('Update'), + '#submit' => array(array($this, 'submitSelectPlugin')), + '#weight' => 20, + '#attributes' => array('class' => array('js-hide')), ); // Add the descriptions to each ratio button element. These attach to the // elements when FormAPI expands them. $action_link_plugin_defs = \Drupal::service('plugin.manager.flag.linktype')->getDefinitions(); foreach ($action_link_plugin_defs as $key => $info) { $form['display']['link_type'][$key]['#description'] = $info['description']; + $form['display']['link_type'][$key]['#submit'] = array(array($this, 'submitSelectPlugin')); + $form['display']['link_type'][$key]['#executes_submit_callback'] = TRUE; + $form['display']['link_type'][$key]['#limit_validation_errors'] = array(array('link_type')); } $action_link_plugin = $flag->getLinkTypePlugin(); @@ -179,6 +216,25 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) return $form; } + /** + * Handles switching the configuration type selector. + */ + public function updateSelectedPluginType($form, &$form_state) { + return $form['display']['settings']; + } + + /** + * Handles submit call when sensor type is selected. + */ + public function submitSelectPlugin(array $form, array &$form_state) { + $this->entity = $this->buildEntity($form, $form_state); + + $form_state['rebuild'] = TRUE; + // @todo: This is necessary because there are two different instances of the + // form object. Core should handle this. + $form_state['build_info']['callback_object'] = $form_state['controller']; + } + /** * Overrides Drupal\Core\Entity\EntityFormController::validate(). */ @@ -266,4 +322,4 @@ public function delete(array $form, array &$form_state) { $form_state['redirect'] = 'admin/structure/flags'; } -} \ No newline at end of file +} diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index 6965763..2af1652 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -82,4 +82,4 @@ public function submitForm(array &$form, array &$form_state) { } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index 5ebfa8c..e3c45d2 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -44,8 +44,7 @@ public function defaultConfiguration() { public function buildConfigurationForm(array $form, array &$form_state) { $form = parent::buildConfigurationForm($form, $form_state); - - $form['display']['link_options_confirm'] = array( + $form['display']['settings']['link_options_confirm'] = array( '#type' => 'fieldset', '#title' => t('Options for the "Confirmation form" link type'), // Any "link type" provider module must put its settings fields inside @@ -53,10 +52,9 @@ public function buildConfigurationForm(array $form, array &$form_state) { // the machine-name of the link type. This is necessary for the // radiobutton's JavaScript dependency feature to work. '#id' => 'link-options-confirm', - '#weight' => 21, ); - $form['display']['link_options_confirm']['flag_confirmation'] = array( + $form['display']['settings']['link_options_confirm']['flag_confirmation'] = array( '#type' => 'textfield', '#title' => t('Flag confirmation message'), '#default_value' => $this->configuration['flag_confirmation'], @@ -65,7 +63,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#required' => TRUE, ); - $form['display']['link_options_confirm']['unflag_confirmation'] = array( + $form['display']['settings']['link_options_confirm']['unflag_confirmation'] = array( '#type' => 'textfield', '#title' => t('Unflag confirmation message'), '#default_value' => $this->configuration['unflag_confirmation'], @@ -91,4 +89,4 @@ public function getUnflagQuestion() { return $this->configuration['unflag_confirmation']; } -} \ No newline at end of file +} \ No newline at end of file From 716e85b8d09b779f0106f94196c61753775a1980 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 19 Jun 2014 21:56:28 -0500 Subject: [PATCH 410/629] Implemented EntityWithPluginBagsInterface for Flag. --- config/schema/flag.schema.yml | 12 ++++++------ src/Entity/Flag.php | 32 +++++++++++++++++++++++++------- src/FlagInterface.php | 5 ++++- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/config/schema/flag.schema.yml b/config/schema/flag.schema.yml index 4ed192b..8f6ec20 100644 --- a/config/schema/flag.schema.yml +++ b/config/schema/flag.schema.yml @@ -38,9 +38,9 @@ flag.flag_flag.*: weight: type: integer label: 'Weight' -# link_type: -# type: sequence -# label: 'Link Type' -# sequence: -# - type: flag.link.[plugin] -# label: 'Flag Link Type's \ No newline at end of file + flag_type: + type: string + label: 'ID of the Flag Type plugin' + link_type: + type: string + label: 'ID of the Link Type plugin' diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index ea87af2..4d4b6a6 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -219,6 +219,16 @@ public function isFlagged(EntityInterface $entity, AccountInterface $account = N return FALSE; } + /** + * + */ + public function getPluginBags() { + return array( + 'flagTypeConfig' => $this->flagTypeBag, + 'linkTypeConfig' => $this->linkTypeBag, + ); + } + /** * Get the flag type plugin for this flag. * @@ -236,7 +246,11 @@ public function getFlagTypePlugin() { */ public function setFlagTypePlugin($pluginID) { $this->flag_type = $pluginID; - $this->flagTypeBag->addInstanceId($pluginID); + //$this->flagTypeBag->addInstanceId($pluginID); + + // Workaround for https://www.drupal.org/node/2288805 + $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), + $this->flag_type, $this->flagTypeConfig); // Get the entity type from the plugin definition. $plugin = $this->getFlagTypePlugin(); @@ -261,7 +275,12 @@ public function getLinkTypePlugin() { */ public function setlinkTypePlugin($pluginID) { $this->link_type = $pluginID; - $this->linkTypeBag->addInstanceId($pluginID); + + //$this->linkTypeBag->addInstanceId($pluginID); + + // Workaround for https://www.drupal.org/node/2288805 + $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), + $this->link_type, $this->linkTypeConfig); } /** @@ -307,7 +326,7 @@ public function getFlaggableEntityType() { */ public function preSave(EntityStorageInterface $storage_controller) { parent::preSave($storage_controller); - +/* // Save the Flag Type configuration. $flagTypePlugin = $this->getFlagTypePlugin(); $this->set('flagTypeConfig', $flagTypePlugin->getConfiguration()); @@ -315,17 +334,16 @@ public function preSave(EntityStorageInterface $storage_controller) { // Save the Link Type configuration. $linkTypePlugin = $this->getLinkTypePlugin(); $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); - +*/ // Reset the render cache for the entity. \Drupal::entityManager() ->getViewBuilder($this->getFlaggableEntityType()) ->resetCache(); } - +/* public function toArray() { $properties = parent::toArray(); $names = array( - 'roles', 'flag_type', 'link_type', 'flagTypeConfig', @@ -338,5 +356,5 @@ public function toArray() { return $properties; } - +*/ } \ No newline at end of file diff --git a/src/FlagInterface.php b/src/FlagInterface.php index 43fcdad..fafd458 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -10,9 +10,10 @@ use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityWithPluginBagsInterface; use Drupal\Core\Session\AccountInterface; -interface FlagInterface extends ConfigEntityInterface { +interface FlagInterface extends ConfigEntityInterface, EntityWithPluginBagsInterface { // todo: Add getters and setters as necessary. @@ -27,4 +28,6 @@ public function getPermissions(); public function isGlobal(); public function setGlobal($isGlobal); + + public function getPluginBags(); } \ No newline at end of file From 7ee32b82ff8939453d3eb2892ba2df9363d98011 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Fri, 20 Jun 2014 16:25:50 +0200 Subject: [PATCH 411/629] Language Manager removed from Plugin managers. --- flag.services.yml | 4 ++-- src/ActionLinkPluginManager.php | 4 ++-- src/FlagTypePluginManager.php | 7 ++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/flag.services.yml b/flag.services.yml index d637bef..9ff8300 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -1,10 +1,10 @@ services: plugin.manager.flag.flagtype: class: Drupal\flag\FlagTypePluginManager - arguments: ['@container.namespaces', '@cache.default', '@language_manager', '@module_handler'] + arguments: ['@container.namespaces', '@cache.default', '@module_handler'] plugin.manager.flag.linktype: class: Drupal\flag\ActionLinkPluginManager - arguments: ['@container.namespaces', '@cache.default', '@language_manager', '@module_handler'] + arguments: ['@container.namespaces', '@cache.default', '@module_handler'] flag: class: Drupal\flag\FlagService arguments: ['@module_handler'] diff --git a/src/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php index 89ad00d..7e6bbec 100644 --- a/src/ActionLinkPluginManager.php +++ b/src/ActionLinkPluginManager.php @@ -20,10 +20,10 @@ class ActionLinkPluginManager extends DefaultPluginManager { /** * {@inheritdoc} */ - public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { + public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { parent::__construct('Plugin/ActionLink', $namespaces, $module_handler, 'Drupal\flag\Annotation\ActionLinkType'); $this->alterInfo('flag_link_type_info'); - $this->setCacheBackend($cache_backend, $language_manager, 'flag_link_type_plugins'); + $this->setCacheBackend($cache_backend, 'flag_link_type_plugins'); } public function getAllLinkTypes() { diff --git a/src/FlagTypePluginManager.php b/src/FlagTypePluginManager.php index 35ccadf..8485eaf 100644 --- a/src/FlagTypePluginManager.php +++ b/src/FlagTypePluginManager.php @@ -10,7 +10,6 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Language\LanguageManager; use Drupal\Core\Plugin\DefaultPluginManager; class FlagTypePluginManager extends DefaultPluginManager { @@ -23,16 +22,14 @@ class FlagTypePluginManager extends DefaultPluginManager { * keyed by the corresponding namespace to look for plugin implementations, * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend instance to use. - * @param \Drupal\Core\Language\LanguageManager $language_manager - * The language manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler to invoke the alter hook with. */ - public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { + public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { parent::__construct('Plugin/Flag', $namespaces, $module_handler, 'Drupal\flag\Annotation\FlagType'); //$this->alterInfo('flag_type_info'); - $this->setCacheBackend($cache_backend, $language_manager, 'flag'); + $this->setCacheBackend($cache_backend, 'flag'); } public function getAllFlagTypes() { From fc079604ce1d7667f885b043885f0dc74535fad5 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 22 Jun 2014 00:26:41 -0500 Subject: [PATCH 412/629] Changed flag entity ID from flag_flag to just plain 'ol flag. --- config/schema/flag.schema.yml | 2 +- flag.module | 4 ++-- flag.routing.yml | 16 ++++++++-------- src/Entity/Flag.php | 18 +++++++++++------- src/Entity/Flagging.php | 4 ++-- src/FlagService.php | 8 ++++---- src/Plugin/views/field/FlagViewsLinkField.php | 5 +++++ 7 files changed, 33 insertions(+), 24 deletions(-) diff --git a/config/schema/flag.schema.yml b/config/schema/flag.schema.yml index 8f6ec20..e5ab63f 100644 --- a/config/schema/flag.schema.yml +++ b/config/schema/flag.schema.yml @@ -1,4 +1,4 @@ -flag.flag_flag.*: +flag.flag.*: type: config_entity label: 'Flag' mapping: diff --git a/flag.module b/flag.module index 009bb16..223abf2 100644 --- a/flag.module +++ b/flag.module @@ -1444,7 +1444,7 @@ function flag_get_flag($name = NULL, $fid = NULL) { } function flag_load_by_id($id) { - return entity_load('flag_flag', $id); + return entity_load('flag', $id); } /** @@ -1465,7 +1465,7 @@ function flag_load_by_id($id) { * An array of the structure [fid] = flag_object. */ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL) { - return entity_load_multiple('flag_flag'); + return entity_load_multiple('flag'); /** $flags = &drupal_static(__FUNCTION__); diff --git a/flag.routing.yml b/flag.routing.yml index a259e8c..8afef14 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -9,7 +9,7 @@ flag.add_page: flag.list: path: '/admin/structure/flags' defaults: - _entity_list: 'flag_flag' + _entity_list: 'flag' _title: 'Flags' requirements: _permission: 'administer flags' @@ -17,26 +17,26 @@ flag.list: flag.add: path: '/admin/structure/flags/add/{entity_type}' defaults: - _entity_form: flag_flag.add + _entity_form: flag.add _title: 'Add New Flag' requirements: _permission: 'administer flags' flag.edit: - path: '/admin/structure/flags/manage/{flag_flag}' + path: '/admin/structure/flags/manage/{flag}' defaults: - _entity_form: flag_flag.edit + _entity_form: flag.edit _title: 'Edit Flag' requirements: - _entity_access: 'flag_flag.update' + _entity_access: 'flag.update' flag.delete: - path: '/admin/structure/flags/manage/{flag_flag}/delete' + path: '/admin/structure/flags/manage/{flag}/delete' defaults: - _entity_form: flag_flag.delete + _entity_form: flag.delete _title: 'Delete Flag' requirements: - _entity_access: 'flag_flag.update' + _entity_access: 'flag.update' flag_link_flag.html: path: '/flag/flag/{flag_id}/{entity_id}' diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 4d4b6a6..3289944 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -23,7 +23,7 @@ * @package Drupal\flag\Entity * * @ConfigEntityType( - * id = "flag_flag", + * id = "flag", * label = @Translation("Flag"), * admin_permission = "administer flags", * controllers = { @@ -185,11 +185,15 @@ class Flag extends ConfigEntityBase implements FlagInterface { public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); - $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), - $this->flag_type, $this->flagTypeConfig); + if ($this->flag_type) { + $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), + $this->flag_type, $this->flagTypeConfig); + } - $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), - $this->link_type, $this->linkTypeConfig); + if ($this->link_type) { + $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), + $this->link_type, $this->linkTypeConfig); + } } public function enable() { @@ -340,7 +344,7 @@ public function preSave(EntityStorageInterface $storage_controller) { ->getViewBuilder($this->getFlaggableEntityType()) ->resetCache(); } -/* + public function toArray() { $properties = parent::toArray(); $names = array( @@ -356,5 +360,5 @@ public function toArray() { return $properties; } -*/ + } \ No newline at end of file diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index debe1a4..8ebe1ec 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -49,7 +49,7 @@ public function getFlagId() { } public function getFlag() { - return entity_load('flag_flag', $this->getFlagId()); + return entity_load('flag', $this->getFlagId()); } public function getFlaggableType() { @@ -91,7 +91,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['type'] = FieldDefinition::create('entity_reference') ->setLabel(t('Type')) ->setDescription(t('The flag type.')) - ->setSetting('target_type', 'flag_flag') + ->setSetting('target_type', 'flag') ->setReadOnly(TRUE); $fields['uid'] = FieldDefinition::create('entity_reference') diff --git a/src/FlagService.php b/src/FlagService.php index a8352e8..fe38a39 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -66,7 +66,7 @@ public function fetchDefinition($entity_type = NULL) { * An array of the structure [fid] = flag_object. */ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $account = NULL) { - $query = \Drupal::entityQuery('flag_flag'); + $query = \Drupal::entityQuery('flag'); if($entity_type != NULL) { $query->condition('entity_type', $entity_type); @@ -78,7 +78,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ $result = $query->execute(); - $flags = entity_load_multiple('flag_flag', $result); + $flags = entity_load_multiple('flag', $result); if ($account == NULL) { return $flags; @@ -115,7 +115,7 @@ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, Accou } public function getFlagById($flag_id) { - return entity_load('flag_flag', $flag_id); + return entity_load('flag', $flag_id); } public function getFlaggableById(FlagInterface $flag, $entity_id) { @@ -128,7 +128,7 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou } $flagging = entity_create('flagging', array( - 'type' => 'flag_flag', + 'type' => 'flag', 'uid' => $account->id(), 'fid' => $flag->id(), 'entity_id' => $entity->id(), diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index 182f71d..7d8e0c9 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -35,6 +35,9 @@ protected function defineOptions() { 'default' => '', 'translatable' => TRUE, ); + + //$options['relationship'] = array('default' => 'none'); + /* $options['link_to_entity'] = array( 'default' => FALSE, @@ -58,6 +61,8 @@ public function buildOptionsForm(&$form, &$form_state) { ); parent::buildOptionsForm($form, $form_state); + + $form['relationship']['#access'] = FALSE; } public function query() { From ae33478c392b1025909b7400ec2ebe1bc249d75f Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 22 Jun 2014 00:55:53 -0500 Subject: [PATCH 413/629] Fix for flaggable types not being stored. --- config/schema/flag.schema.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/schema/flag.schema.yml b/config/schema/flag.schema.yml index e5ab63f..104ded9 100644 --- a/config/schema/flag.schema.yml +++ b/config/schema/flag.schema.yml @@ -11,6 +11,10 @@ flag.flag.*: label: type: label label: 'Label' + types: + type: sequence + sequence: + - type: string is_global: type: boolean label: 'Is flag global' From b2b420240d6afb7eb313f75af70f57e78479c78d Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 22 Jun 2014 23:00:29 -0500 Subject: [PATCH 414/629] Fixed missing entity_type field in Flag config schema. --- config/schema/flag.schema.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/schema/flag.schema.yml b/config/schema/flag.schema.yml index 104ded9..3e07818 100644 --- a/config/schema/flag.schema.yml +++ b/config/schema/flag.schema.yml @@ -15,6 +15,9 @@ flag.flag.*: type: sequence sequence: - type: string + entity_type: + type: string + label: 'Flaggable Entity Type' is_global: type: boolean label: 'Is flag global' From c64417cb1e115b8f0977aeb1a87c0b0e54865bd8 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 22 Jun 2014 23:01:12 -0500 Subject: [PATCH 415/629] Fixed missing default flag selection in view relationship. --- .../relationship/FlagViewsRelationship.php | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 05e4d28..b8349f5 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -19,35 +19,35 @@ class FlagViewsRelationship extends RelationshipPluginBase { public function defineOptions() { $options = parent::defineOptions(); - $options['flag'] = array('default' => NULL); // @todo load first defined flag for entity. + $options['flag'] = array('default' => NULL); $options['required'] = array('default' => 1); $options['user_scope'] = array('default' => 'current'); return $options; } public function buildOptionsForm(&$form, &$form_state) { - $entity_type = $this->definition['flaggable']; - //$form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); + parent::buildOptionsForm($form, $form_state); - /*////////////////////////////////////////////////////////////////////////// - @todo Add Flag selection form + $entity_type = $this->definition['flaggable']; + $form['label']['#description'] .= ' ' . t('The name of the selected flag makes a good label.'); - The Flag relationship relates a single flag to a single entity. Since - multiple flags may be configured for the same entity type, we need to - provide a form here that allows us to choose the flag. - //////////////////////////////////////////////////////////////////////////*/ $flags = \Drupal::service('flag')->getFlags($entity_type); + $default_value = $this->options['flag']; + if (!empty($flags) ) { + $default_value = current(array_keys($flags)); + } + $form['flag'] = array( '#type' => 'radios', '#title' => t('Flag'), - // '#default_value' => current(array_keys($flags)), + '#default_value' => $default_value, '#required' => TRUE, ); foreach ($flags as $fid => $flag) { if (!empty($flag)) { - $form['flag']['#options'][$flag->label()] = $fid; + $form['flag']['#options'][$fid] = $flag->label(); } } @@ -69,8 +69,6 @@ public function buildOptionsForm(&$form, &$form_state) { ); $form_state['no flags exist'] = TRUE; } - - parent::buildOptionsForm($form, $form_state); } public function query() { From da10302079cc9839f568514c713b3714ef2cc59d Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 23 Jun 2014 09:47:52 -0500 Subject: [PATCH 416/629] Set default relationship for FlagViewsLinkField. --- src/Plugin/views/field/FlagViewsLinkField.php | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index 7d8e0c9..acb1e4b 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -36,15 +36,12 @@ protected function defineOptions() { 'translatable' => TRUE, ); - //$options['relationship'] = array('default' => 'none'); - -/* - $options['link_to_entity'] = array( - 'default' => FALSE, - 'bool' => TRUE, - ); -*/ - //@todo return link type + // Set the default relationship handler. The first instance of the + // FlagViewsRelationship should always have the id "flag_content_rel", so + // we set that as the default. + //if (!isset($this->options['relationship'])) { + $options['relationship'] = array('default' => 'flag_content_rel'); + //} return $options; } @@ -60,9 +57,9 @@ public function buildOptionsForm(&$form, &$form_state) { '#default_value' => $this->options['text'], ); - parent::buildOptionsForm($form, $form_state); + $form['relationship']['#default_value'] = $this->options['relationship']; - $form['relationship']['#access'] = FALSE; + parent::buildOptionsForm($form, $form_state); } public function query() { From 025dcf09f479087277f3f52ffa92396ea219e783 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 23 Jun 2014 20:34:45 -0500 Subject: [PATCH 417/629] Fixed default relationship for flagged field, link field, and views filter. --- src/Plugin/views/field/FlagViewsFlaggedField.php | 13 +++++++++++++ src/Plugin/views/field/FlagViewsLinkField.php | 2 -- src/Plugin/views/filter/FlagViewsFilter.php | 7 ++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Plugin/views/field/FlagViewsFlaggedField.php b/src/Plugin/views/field/FlagViewsFlaggedField.php index eb267c5..1835bf8 100644 --- a/src/Plugin/views/field/FlagViewsFlaggedField.php +++ b/src/Plugin/views/field/FlagViewsFlaggedField.php @@ -29,4 +29,17 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o // flag object, but a) we need to lift that from the relationship we're on // and b) they will not necessarily make sense in a static context. } + + protected function defineOptions() { + $options = parent::defineOptions(); + $options['relationship'] = array('default' => 'flag_content_rel'); + + return $options; + } + + public function buildOptionsForm(&$form, &$form_state) { + $form['relationship']['#default_value'] = $this->options['relationship']; + + parent::buildOptionsForm($form, $form_state); + } } \ No newline at end of file diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index acb1e4b..f261038 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -39,9 +39,7 @@ protected function defineOptions() { // Set the default relationship handler. The first instance of the // FlagViewsRelationship should always have the id "flag_content_rel", so // we set that as the default. - //if (!isset($this->options['relationship'])) { $options['relationship'] = array('default' => 'flag_content_rel'); - //} return $options; } diff --git a/src/Plugin/views/filter/FlagViewsFilter.php b/src/Plugin/views/filter/FlagViewsFilter.php index c3fb36c..1f0afcb 100644 --- a/src/Plugin/views/filter/FlagViewsFilter.php +++ b/src/Plugin/views/filter/FlagViewsFilter.php @@ -18,11 +18,12 @@ class FlagViewsFilter extends BooleanOperator { public function defineOptions() { $options = parent::defineOptions(); $options['value'] = array('default' => 1); + $options['relationship'] = array('default' => 'flag_content_rel'); + return $options; } public function buildOptionsForm(&$form, &$form_state) { - parent::buildOptionsForm($form, $form_state); $form['value']['#type'] = 'radios'; $form['value']['#title'] = t('Status'); $form['value']['#options'] = array( @@ -33,6 +34,10 @@ public function buildOptionsForm(&$form, &$form_state) { ); $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; + + $form['relationship']['#default_value'] = $this->options['relationship']; + + parent::buildOptionsForm($form, $form_state); } From c8ed54509293df19658c5f5137ca31abd029b570 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 23 Jun 2014 21:58:56 -0500 Subject: [PATCH 418/629] Fixed broken Flag delete form, flagging confirm form, and ConfirmForm link type plugin. --- ...lag.flag_flag.bookmark.yml => flag.flag.bookmark.yml} | 0 src/Form/FlagDeleteForm.php | 5 ++--- src/Form/FlaggingConfirmForm.php | 9 +++++---- src/Plugin/ActionLink/ConfirmForm.php | 6 ++---- 4 files changed, 9 insertions(+), 11 deletions(-) rename flag_bookmark/config/install/{flag.flag_flag.bookmark.yml => flag.flag.bookmark.yml} (100%) diff --git a/flag_bookmark/config/install/flag.flag_flag.bookmark.yml b/flag_bookmark/config/install/flag.flag.bookmark.yml similarity index 100% rename from flag_bookmark/config/install/flag.flag_flag.bookmark.yml rename to flag_bookmark/config/install/flag.flag.bookmark.yml diff --git a/src/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php index fb74c8b..87855e4 100644 --- a/src/Form/FlagDeleteForm.php +++ b/src/Form/FlagDeleteForm.php @@ -9,6 +9,7 @@ namespace Drupal\flag\Form; use Drupal\Core\Entity\EntityConfirmFormBase; +use Drupal\Core\Url; class FlagDeleteForm extends EntityConfirmFormBase { @@ -23,9 +24,7 @@ public function getConfirmText() { } public function getCancelRoute() { - return array( - 'route_name' => 'flag.list', - ); + return new URL('flag.list'); } public function submit(array $form, array &$form_state) { diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index 2af1652..4c81d26 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -9,6 +9,7 @@ namespace Drupal\flag\Form; use Drupal\Core\Form\ConfirmFormBase; +use Drupal\Core\Url; use Drupal\Core\Entity\EntityInterface; use Drupal\flag\FlagInterface; @@ -38,10 +39,8 @@ public function getQuestion() { if ($this->isFlagged()) { return $linkType->getUnflagQuestion(); } - else { - return $linkType->getFlagQuestion(); - } + return $linkType->getFlagQuestion(); } public function getCancelRoute() { @@ -50,7 +49,9 @@ public function getCancelRoute() { return URL::createFromPath($destination); } - return $this->entity->urlInfo(); + $route_name = $this->entity->urlInfo(); + + return new URL($route_name['canonical']); } public function getDescription() { diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index e3c45d2..9812f60 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -33,10 +33,8 @@ public function routeName($action = NULL) { public function defaultConfiguration() { $options = parent::defaultConfiguration(); - $options += array( - 'flag_confirmation' => 'Flag this content?', - 'unflag_confirmation' => 'Unflag this content?', - ); + $options['flag_confirmation'] = 'Flag this content?'; + $options['unflag_confirmation'] = 'Unflag this content?'; return $options; } From 24edb5fd5a908c5fba51de1b4b4a107a15120b48 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Tue, 24 Jun 2014 13:48:58 +0200 Subject: [PATCH 419/629] Corrected the return of duplicate occurences of some entity flag types. --- src/FlagTypePluginManager.php | 15 ++++++--- src/Plugin/Derivative/EntityFlagType.php | 40 ++++++++++++++++++------ src/Plugin/Flag/CommentFlagType.php | 3 +- src/Plugin/Flag/NodeFlagType.php | 3 +- src/Plugin/Flag/UserFlagType.php | 5 +-- 5 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/FlagTypePluginManager.php b/src/FlagTypePluginManager.php index 8485eaf..867a190 100644 --- a/src/FlagTypePluginManager.php +++ b/src/FlagTypePluginManager.php @@ -32,14 +32,21 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac $this->setCacheBackend($cache_backend, 'flag'); } + /** + * Gets all flag types. + * + * @return array + * Returns all flag types. + */ public function getAllFlagTypes() { - $flagTypes = array(); + $flag_types = array(); - foreach ($this->getDefinitions() as $pluginID => $pluginDef) { - $flagTypes[$pluginID] = t($pluginDef['title']); + foreach ($this->getDefinitions() as $plugin_id => $plugin_def) { + $flag_types[$plugin_id] = $plugin_def['title']; } + asort($flag_types); - return $flagTypes; + return $flag_types; } } \ No newline at end of file diff --git a/src/Plugin/Derivative/EntityFlagType.php b/src/Plugin/Derivative/EntityFlagType.php index 9fb25df..bb675e9 100644 --- a/src/Plugin/Derivative/EntityFlagType.php +++ b/src/Plugin/Derivative/EntityFlagType.php @@ -1,27 +1,47 @@ getDefinitions() as $entity_id => $entity_info) { + foreach (\Drupal::entityManager()->getDefinitions() as $entity_id => $entity_type) { + if (in_array($entity_id, $this->ignoredEntities)) { + continue; + } $derivatives[$entity_id] = array( - 'title' => $entity_id, + 'title' => $entity_type->getLabel(), 'entity_type' => $entity_id, ) + $base_plugin_def; } diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index e8115f3..a223a67 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -19,7 +19,8 @@ * @FlagType( * id = "flagtype_comment", * title = @Translation("Comment"), - * entity_type = "comment" + * entity_type = "comment", + * provider = "comment" * ) */ class CommentFlagType extends EntityFlagType { diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index 2fbd1ac..e97fe9b 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -19,7 +19,8 @@ * @FlagType( * id = "flagtype_node", * title = @Translation("Content"), - * entity_type = "node" + * entity_type = "node", + * provider = "node" * ) */ class NodeFlagType extends EntityFlagType { diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 014ef7d..975fca7 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -17,7 +17,8 @@ * @FlagType( * id = "flagtype_user", * title = @Translation("User"), - * entity_type = "user" + * entity_type = "user", + * provider = "user" * ) */ class UserFlagType extends FlagTypeBase { @@ -87,6 +88,6 @@ public function getAccessUidSetting() { } public function showOnProfile() { - return this->configuration['show_on_profile']; + return $this->configuration['show_on_profile']; } } \ No newline at end of file From e6a2f367fb211bf24e2c51195ddf0a3ccdf6d50f Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Tue, 24 Jun 2014 14:04:00 +0200 Subject: [PATCH 420/629] Initial versio of basic tests. --- flag.module | 2 +- src/Tests/FlagSimpleTest.php | 107 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/Tests/FlagSimpleTest.php diff --git a/flag.module b/flag.module index 223abf2..a37ef0a 100644 --- a/flag.module +++ b/flag.module @@ -720,7 +720,7 @@ function _flag_entity_delete($entity_type, $entity_id, $fid = NULL) { /** * Implements hook_user_login(). */ -function flag_user_login(&$edit, &$account) { +function flag_user_login($account) { // Migrate anonymous flags to this user's account. if (module_exists('session_api') && ($sid = flag_get_sid(0))) { // Get a list of flagging IDs that will be moved over. diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php new file mode 100644 index 0000000..09d4112 --- /dev/null +++ b/src/Tests/FlagSimpleTest.php @@ -0,0 +1,107 @@ + 'Flag form/s', + 'description' => 'Creates a flag, adds flag to node.', + 'group' => 'Flag', + ); + } + + /** + * Configures test base and executes test cases. + */ + public function testFlagForm() { + // Create and log in our user. + $admin_user = $this->drupalCreateUser(array( + 'administer flags', + )); + $this->drupalLogin($admin_user); + $this->drupalCreateContentType(array('type' => 'article')); + $this->doTestFlagAdd(); + } + + /** + * Flag creation. + */ + public function doTestFlagAdd() { + // First, test with minimal value requirement. + $edit = array( + 'label' => $this->label, + 'id' => $this->id, + ); + $this->drupalPostForm('/admin/structure/flags/add', $edit, t('Continue')); + // Check for fieldset titles. + $this->assertText(t('Messages')); + $this->assertText(t('Flag access')); + $this->assertText(t('Display options')); + + $edit = array( + 'types[' . $this->flaggableTypes . ']' => $this->flaggableTypes, + ); + $this->drupalPostForm(NULL, $edit, t('Create Flag')); + + $this->assertText(t('Flag @this_label has been added.', array('@this_label' => $this->label))); + + } + + /** + * Node creation and flagging. + */ + +} From 0a0e8860d5e75b08465e1dfbf0e31edd61e52d31 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 25 Jun 2014 10:18:13 +0200 Subject: [PATCH 421/629] Provided basic tests and added documentation for changed code. --- src/Entity/Flag.php | 16 +++++++++++-- src/FlagInterface.php | 16 +++++++++++++ src/FlaggingAccessController.php | 41 ++++++++++++++++++++------------ src/Tests/FlagSimpleTest.php | 27 +++++++++++++++++---- 4 files changed, 79 insertions(+), 21 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 3289944..a883f4d 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -14,8 +14,6 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageInterface; -use Drupal\Core\Entity\Annotation\EntityType; -use Drupal\Core\Annotation\Translation; use Drupal\flag\FlagInterface; /** @@ -308,6 +306,20 @@ function getPermissions() { ); } + /** + * {@inheritdoc}. + */ + public function hasActionAccess($action, AccountInterface $account = NULL) { + if ($action === 'flag' || $action === 'unflag') { + $account = $account ?: \Drupal::currentUser(); + return $account->hasPermission($action . ' ' . $this->id); + } + else { + // @todo: Is this the correct response? + return FALSE; + } + } + public function isGlobal() { return $this->is_global; } diff --git a/src/FlagInterface.php b/src/FlagInterface.php index fafd458..a40a2ff 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -30,4 +30,20 @@ public function isGlobal(); public function setGlobal($isGlobal); public function getPluginBags(); + + /** + * User access permission for flagging actions. + * + * Checks whether a user has permission to flag/unflag or not. + * + * @param string $action + * An indicator flag. + * @param AccountInterface $account + * (optional) An AccountInterface object. + * + * @return bool|null + * Returns a bool defining the users access permission for flagging action. + */ + public function hasActionAccess($action, AccountInterface $account = NULL); + } \ No newline at end of file diff --git a/src/FlaggingAccessController.php b/src/FlaggingAccessController.php index e2c0ce1..bc70b14 100644 --- a/src/FlaggingAccessController.php +++ b/src/FlaggingAccessController.php @@ -1,27 +1,33 @@ get('entity_id'); - - if (user_access('flag' . $entity_id)) { + $flag = Flag::load($request->get('flag_id')); + if ($flag->hasActionAccess('flag')) { return AccessInterface::ALLOW; } @@ -29,16 +35,21 @@ public function checkFlag(Request $request) { } /** + * Checks unflagging permission. * + * @param Request $request + * The request object. + * + * @return string + * Returns indication value for unflagging access permission. */ public function checkUnflag(Request $request) { - $entity_id = $request->get('entity_id'); - - if (user_access('unflag' . $entity_id)) { + $flag = Flag::load($request->get('flag_id')); + if ($flag->hasActionAccess('unflag')) { return AccessInterface::ALLOW; } return AccessInterface::DENY; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 09d4112..97d3bb4 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -33,7 +33,7 @@ class FlagSimpleTest extends WebTestBase { /** * @var string */ - protected $flaggableTypes = 'article'; + protected $nodeType = 'article'; /** * @var string @@ -72,7 +72,6 @@ public function testFlagForm() { 'administer flags', )); $this->drupalLogin($admin_user); - $this->drupalCreateContentType(array('type' => 'article')); $this->doTestFlagAdd(); } @@ -80,7 +79,10 @@ public function testFlagForm() { * Flag creation. */ public function doTestFlagAdd() { - // First, test with minimal value requirement. + // Create content type. + $this->drupalCreateContentType(array('type' => $this->nodeType)); + + // Test with minimal value requirement. $edit = array( 'label' => $this->label, 'id' => $this->id, @@ -92,16 +94,33 @@ public function doTestFlagAdd() { $this->assertText(t('Display options')); $edit = array( - 'types[' . $this->flaggableTypes . ']' => $this->flaggableTypes, + 'types[' . $this->nodeType . ']' => $this->nodeType, ); $this->drupalPostForm(NULL, $edit, t('Create Flag')); $this->assertText(t('Flag @this_label has been added.', array('@this_label' => $this->label))); + // Continue test process. + $this->doTestCreateNodeAndFlagIt(); } /** * Node creation and flagging. */ + public function doTestCreateNodeAndFlagIt() { + $node = $this->drupalCreateNode(array('type' => $this->nodeType)); + $node_id = $node->id(); + + // Now that permissions have been created for this node, create and login + // new user. + $node_user = $this->drupalCreateUser(array( + 'flag ' . $this->id, + 'unflag ' . $this->id, + )); + $this->drupalLogin($node_user); + $this->drupalGet('/node/' . $node_id); + $this->clickLink('Flag this item'); + $this->clickLink('Unflag this item'); + } } From f13675bd73f57a644af4bd46a1af08f9dc5a5587 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 25 Jun 2014 12:21:43 +0200 Subject: [PATCH 422/629] Fixed caching issue in basic tests, created permission role instead of multiple permission settings. --- flag.module | 29 +++++++++++++++++++++++++++++ src/Entity/Flag.php | 1 - src/Entity/Flagging.php | 2 -- src/Tests/FlagSimpleTest.php | 34 +++++++++++++++++++++++++++------- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/flag.module b/flag.module index a37ef0a..5c69e2d 100644 --- a/flag.module +++ b/flag.module @@ -10,6 +10,7 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); +use Drupal\entity\Entity\EntityViewDisplay; use Drupal\flag\Flag; use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; @@ -600,6 +601,34 @@ function flag_entity_view(array &$build, EntityInterface $entity, } } +/** + * Implements hook_entity_build_defaults_alter(). + */ +function flag_entity_build_defaults_alter(array &$build, EntityInterface $entity, $view_mode = 'full', $langcode = NULL) { + // Get the corresponding display settings. + // $display = EntityViewDisplay::collectRenderDisplay($entity, $view_mode); + // Add the flag ID combined with the action to the cache key if render + // caching is enabled. + if (isset($build['#cache']) && isset($build['#cache']['keys'])) { + + // Get all possible flags for this entity type. + $flag_service = \Drupal::service('flag'); + $flags = $flag_service->getFlags($entity->getEntityTypeID(), + $entity->bundle()); + + foreach ($flags as $flag) { + $action = 'flag'; + + if ($flag->isFlagged($entity)) { + $action = 'unflag'; + } + + $build['#cache']['keys'][] = $flag->id . '-' . $action; + } + } + return $build; +} + /** * Implements hook_node_insert(). */ diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index a883f4d..02d4481 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -9,7 +9,6 @@ namespace Drupal\flag\Entity; use Drupal\Core\Plugin\DefaultSinglePluginBag; -use Drupal\Compontent\Plugin\ConfigurablePluginInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 8ebe1ec..fa6c70b 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -11,8 +11,6 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityStorageControllerInterface; -use Drupal\Core\Language\Language; -use Drupal\Core\Session\AccountInterface; use Drupal\Core\Field\FieldDefinition; use Drupal\flag\FlaggingInterface; diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 97d3bb4..5a3c240 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -8,6 +8,7 @@ namespace Drupal\flag\Tests; use Drupal\simpletest\WebTestBase; +use Drupal\user\Entity\Role; /** @@ -111,16 +112,35 @@ public function doTestCreateNodeAndFlagIt() { $node = $this->drupalCreateNode(array('type' => $this->nodeType)); $node_id = $node->id(); - // Now that permissions have been created for this node, create and login - // new user. - $node_user = $this->drupalCreateUser(array( - 'flag ' . $this->id, - 'unflag ' . $this->id, - )); - $this->drupalLogin($node_user); + // Grant the flag permissions to the authenticated role, so that both + // users have the same roles and share the render cache. + $role = Role::load(DRUPAL_AUTHENTICATED_RID); + $role->grantPermission('flag ' . $this->id); + $role->grantPermission('unflag ' . $this->id); + $role->save(); + + // Create and login a new user. + $user_1 = $this->drupalCreateUser(); + $this->drupalLogin($user_1); $this->drupalGet('/node/' . $node_id); $this->clickLink('Flag this item'); + $this->assertResponse(200); + $this->assertLink('Unflag this item'); + + // Switch user to check flagging link. + $user_2 = $this->drupalCreateUser(); + $this->drupalLogin($user_2); + $this->drupalGet('/node/' . $node_id); + $this->assertResponse(200); + $this->assertLink('Flag this item'); + + // Switch back to first user and unflag. + $this->drupalLogin($user_1); + $this->drupalGet('/node/' . $node_id); + $this->clickLink('Unflag this item'); + $this->assertResponse(200); + $this->assertLink('Flag this item'); } } From 94aadbf03e1ebd81897b321396d6ab91f71bdb14 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 25 Jun 2014 12:35:11 +0200 Subject: [PATCH 423/629] Removed unused Entity display. --- flag.module | 3 --- 1 file changed, 3 deletions(-) diff --git a/flag.module b/flag.module index 5c69e2d..3d1987f 100644 --- a/flag.module +++ b/flag.module @@ -10,7 +10,6 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); -use Drupal\entity\Entity\EntityViewDisplay; use Drupal\flag\Flag; use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; @@ -605,8 +604,6 @@ function flag_entity_view(array &$build, EntityInterface $entity, * Implements hook_entity_build_defaults_alter(). */ function flag_entity_build_defaults_alter(array &$build, EntityInterface $entity, $view_mode = 'full', $langcode = NULL) { - // Get the corresponding display settings. - // $display = EntityViewDisplay::collectRenderDisplay($entity, $view_mode); // Add the flag ID combined with the action to the cache key if render // caching is enabled. if (isset($build['#cache']) && isset($build['#cache']['keys'])) { From 1179d343d30ac2748eddaadd7dbd1c1977e2887c Mon Sep 17 00:00:00 2001 From: Andy Postnikov Date: Wed, 25 Jun 2014 14:41:37 +0400 Subject: [PATCH 424/629] Clean-up Flag entity doc blocks --- src/Entity/Flag.php | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 3289944..4ed07f7 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -1,21 +1,16 @@ getFlagTypePlugin(); @@ -361,4 +356,4 @@ public function toArray() { return $properties; } -} \ No newline at end of file +} From be3b43f0cc07da605e4b8efcb241ce51ef234123 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 25 Jun 2014 16:56:38 +0200 Subject: [PATCH 425/629] Converted hook_help() paths to routes. --- flag.module | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/flag.module b/flag.module index 223abf2..4f323ab 100644 --- a/flag.module +++ b/flag.module @@ -14,6 +14,7 @@ use Drupal\flag\Flag; use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Symfony\Component\HttpFoundation\Request; // @todo: Implement flagging_view(). Not extremely useful. I already have it. @@ -156,15 +157,18 @@ function flag_load($flag_name, $include_disabled = FALSE) { /** * Implements hook_help(). */ -function flag_help($path, $arg) { - switch ($path) { - case FLAG_ADMIN_PATH: +function flag_help($route_name, Request $request) { + switch ($route_name) { + case 'flag.list': $output = '

' . t('This page lists all the flags that are currently defined on this system.') . '

'; return $output; - case FLAG_ADMIN_PATH . '/add': + case 'flag.add_page': $output = '

' . t('Select the type of flag to create. An individual flag can only affect one type of object. This cannot be changed once the flag is created.') . '

'; return $output; - case FLAG_ADMIN_PATH . '/manage/%/fields': + case 'field_ui.overview_flagging': + // @todo: Doesn't make sense at the moment, implement when form + // functionality is available. + /* // Get the existing link types that provide a flagging form. $link_types = flag_get_link_types(); $form_link_types = array(); @@ -221,6 +225,7 @@ function flag_help($path, $arg) { } return $output; + */ } } From 0fbc2ae818547debcf0e40325c1a309afad7aaaa Mon Sep 17 00:00:00 2001 From: yanniboi Date: Wed, 25 Jun 2014 16:19:23 +0100 Subject: [PATCH 426/629] Fixed a type on UserFlagType. --- src/Plugin/Flag/UserFlagType.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 014ef7d..e2e5256 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -87,6 +87,6 @@ public function getAccessUidSetting() { } public function showOnProfile() { - return this->configuration['show_on_profile']; + return $this->configuration['show_on_profile']; } -} \ No newline at end of file +} From af75dc4f6522aba57abda7b628324d2f45fd4f28 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Thu, 26 Jun 2014 17:18:59 +0200 Subject: [PATCH 427/629] Added tests and now checks that cache key is only added if flag is displayed. --- flag.module | 49 +++++++++++++++------------ src/Entity/Flag.php | 3 ++ src/Tests/FlagSimpleTest.php | 65 ++++++++++++++++++++++++++++-------- 3 files changed, 81 insertions(+), 36 deletions(-) diff --git a/flag.module b/flag.module index 3d1987f..2e94df3 100644 --- a/flag.module +++ b/flag.module @@ -10,6 +10,7 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); +use Drupal\entity\Entity\EntityViewDisplay; use Drupal\flag\Flag; use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; @@ -323,11 +324,10 @@ function flag_flag_link($flag, $action, $entity_id) { } /** - * Implements hook_field_extra_fields(). + * Implements hook_entity_extra_field_info(). */ -function flag_field_extra_fields() { +function flag_entity_extra_field_info() { $extra = array(); - $flag_service = \Drupal::service('flag'); $flags = $flag_service->getFlags(); foreach ($flags as $flag) { @@ -342,12 +342,12 @@ function flag_field_extra_fields() { $extra[$flag->entity_type][$bundle_name]['form']['flag'] = array( 'label' => t('Flags'), 'description' => t('Checkboxes for toggling flags'), - 'weight' => 10 + 'weight' => 10, ); } if ($flagTypePlugin->showAsField()) { - $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $flag->label()] = array( + $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $flag->id()] = array( // It would be nicer to use % as the placeholder, but the label is // run through check_plain() by field_ui_display_overview_form() // (arguably incorrectly; see http://drupal.org/node/1991292). @@ -571,32 +571,28 @@ function flag_field_attach_save($entity_type, $entity) { * Implements hook_entity_view(). * * Handles the 'show_in_links' and 'show_as_field' flag options. - * - * Note this is broken for taxonomy terms for version of Drupal core < 7.17. */ -function flag_entity_view(array &$build, EntityInterface $entity, - EntityViewDisplayInterface $display, - $view_mode, $langcode) { - - - //@todo Check $type->getComponent('flag_whateverHookFieldExtraFieldsIS'). - // if not NULL, display it. - +function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode) { // Get all possible flags for this entity type. $flag_service = \Drupal::service('flag'); - $flags = $flag_service->getFlags($entity->getEntityTypeID(), - $entity->bundle()); + $flags = $flag_service->getFlags($entity->getEntityTypeID(), $entity->bundle()); foreach ($flags as $flag) { - $linkTypePlugin = $flag->getLinkTypePlugin(); - $action = 'flag'; + $link_type_plugin = $flag->getLinkTypePlugin(); + $flag_type_plugin = $flag->getFlagTypePlugin(); + + // Only add cache key if flag link is displayed. + if ($flag_type_plugin->showAsField() && !$display->getComponent('flag_' . $flag->id())) { + continue; + } + $action = 'flag'; if ($flag->isFlagged($entity)) { $action = 'unflag'; } - $link = $linkTypePlugin->renderLink($action, $flag, $entity); - $build['flag_' . $flag->id] = $link; + $link = $link_type_plugin->renderLink($action, $flag, $entity); + $build['flag_' . $flag->id()] = $link; } } @@ -613,9 +609,18 @@ function flag_entity_build_defaults_alter(array &$build, EntityInterface $entity $flags = $flag_service->getFlags($entity->getEntityTypeID(), $entity->bundle()); + // Get the corresponding display settings. + $display = EntityViewDisplay::collectRenderDisplay($entity, $view_mode); + foreach ($flags as $flag) { - $action = 'flag'; + $flag_type_plugin = $flag->getFlagTypePlugin(); + + // Only add cache key if flag link is displayed. + if ($flag_type_plugin->showAsField() && !$display->getComponent('flag_' . $flag->id())) { + continue; + } + $action = 'flag'; if ($flag->isFlagged($entity)) { $action = 'unflag'; } diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 02d4481..69887bf 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -354,6 +354,9 @@ public function preSave(EntityStorageInterface $storage_controller) { \Drupal::entityManager() ->getViewBuilder($this->getFlaggableEntityType()) ->resetCache(); + // Clear entity extra field caches. + \Drupal::entityManager()->clearCachedFieldDefinitions(); + } public function toArray() { diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 5a3c240..a41c2db 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -32,26 +32,25 @@ class FlagSimpleTest extends WebTestBase { protected $flagLinkType; /** + * + * * @var string */ protected $nodeType = 'article'; /** - * @var string - */ - protected $flag_confirmation = 'Are you sure you want to flag this content?'; - - /** - * @var string + * User object. + * + * @var \Drupal\user\Entity\User|false */ - protected $unflag_confirmation = 'Are you sure you want to unflag this content?'; + protected $adminUser; /** * Modules to enable. * * @var array */ - public static $modules = array('flag', 'node'); + public static $modules = array('views', 'flag', 'node', 'field_ui'); /** * {@inheritdoc} @@ -69,11 +68,15 @@ public static function getInfo() { */ public function testFlagForm() { // Create and log in our user. - $admin_user = $this->drupalCreateUser(array( + $this->adminUser = $this->drupalCreateUser(array( 'administer flags', + 'administer node display', )); - $this->drupalLogin($admin_user); + + $this->drupalLogin($this->adminUser); + $this->doTestFlagAdd(); + $this->doTestHideFlagLinkFromTeaser(); } /** @@ -88,7 +91,7 @@ public function doTestFlagAdd() { 'label' => $this->label, 'id' => $this->id, ); - $this->drupalPostForm('/admin/structure/flags/add', $edit, t('Continue')); + $this->drupalPostForm('admin/structure/flags/add', $edit, t('Continue')); // Check for fieldset titles. $this->assertText(t('Messages')); $this->assertText(t('Flag access')); @@ -123,7 +126,7 @@ public function doTestCreateNodeAndFlagIt() { $user_1 = $this->drupalCreateUser(); $this->drupalLogin($user_1); - $this->drupalGet('/node/' . $node_id); + $this->drupalGet('node/' . $node_id); $this->clickLink('Flag this item'); $this->assertResponse(200); $this->assertLink('Unflag this item'); @@ -131,16 +134,50 @@ public function doTestCreateNodeAndFlagIt() { // Switch user to check flagging link. $user_2 = $this->drupalCreateUser(); $this->drupalLogin($user_2); - $this->drupalGet('/node/' . $node_id); + $this->drupalGet('node/' . $node_id); $this->assertResponse(200); $this->assertLink('Flag this item'); // Switch back to first user and unflag. $this->drupalLogin($user_1); - $this->drupalGet('/node/' . $node_id); + $this->drupalGet('node/' . $node_id); $this->clickLink('Unflag this item'); $this->assertResponse(200); $this->assertLink('Flag this item'); } + + /** + * Node creation and flag link. + */ + public function doTestHideFlagLinkFromTeaser() { + $this->drupalLogin($this->adminUser); + + $node = $this->drupalCreateNode(array( + 'type' => $this->nodeType, + 'promote' => TRUE, + )); + $node_id = $node->id(); + $node_title = $node->getTitle(); + + $this->drupalGet('node'); + $this->assertText($node_title); + $this->assertLink('Flag this item'); + + // Set flag format to hidden for teaser display and post form. + $edit = array( + 'fields[flag_' . $this->id . '][type]' => 'hidden', + ); + + $this->drupalPostForm('admin/structure/types/manage/' . $this->nodeType . '/display/teaser', $edit, t('Save')); + + // Check if form is saved successfully. + $this->assertText('Your settings have been saved.'); + + $this->drupalGet('node'); + $this->assertText($node_title); + $this->assertNoLink('Flag this item'); + + $this->drupalGet('node/' . $node_id); + } } From 433d1ccc55f7b17d099b95b6189dde4e1d6d88fc Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Fri, 27 Jun 2014 12:45:37 +0200 Subject: [PATCH 428/629] Fixed error on/admin/structure/types/manage/page (temporary solution, see @todo) and replaced non-existent functions canFlag/canUnflag with hasActionAccess. --- flag.module | 6 ++++-- src/FlagService.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/flag.module b/flag.module index fb0dbd7..ab971cb 100644 --- a/flag.module +++ b/flag.module @@ -374,9 +374,11 @@ function flag_entity_extra_field_info() { */ function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { global $user; - $flags = \Drupal::service('flag')->getFlags('node', $form['#node_type']->type, $user); + $node_type = $form_state['controller']->getEntity(); + $flags = \Drupal::service('flag')->getFlags('node', $node_type->id(), $user); foreach ($flags as $flag) { - if ($flag->show_on_form) { + // @todo: Revisit when form functionality is implemented. + if (!empty($flag->show_on_form)) { // To be able to process node tokens in flag labels, we create a fake // node and store it in the flag's cache for replace_tokens() to find, // with a fake ID. diff --git a/src/FlagService.php b/src/FlagService.php index fe38a39..5b5f901 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -86,7 +86,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ $filtered_flags = array(); foreach ($flags as $flag) { - if ($flag->canFlag($account) || $flag->canUnflag($account)) { + if ($flag->hasActionAccess('flag ' . $flag->id(), $account) || $flag->hasActionAccess('unflag ' . $flag->id(), $account)) { $filtered_flags[] = $flag; } } From c4b3cd17b82c2a9e62384cfbbe4ad06b4742b012 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 29 Jun 2014 21:35:53 -0500 Subject: [PATCH 429/629] Added basic events support for flag, unflag, and delete. --- src/Entity/Flag.php | 11 +++++++++++ src/Event/FlagDeleteEvent.php | 19 +++++++++++++++++++ src/Event/FlagEventBase.php | 23 +++++++++++++++++++++++ src/Event/FlagEvents.php | 22 ++++++++++++++++++++++ src/Event/FlaggingEvent.php | 27 +++++++++++++++++++++++++++ src/FlagService.php | 9 +++++++++ 6 files changed, 111 insertions(+) create mode 100644 src/Event/FlagDeleteEvent.php create mode 100644 src/Event/FlagEventBase.php create mode 100644 src/Event/FlagEvents.php create mode 100644 src/Event/FlaggingEvent.php diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index fc52453..0d877f6 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -11,6 +11,8 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\flag\Event\FlagDeleteEvent; +use Drupal\flag\Event\FlagEvents; use Drupal\flag\FlagInterface; /** @@ -357,6 +359,15 @@ public function preSave(EntityStorageInterface $storage) { } + public static function preDelete(EntityStorageInterface $storage, array $entities) { + parent::preDelete($storage, $entities); + + foreach ($entities as $entity) { + \Drupal::service('event_dispatcher') + ->dispatch(FlagEvents::FLAG_DELETED, new FlagDeleteEvent($entity)); + } + } + public function toArray() { $properties = parent::toArray(); $names = array( diff --git a/src/Event/FlagDeleteEvent.php b/src/Event/FlagDeleteEvent.php new file mode 100644 index 0000000..b1ba5cf --- /dev/null +++ b/src/Event/FlagDeleteEvent.php @@ -0,0 +1,19 @@ +flag = $flag; + } + +} \ No newline at end of file diff --git a/src/Event/FlagEvents.php b/src/Event/FlagEvents.php new file mode 100644 index 0000000..65a2709 --- /dev/null +++ b/src/Event/FlagEvents.php @@ -0,0 +1,22 @@ +entity = $entity; + $this->action = $action; + } + +} \ No newline at end of file diff --git a/src/FlagService.php b/src/FlagService.php index 5b5f901..059f0be 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -10,6 +10,8 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\flag\Event\FlagEvents; +use Drupal\flag\Event\FlaggingEvent; use Drupal\flag\FlagInterface; use Drupal\Core\Entity\EntityInterface; @@ -143,6 +145,9 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $entity, )); + \Drupal::service('event_dispatcher') + ->dispatch(FlagEvents::ENTITY_FLAGGED, new FlaggingEvent($flag, $entity, 'flag')); + return $flagging; } @@ -190,6 +195,10 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { public function unflagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { + + \Drupal::service('event_dispatcher') + ->dispatch(FlagEvents::ENTITY_UNFLAGGED, new FlaggingEvent($flag, $entity, 'unflag')); + $out = array(); $flaggings = $this->getFlaggings($entity, $flag); foreach ($flaggings as $flagging) { From 6a258e7cbc5978abffa7b767e07bf83fe014fa5f Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 09:53:52 +0200 Subject: [PATCH 430/629] Added permission check for flag link. --- flag.module | 4 ++++ src/Tests/FlagSimpleTest.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/flag.module b/flag.module index ab971cb..6ba3ed8 100644 --- a/flag.module +++ b/flag.module @@ -597,6 +597,10 @@ function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisp if ($flag->isFlagged($entity)) { $action = 'unflag'; } + // + if(!$flag->hasActionAccess($action)){ + continue; + } $link = $link_type_plugin->renderLink($action, $flag, $entity); $build['flag_' . $flag->id()] = $link; diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index a41c2db..79ff128 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -145,6 +145,10 @@ public function doTestCreateNodeAndFlagIt() { $this->clickLink('Unflag this item'); $this->assertResponse(200); $this->assertLink('Flag this item'); + + $this->drupalLogout(); + $this->drupalGet('node/' . $node_id); + $this->assertNoLink('Flag this item'); } /** From 0c0b471f14a621c348a44803ee7ab34955c7f620 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 15:50:21 +0200 Subject: [PATCH 431/629] Fixed flag (and flag count) deletion when node is deleted. Fixed saving/updating/deleting flag counts. --- flag.install | 4 +-- flag.module | 5 ++- src/FlagService.php | 81 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/flag.install b/flag.install index 3e7100b..9992e0b 100644 --- a/flag.install +++ b/flag.install @@ -15,8 +15,8 @@ function flag_schema() { 'description' => 'The number of times an item has been flagged.', 'fields' => array( 'fid' => array( - 'type' => 'int', - 'size' => 'small', + 'type' => 'varchar', + 'size' => '255', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, diff --git a/flag.module b/flag.module index ab971cb..8b6889e 100644 --- a/flag.module +++ b/flag.module @@ -696,12 +696,11 @@ function flag_entity_delete($entity, $type) { */ function flag_node_delete($node) { foreach (flag_get_flags('node') as $flag) { + // @todo: Update comments below and perhaps also flag_node_translation_change? // If the flag is being tracked by translation set and the node is part // of a translation set, don't delete the flagging record. // Instead, data will be updated in hook_node_translation_change(), below. - if (!$flag->i18n || empty($node->tnid)) { - _flag_entity_delete('node', $node->nid, $flag->fid); - } + _flag_entity_delete('node', $node->id()); } } diff --git a/src/FlagService.php b/src/FlagService.php index 059f0be..759126b 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -10,6 +10,8 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\flag\Entity\Flag; +use Drupal\flag\Entity\Flagging; use Drupal\flag\Event\FlagEvents; use Drupal\flag\Event\FlaggingEvent; use Drupal\flag\FlagInterface; @@ -116,10 +118,16 @@ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, Accou return $flaggings; } + /** + * @todo Should not work like this, instead of the ID, the object itself should be passed along! + */ public function getFlagById($flag_id) { return entity_load('flag', $flag_id); } + /** + * @todo Should not work like this, instead of the ID, the object itself should be passed along! + */ public function getFlaggableById(FlagInterface $flag, $entity_id) { return entity_load($flag->getFlaggableEntityType(), $entity_id); } @@ -139,6 +147,8 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $flagging->save(); + $this->incrementFlagCounts($flag, $entity); + \Drupal::entityManager() ->getViewBuilder($entity->getEntityTypeId()) ->resetCache(array( @@ -188,14 +198,13 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { $flag = $this->getFlagById($flag_id); $entity = $this->getFlaggableById($flag, $entity_id); + $this->decrementFlagCounts($flag, $entity); + return $this->unflagByObject($flag, $entity, $account); } - public function unflagByObject(FlagInterface $flag, - EntityInterface $entity, - AccountInterface $account = NULL) { - + public function unflagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { \Drupal::service('event_dispatcher') ->dispatch(FlagEvents::ENTITY_UNFLAGGED, new FlaggingEvent($flag, $entity, 'unflag')); @@ -212,4 +221,68 @@ public function unflagByFlagging(FlaggingInterface $flagging) { $flagging->delete(); } + /** + * Increments count of flagged entities. + * + * @param FlagInterface $flag + * @param EntityInterface $entity + */ + protected function incrementFlagCounts(FlagInterface $flag, EntityInterface $entity) { + $count_result = db_select('flag_counts') + ->fields(NULL, array('fid', 'entity_id', 'entity_type', 'count')) + ->condition('fid', $flag->id()) + ->condition('entity_id', $entity->id()) + ->condition('entity_type', $entity->getEntityTypeId()) + ->execute() + ->fetchAll(); + var_dump($count_result); + if (count($count_result) == 1) { + db_update('flag_counts') + ->expression('count', 'count + 1') + ->condition('fid', $flag->id()) + ->condition('entity_id', $entity->id()) + ->execute(); + } + else { + db_insert('flag_counts') + ->fields(array( + 'fid' => $flag->id(), + 'entity_id' => $entity->id(), + 'entity_type' => $entity->getEntityTypeId(), + 'count' => 1, + )) + ->execute(); + } + } + + /** + * Reverts incrementation of count of flagged entities. + * + * @param FlagInterface $flag + * @param EntityInterface $entity + */ + protected function decrementFlagCounts(FlagInterface $flag, EntityInterface $entity) { + $count_result = db_select('flag_counts') + ->fields(NULL, array('fid', 'entity_id', 'entity_type', 'count')) + ->condition('fid', $flag->id()) + ->condition('entity_id', $entity->id()) + ->condition('entity_type', $entity->getEntityTypeId()) + ->execute() + ->fetchAll(); + var_dump($count_result); + if (count($count_result) == 1) { + db_delete('flag_counts') + ->condition('fid', $flag->id()) + ->condition('entity_id', $entity->id()) + ->execute(); + } + else { + db_update('flag_counts') + ->expression('count', 'count - 1') + ->condition('fid', $flag->id()) + ->condition('entity_id', $entity->id()) + ->execute(); + } + } + } \ No newline at end of file From fa23e8ac15bf0c5ae4b40a22a304d6cf3e879d73 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 09:53:52 +0200 Subject: [PATCH 432/629] Added permission check for flag link. --- flag.module | 4 +++- src/Tests/FlagSimpleTest.php | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 6ba3ed8..3576f63 100644 --- a/flag.module +++ b/flag.module @@ -597,7 +597,9 @@ function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisp if ($flag->isFlagged($entity)) { $action = 'unflag'; } - // + + // If does not have permission for this action, stop here and go to next + // foreach loop. if(!$flag->hasActionAccess($action)){ continue; } diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 79ff128..d7acde0 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -146,6 +146,8 @@ public function doTestCreateNodeAndFlagIt() { $this->assertResponse(200); $this->assertLink('Flag this item'); + // Checks that an anonymous user does not have permission to see the + // flag/unflag link. $this->drupalLogout(); $this->drupalGet('node/' . $node_id); $this->assertNoLink('Flag this item'); From 451b67079394ba28997740fefd78be21f90d3fd7 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 17:56:37 +0200 Subject: [PATCH 433/629] Updated commenting. --- src/Tests/FlagSimpleTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index d7acde0..497c2e3 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -146,8 +146,8 @@ public function doTestCreateNodeAndFlagIt() { $this->assertResponse(200); $this->assertLink('Flag this item'); - // Checks that an anonymous user does not have permission to see the - // flag/unflag link. + // Check that the anonymous user, who does not have the necessary + // permissions, does not see the flag link. $this->drupalLogout(); $this->drupalGet('node/' . $node_id); $this->assertNoLink('Flag this item'); From d8140972e7ae255fbf524b984a2e0ed7828f12f6 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 18:02:13 +0200 Subject: [PATCH 434/629] Updated commenting. --- flag.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 3576f63..de6751d 100644 --- a/flag.module +++ b/flag.module @@ -598,8 +598,8 @@ function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisp $action = 'unflag'; } - // If does not have permission for this action, stop here and go to next - // foreach loop. + // If the user does not have permission, go to the next foreach loop and + // don't display this flag. if(!$flag->hasActionAccess($action)){ continue; } From 07e27184946f19847f9fd87e898931750ef4588a Mon Sep 17 00:00:00 2001 From: Arild Date: Wed, 2 Jul 2014 18:02:46 +0200 Subject: [PATCH 435/629] flag_help() should use RouteMatchInterface, not Request This is to reflect updates made to hook_help(). Note that the implementation is still @todo. --- flag.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index ab971cb..ad8ff15 100644 --- a/flag.module +++ b/flag.module @@ -15,7 +15,7 @@ use Drupal\flag\Flag; use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; -use Symfony\Component\HttpFoundation\Request; +use Drupal\Core\Routing\RouteMatchInterface; // @todo: Implement flagging_view(). Not extremely useful. I already have it. @@ -158,7 +158,7 @@ function flag_load($flag_name, $include_disabled = FALSE) { /** * Implements hook_help(). */ -function flag_help($route_name, Request $request) { +function flag_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'flag.list': $output = '

' . t('This page lists all the flags that are currently defined on this system.') . '

'; From f4e2e5bd44d91b227c8af459490c63fd35646892 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Thu, 3 Jul 2014 11:06:10 +0200 Subject: [PATCH 436/629] Replaced conditional row creation/update with db_merge(). --- src/FlagService.php | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index 759126b..c8d9f73 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -228,31 +228,21 @@ public function unflagByFlagging(FlaggingInterface $flagging) { * @param EntityInterface $entity */ protected function incrementFlagCounts(FlagInterface $flag, EntityInterface $entity) { - $count_result = db_select('flag_counts') - ->fields(NULL, array('fid', 'entity_id', 'entity_type', 'count')) - ->condition('fid', $flag->id()) - ->condition('entity_id', $entity->id()) - ->condition('entity_type', $entity->getEntityTypeId()) - ->execute() - ->fetchAll(); - var_dump($count_result); - if (count($count_result) == 1) { - db_update('flag_counts') - ->expression('count', 'count + 1') - ->condition('fid', $flag->id()) - ->condition('entity_id', $entity->id()) - ->execute(); - } - else { - db_insert('flag_counts') - ->fields(array( - 'fid' => $flag->id(), - 'entity_id' => $entity->id(), - 'entity_type' => $entity->getEntityTypeId(), - 'count' => 1, - )) - ->execute(); - } + db_merge('flag_counts') + ->key(array( + 'fid' => $flag->id(), + 'entity_id' => $entity->id(), + 'entity_type' => $entity->getEntityTypeId(), + 'last_updated' => time(), + )) + ->fields(array( + 'fid' => $flag->id(), + 'entity_id' => $entity->id(), + 'entity_type' => $entity->getEntityTypeId(), + 'count' => 1 + )) + ->expression('count', 'count + :inc', array(':inc' => 1)) + ->execute(); } /** @@ -269,11 +259,11 @@ protected function decrementFlagCounts(FlagInterface $flag, EntityInterface $ent ->condition('entity_type', $entity->getEntityTypeId()) ->execute() ->fetchAll(); - var_dump($count_result); if (count($count_result) == 1) { db_delete('flag_counts') ->condition('fid', $flag->id()) ->condition('entity_id', $entity->id()) + ->condition('entity_type', $entity->getEntityTypeId()) ->execute(); } else { @@ -281,6 +271,7 @@ protected function decrementFlagCounts(FlagInterface $flag, EntityInterface $ent ->expression('count', 'count - 1') ->condition('fid', $flag->id()) ->condition('entity_id', $entity->id()) + ->condition('entity_id', $entity->id()) ->execute(); } } From 59a6f6a396b43c720fb3b00a032a94e9e4b6c55f Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Thu, 3 Jul 2014 11:28:26 +0200 Subject: [PATCH 437/629] Added test that flags a node using different user accounts and checks flag counts. --- src/Tests/FlagSimpleTest.php | 74 ++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index a41c2db..01a2875 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -180,4 +180,78 @@ public function doTestHideFlagLinkFromTeaser() { $this->drupalGet('node/' . $node_id); } + + /** + * Flags a node using different user accounts and checks flag counts. + */ + public function doTestFlagCounts() { + $node = $this->drupalCreateNode(array('type' => $this->nodeType)); + $node_id = $node->id(); + + // Create and login user 1. + $user_1 = $this->drupalCreateUser(); + $this->drupalLogin($user_1); + + // Flag node (first count). + $this->drupalGet('node/' . $node_id); + $this->clickLink('Flag this item'); + $this->assertResponse(200); + $this->assertLink('Unflag this item'); + + // Check for 1 flag count. + $count_flags_before = \Drupal::entityQuery('flag_counts') + ->condition('fid', $this->id) + ->condition('entity_type', $node->getEntityTypeId()) + ->condition('entity_id', $node_id) + ->count() + ->execute(); + $this->assertTrue(1, $count_flags_before); + + // Logout user 1, create and login user 2. + $user_2 = $this->drupalCreateUser(); + $this->drupalLogin($user_2); + + // Flag node (second count). + $this->drupalGet('node/' . $node_id); + $this->clickLink('Flag this item'); + $this->assertResponse(200); + $this->assertLink('Unflag this item'); + + // Check for 2 flag counts. + $count_flags_after = \Drupal::entityQuery('flag_counts') + ->condition('fid', $this->id) + ->condition('entity_type', $node->getEntityTypeId()) + ->condition('entity_id', $node_id) + ->count() + ->execute(); + $this->assertTrue(2, $count_flags_after); + + // Unflag the node again. + $this->drupalGet('node/' . $node_id); + $this->clickLink('Unflag this item'); + $this->assertResponse(200); + $this->assertLink('Flag this item'); + + // Check for 1 flag count. + $count_flags_before = \Drupal::entityQuery('flag_counts') + ->condition('fid', $this->id) + ->condition('entity_type', $node->getEntityTypeId()) + ->condition('entity_id', $node_id) + ->count() + ->execute(); + $this->assertTrue(1, $count_flags_before); + + // Delete user 1. + $user_1->delete(); + + // Check for 0 flag counts, user deletion should lead to count decrement + // or row deletion. + $count_flags_before = \Drupal::entityQuery('flag_counts') + ->condition('fid', $this->id) + ->condition('entity_type', $node->getEntityTypeId()) + ->condition('entity_id', $node_id) + ->count() + ->execute(); + $this->assertTrue(0, $count_flags_before); + } } From 3af54ea325ab2ff86978e36da586cb11dbc5674c Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Mon, 7 Jul 2014 13:55:46 +0200 Subject: [PATCH 438/629] Fixed hook requirements to enable successful installation. --- flag.install | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flag.install b/flag.install index 3e7100b..677b461 100644 --- a/flag.install +++ b/flag.install @@ -76,9 +76,9 @@ function flag_uninstall() { * Implements hook_requirements(). */ function flag_requirements($phase) { - /* - $requirements = array(); + $requirements = array(); + /* if ($phase == 'runtime') { if (module_exists('translation') && !module_exists('translation_helpers')) { $requirements['flag_translation'] = array( @@ -107,6 +107,6 @@ function flag_requirements($phase) { } } } - return $requirements; */ + return $requirements; } From 4f724fe55132947a77694a88dcc0be30fa2f9820 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Tue, 8 Jul 2014 13:57:31 +0200 Subject: [PATCH 439/629] Fix and simplify flag_counts schema --- flag.install | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/flag.install b/flag.install index 9992e0b..572606b 100644 --- a/flag.install +++ b/flag.install @@ -16,40 +16,29 @@ function flag_schema() { 'fields' => array( 'fid' => array( 'type' => 'varchar', - 'size' => '255', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, + 'length' => '32', ), 'entity_type' => array( 'description' => 'The flag type, usually one of "node", "comment", "user".', 'type' => 'varchar', 'length' => '128', - 'not null' => TRUE, - 'default' => '', ), 'entity_id' => array( 'description' => 'The unique ID of the content, usually either the {cid}, {uid}, or {nid}.', 'type' => 'int', 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, 'disp-width' => '10', ), 'count' => array( 'description' => 'The number of times this object has been flagged for this flag.', 'type' => 'int', 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, 'disp-width' => '10', ), 'last_updated' => array( 'description' => 'The UNIX time stamp representing when the flag was last updated.', 'type' => 'int', 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, 'disp-size' => 11, ) ), From f72df551ce0c600f30fb2e574900985a4cc109d3 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Fri, 11 Jul 2014 16:42:48 +0200 Subject: [PATCH 440/629] Removed getInfo() and deleted unused/missplaced test including it's parent folder structure. --- src/Tests/FlagSimpleTest.php | 15 +++------------ tests/src/FlagTestBase.php | 16 ---------------- 2 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 tests/src/FlagTestBase.php diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index a41c2db..9f4b70e 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -12,7 +12,9 @@ /** - * Tests the Flag forms (add/edit/delete). + * Tests the Flag form actions (add/edit/delete). + * + * @group Flag */ class FlagSimpleTest extends WebTestBase { @@ -52,17 +54,6 @@ class FlagSimpleTest extends WebTestBase { */ public static $modules = array('views', 'flag', 'node', 'field_ui'); - /** - * {@inheritdoc} - */ - public static function getInfo() { - return array( - 'name' => 'Flag form/s', - 'description' => 'Creates a flag, adds flag to node.', - 'group' => 'Flag', - ); - } - /** * Configures test base and executes test cases. */ diff --git a/tests/src/FlagTestBase.php b/tests/src/FlagTestBase.php deleted file mode 100644 index 7bdb96c..0000000 --- a/tests/src/FlagTestBase.php +++ /dev/null @@ -1,16 +0,0 @@ - Date: Fri, 11 Jul 2014 18:23:57 +0200 Subject: [PATCH 441/629] module_invoke_all() has been removed --- flag.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index ad8ff15..619edc5 100644 --- a/flag.module +++ b/flag.module @@ -249,7 +249,7 @@ function flag_fetch_definition($entity_type = NULL) { $definitions = $cache->data; } else { - $definitions = module_invoke_all('flag_type_info'); + $definitions = \Drupal::moduleHandler()->invokeAll('flag_type_info'); drupal_alter('flag_type_info', $definitions); \Drupal::cache()->set('flag_type_info', $definitions); @@ -1881,7 +1881,7 @@ function flag_reset_flag($flag, $entity_id = NULL) { foreach ($result as $row) { $rows[] = $row; } - module_invoke_all('flag_reset', $flag, $entity_id, $rows); + \Drupal::moduleHandler()->invokeAll('flag_reset', array($flag, $entity_id, $rows)); $query = db_delete('flagging')->condition('fid' , $flag->fid); // Update the flag_counts table. From 53e12cf4b5402ae9ae6c28f86752a08feba4e6c3 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 11 Jul 2014 19:37:36 +0200 Subject: [PATCH 442/629] entity_type argument to hook_entity_delete() was removed. --- flag.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index ad8ff15..f6ab5be 100644 --- a/flag.module +++ b/flag.module @@ -681,10 +681,10 @@ function flag_node_save($node) { /** * Implements hook_entity_delete(). */ -function flag_entity_delete($entity, $type) { +function flag_entity_delete(EntityInterface $entity) { // Node and user flags handle things through the entity type delete hooks. // @todo: make this configurable in the flag type definition? - if ($type == 'node' || $type == 'user') { + if ($entity->getEntityTypeId() == 'node' || $entity->getEntityTypeId() == 'user') { return; } From 66c00b0095f0fe2420a8eee032404b0eede575a8 Mon Sep 17 00:00:00 2001 From: Jibran Ijaz Date: Sat, 12 Jul 2014 00:27:36 +0500 Subject: [PATCH 443/629] Added travis support. --- .travis.yml | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6d8954c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,64 @@ +language: php + +php: + - 5.4 + - 5.5 + +mysql: + database: flag + username: root + encoding: utf8 + +before_install: + - sudo apt-get update > /dev/null + # Always update Composer to the recent version, otherwise the drush + # installation fails. + - composer selfupdate + +install: + # Install php packages required for running a web server from drush. + - sudo apt-get install -y --force-yes php5-cgi php5-mysql + + # Add composer's global bin directory to the path. + # @see: https://github.com/drush-ops/drush#install---composer + - export PATH="$HOME/.composer/vendor/bin:$PATH" + + # install drush globally + - composer global require drush/drush:dev-master + - composer global require youngj/httpserver:dev-master + +before_script: + # Remember the current flag test directory for later use in the Drupal + # installation. + - TESTDIR=$(pwd) + # Navigate out of module directory to prevent blown stack by recursive module + # lookup. + - cd .. + + # Create new site, stubbing sendmail path with true to prevent delivery errors + # and manually resolving drush path. + - mysql -e 'create database flag' + # Download Drupal 8 core. + - wget -q -O - http://ftp.drupal.org/files/projects/drupal-8.x-dev.tar.gz | tar xz + - cd drupal-8.x-dev + # Install Drupal. + - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@127.0.0.1/flag testing + + # Reference and enable flag in build site. + - ln -s $TESTDIR modules/flag + - drush --yes pm-enable simpletest flag + + # Switch to core directory where we will execute PHPUnit. + - cd core + + # Start a web server on port 8080, run in the background; wait for + # initialization. This is temporarly disabled since there are no web tests + # yet. + #- drush runserver 127.0.0.1:8080 & + #- until netstat -an 2>/dev/null | grep '8080.*LISTEN'; do true; done + +script: + # Run the Simpletests for flag. + - drush test-run 'flag' --uri=http://127.0.0.1:8080 + # Run the PHPUnit tests. +# - ./vendor/phpunit/phpunit/phpunit ../modules/flag From 55413ea1a000062a96ef23eb82d28c633f8cf431 Mon Sep 17 00:00:00 2001 From: Jibran Ijaz Date: Sun, 13 Jul 2014 07:33:59 +0500 Subject: [PATCH 444/629] Added PHPCS to .travis.yml and Updated simpetest script. --- .travis.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6d8954c..93e30c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,12 @@ install: # install drush globally - composer global require drush/drush:dev-master - composer global require youngj/httpserver:dev-master + - composer global require squizlabs/php_codesniffer:2.0.*@dev + - composer global require drupal/coder:dev-8.x-2.x before_script: + # Create a Drupal coding standard reference in PHPCS coding standards. + - ln -s ~/.composer/vendor/drupal/coder/coder_sniffer/Drupal ~/.composer/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards # Remember the current flag test directory for later use in the Drupal # installation. - TESTDIR=$(pwd) @@ -48,9 +52,6 @@ before_script: - ln -s $TESTDIR modules/flag - drush --yes pm-enable simpletest flag - # Switch to core directory where we will execute PHPUnit. - - cd core - # Start a web server on port 8080, run in the background; wait for # initialization. This is temporarly disabled since there are no web tests # yet. @@ -58,7 +59,9 @@ before_script: #- until netstat -an 2>/dev/null | grep '8080.*LISTEN'; do true; done script: - # Run the Simpletests for flag. - - drush test-run 'flag' --uri=http://127.0.0.1:8080 + # Run the Coder sniffer for Flag. + - phpcs --report=full --standard=Drupal ./modules/flag + # Run the Simpletests for Flag. + - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://127.0.0.1:8080 --verbose --color "flag" # Run the PHPUnit tests. -# - ./vendor/phpunit/phpunit/phpunit ../modules/flag + - ./core/vendor/phpunit/phpunit/phpunit -c ./core/phpunit.xml.dist ./modules/flag From 723b2067d4f93e0c12b20d23a03db2bb691fe940 Mon Sep 17 00:00:00 2001 From: Jibran Ijaz Date: Sun, 13 Jul 2014 19:45:38 +0500 Subject: [PATCH 445/629] Updated .travis.yml. --- .travis.yml | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93e30c4..d636141 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,19 @@ php: - 5.5 mysql: - database: flag + database: drupal username: root encoding: utf8 +env: + global: + - MODULE_NAME='flag' + - MODULE_TEST_GROUP='flag' + - DRUPAL_REPO='git://drupalcode.org/project/drupal.git' + - DRUPAL_VERSION='8.x' + - PHPCS_VERSION='2.0.*@dev' + - CODER_VERSION='dev-8.x-2.x' + before_install: - sudo apt-get update > /dev/null # Always update Composer to the recent version, otherwise the drush @@ -26,8 +35,8 @@ install: # install drush globally - composer global require drush/drush:dev-master - composer global require youngj/httpserver:dev-master - - composer global require squizlabs/php_codesniffer:2.0.*@dev - - composer global require drupal/coder:dev-8.x-2.x + - composer global require squizlabs/php_codesniffer:$PHPCS_VERSION + - composer global require drupal/coder:$CODER_VERSION before_script: # Create a Drupal coding standard reference in PHPCS coding standards. @@ -41,27 +50,27 @@ before_script: # Create new site, stubbing sendmail path with true to prevent delivery errors # and manually resolving drush path. - - mysql -e 'create database flag' + - mysql -e 'create database drupal' # Download Drupal 8 core. - - wget -q -O - http://ftp.drupal.org/files/projects/drupal-8.x-dev.tar.gz | tar xz - - cd drupal-8.x-dev + - git clone --branch $DRUPAL_VERSION $DRUPAL_REPO drupal + - cd drupal # Install Drupal. - - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@127.0.0.1/flag testing + - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@127.0.0.1/drupal testing # Reference and enable flag in build site. - - ln -s $TESTDIR modules/flag - - drush --yes pm-enable simpletest flag + - ln -s $TESTDIR modules/$MODULE_NAME + - drush --yes pm-enable simpletest $MODULE_NAME # Start a web server on port 8080, run in the background; wait for # initialization. This is temporarly disabled since there are no web tests # yet. - #- drush runserver 127.0.0.1:8080 & - #- until netstat -an 2>/dev/null | grep '8080.*LISTEN'; do true; done + - drush runserver 127.0.0.1:8080 & + - until netstat -an 2>/dev/null | grep '8080.*LISTEN'; do true; done script: # Run the Coder sniffer for Flag. - - phpcs --report=full --standard=Drupal ./modules/flag + - phpcs --report=full --standard=Drupal ./modules/$MODULE_NAME # Run the Simpletests for Flag. - - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://127.0.0.1:8080 --verbose --color "flag" + - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://127.0.0.1:8080 --verbose --color "$MODULE_TEST_GROUP" # Run the PHPUnit tests. - - ./core/vendor/phpunit/phpunit/phpunit -c ./core/phpunit.xml.dist ./modules/flag + - ./core/vendor/phpunit/phpunit/phpunit -c ./core/phpunit.xml.dist ./modules/$MODULE_NAME From edd3afbd743321c4bf39751e1e1fcbfe5826890f Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Mon, 14 Jul 2014 12:14:51 +0200 Subject: [PATCH 446/629] Fix and simplify merge query --- src/FlagService.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index c8d9f73..c459a49 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -233,13 +233,10 @@ protected function incrementFlagCounts(FlagInterface $flag, EntityInterface $ent 'fid' => $flag->id(), 'entity_id' => $entity->id(), 'entity_type' => $entity->getEntityTypeId(), - 'last_updated' => time(), )) ->fields(array( - 'fid' => $flag->id(), - 'entity_id' => $entity->id(), - 'entity_type' => $entity->getEntityTypeId(), - 'count' => 1 + 'last_updated' => REQUEST_TIME, + 'count' => 1, )) ->expression('count', 'count + :inc', array(':inc' => 1)) ->execute(); @@ -276,4 +273,4 @@ protected function decrementFlagCounts(FlagInterface $flag, EntityInterface $ent } } -} \ No newline at end of file +} From c42d4a932f3fb283ca56e683875f4c451677aee5 Mon Sep 17 00:00:00 2001 From: Jibran Ijaz Date: Tue, 15 Jul 2014 09:59:19 +0500 Subject: [PATCH 447/629] Updated .travis.yml. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d636141..c204734 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ before_script: # and manually resolving drush path. - mysql -e 'create database drupal' # Download Drupal 8 core. - - git clone --branch $DRUPAL_VERSION $DRUPAL_REPO drupal + - git clone --depth 1 --branch $DRUPAL_VERSION $DRUPAL_REPO drupal - cd drupal # Install Drupal. - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@127.0.0.1/drupal testing From 8ba4715d698d9472f49fca3b0b029f7559423e06 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Tue, 15 Jul 2014 12:29:05 +0200 Subject: [PATCH 448/629] Updated label to label(). --- src/Controller/FlagListController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 44aaede..5879ce5 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -34,7 +34,7 @@ protected function getFlagRoles(FlagInterface $flag) { $roles = user_roles(FALSE, $perm); foreach ($roles as $rid => $role) { - $allRoles[$rid] = $role->label; + $allRoles[$rid] = $role->label(); } } From a2be0915a1ef3461171fdbf82dccc537da6f40e0 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 18 Jul 2014 16:06:26 +0200 Subject: [PATCH 449/629] Fixed case of Url class --- src/ActionLinkTypeBase.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 55ff42a..21749d6 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -8,7 +8,7 @@ namespace Drupal\flag; -use Drupal\Core\URL; +use Drupal\Core\Url; use Drupal\Core\Entity\EntityInterface; use \Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Component\Plugin\PluginBase; @@ -52,7 +52,7 @@ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) 'entity_id' => $entity->id(), ); - return new URL($this->routeName($action), $parameters); + return new Url($this->routeName($action), $parameters); } public function renderLink($action, FlagInterface $flag, EntityInterface $entity) { @@ -149,4 +149,4 @@ public function setConfiguration(array $configuration) { $this->configuration = $configuration; } -} \ No newline at end of file +} From ad0e87ffad4d1c5a42ca34e7d1b4334d000e55e4 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 18 Jul 2014 11:43:42 -0500 Subject: [PATCH 450/629] Changed YAML file names due to https://www.drupal.org/node/2302893 --- flag.local_actions.yml => flag.links.action.yml | 0 flag.menu_links.yml => flag.links.menu.yml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename flag.local_actions.yml => flag.links.action.yml (100%) rename flag.menu_links.yml => flag.links.menu.yml (100%) diff --git a/flag.local_actions.yml b/flag.links.action.yml similarity index 100% rename from flag.local_actions.yml rename to flag.links.action.yml diff --git a/flag.menu_links.yml b/flag.links.menu.yml similarity index 100% rename from flag.menu_links.yml rename to flag.links.menu.yml From 6d119bf04c7bfbb126ccbf9b175d7ea7d052d48a Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 18 Jul 2014 11:47:28 -0500 Subject: [PATCH 451/629] Fixed broken FlagListController due to module_exists() going away. --- src/Controller/FlagListController.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 5879ce5..a821f57 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -67,7 +67,7 @@ public function render() { $output = ""; //@todo Move this too hook_help()? - if (!module_exists('views')) { + if (!\Drupal::moduleHandler()->moduleExists('views')) { $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; } else { @@ -80,14 +80,14 @@ public function render() { $output .= '

'; } - if (!module_exists('flag_actions')) { + if (!\Drupal::moduleHandler()->moduleExists('flag_actions')) { $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules'))) . '

'; } else { $output .= '

' . t('Flagging an item may trigger actions.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'))) . '

'; } - if (!module_exists('rules')) { + if (!\Drupal::moduleHandler()->moduleExists('rules')) { $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', array('@rules-url' => url('http://drupal.org/node/407070'))) . '

'; } else { From 15d623bf2c00892c4bb67a882711333221d2abd8 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 18 Jul 2014 12:20:53 -0500 Subject: [PATCH 452/629] Removed trigger module references. --- flag.module | 83 ----------------------------------------------------- 1 file changed, 83 deletions(-) diff --git a/flag.module b/flag.module index ba9864f..1f2f494 100644 --- a/flag.module +++ b/flag.module @@ -930,89 +930,6 @@ function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { )); } -/** - * Flags or unflags an item. - * - * @param $action - * Either 'flag' or 'unflag'. - * @param $flag_name - * The name of the flag to use. - * @param $entity_id - * The ID of the item to flag or unflag. - * @param $account - * (optional) The user on whose behalf to flag. Omit for the current user. - * @param permissions_check - * (optional) A boolean indicating whether to skip permissions. - * - * @return - * FALSE if some error occured (e.g., user has no permission, flag isn't - * applicable to the item, etc.), TRUE otherwise. - */ -function flag($action, $flag_name, $entity_id, $account = NULL, $permissions_check = FALSE) { - if (!($flag = flag_get_flag($flag_name))) { - // Flag does not exist. - return FALSE; - } - return $flag->flag($action, $entity_id, $account, $permissions_check); -} - -/** - * Implements hook_flag_flag(). - */ -function flag_flag_flag($flag, $entity_id, $account, $flagging) { - if (module_exists('trigger')) { - flag_flag_trigger('flag', $flag, $entity_id, $account, $flagging); - } -} - -/** - * Implements hook_flag_unflag(). - */ -function flag_flag_unflag($flag, $entity_id, $account, $flagging) { - if (module_exists('trigger')) { - flag_flag_trigger('unflag', $flag, $entity_id, $account, $flagging); - } -} - -/** - * Trigger actions if any are available. Helper for hook_flag_(un)flag(). - * - * @param $op - * The operation being performed: one of 'flag' or 'unflag'. - * @param $flag - * The flag object. - * @param $entity_id - * The id of the entity the flag is on. - * @param $account - * The user account performing the action. - * @param $flagging_id - * The flagging entity. - */ -function flag_flag_trigger($action, $flag, $entity_id, $account, $flagging) { - $context['hook'] = 'flag'; - $context['account'] = $account; - $context['flag'] = $flag; - $context['op'] = $action; - // We add to the $context all the objects we know about: - $context = array_merge($flag->get_relevant_action_objects($entity_id), $context); - // The primary object the actions work on. - $object = $flag->fetch_entity($entity_id); - - // Generic "all flags" actions. - foreach (trigger_get_assigned_actions('flag_' . $action) as $aid => $action_info) { - // The 'if ($aid)' is a safeguard against http://drupal.org/node/271460#comment-886564 - if ($aid) { - actions_do($aid, $object, $context); - } - } - // Actions specifically for this flag. - foreach (trigger_get_assigned_actions('flag_' . $action . '_' . $flag->name) as $aid => $action_info) { - if ($aid) { - actions_do($aid, $object, $context); - } - } -} - /** * Implements hook_flag_access(). */ From 8027ef968bac403beb6b47139a78df39878e8129 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Tue, 15 Jul 2014 14:17:29 +0200 Subject: [PATCH 453/629] Fixed deprecated function module_exists(), tests working again. --- flag.install | 4 ++-- flag.module | 14 +++++++------- flag.tokens.inc | 2 +- src/Form/FlagFormBase.php | 2 +- src/Plugin/Flag/EntityFlagType.php | 2 +- src/Plugin/Flag/NodeFlagType.php | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/flag.install b/flag.install index e3fcc94..2af50ac 100644 --- a/flag.install +++ b/flag.install @@ -69,7 +69,7 @@ function flag_requirements($phase) { $requirements = array(); /* if ($phase == 'runtime') { - if (module_exists('translation') && !module_exists('translation_helpers')) { + if (\Drupal::moduleHandler()->moduleExists('translation') && !\Drupal::moduleHandler()->moduleExists('translation_helpers')) { $requirements['flag_translation'] = array( 'title' => t('Flag'), 'severity' => REQUIREMENT_ERROR, @@ -77,7 +77,7 @@ function flag_requirements($phase) { 'value' => t('Translation helpers module not found.'), ); } - if (module_exists('session_api')) { + if (\Drupal::moduleHandler()->moduleExists('session_api')) { if (file_exists('./robots.txt')) { $flag_path = url('flag') . '/'; // We don't use url() because this may return an absolute URL when diff --git a/flag.module b/flag.module index 1f2f494..d5e9512 100644 --- a/flag.module +++ b/flag.module @@ -94,7 +94,7 @@ function flag_admin_menu_map() { ), ); - if (module_exists('field_ui')) { + if (\Drupal::moduleHandler()->moduleExists('field_ui')) { foreach (entity_get_info() as $obj_type => $info) { if ($obj_type == 'flagging') { foreach ($info['bundles'] as $bundle_name => $bundle_info) { @@ -198,7 +198,7 @@ function flag_help($route_name, RouteMatchInterface $route_match) { $output .= t("Field values may be edited when flaggings are created because this flag's link type shows a form for the flagging. However, to edit field values on existing flaggings, you will need to set your flag to use the Flagging form link type. This is provided by the Flagging Form module.", array( '!flagging-form-url' => 'http://drupal.org/project/flagging_form', )); - if (!module_exists('flagging_form')) { + if (!\Drupal::moduleHandler()->moduleExists('flagging_form')) { $output .= ' ' . t("You do not currently have this module enabled.") . ''; @@ -217,7 +217,7 @@ function flag_help($route_name, RouteMatchInterface $route_match) { $output .= '

' . t("Additionally, to edit field values on existing flaggings, you will need to set your flag to use the Flagging form link type. This is provided by the Flagging Form module.", array( '!flagging-form-url' => 'http://drupal.org/project/flagging_form', )); - if (!module_exists('flagging_form')) { + if (!\Drupal::moduleHandler()->moduleExists('flagging_form')) { $output .= ' ' . t("You do not currently have this module enabled.") . ''; @@ -250,7 +250,7 @@ function flag_fetch_definition($entity_type = NULL) { } else { $definitions = \Drupal::moduleHandler()->invokeAll('flag_type_info'); - drupal_alter('flag_type_info', $definitions); + \Drupal::moduleHandler()->alter('flag_type_info', $definitions); \Drupal::cache()->set('flag_type_info', $definitions); } @@ -307,7 +307,7 @@ function flag_permission() { * anonymous users when Session API module is not enabled. */ function flag_form_user_admin_permissions_alter(&$form, &$form_state, $form_id) { - if (!module_exists('session_api')) { + if (!\Drupal::moduleHandler()->moduleExists('session_api')) { $flags = \Drupal::service('flag')->getFlags(); // Disable flag and unflag permission checkboxes for anonymous users. foreach ($flags as $flag_name => $flag) { @@ -759,7 +759,7 @@ function _flag_entity_delete($entity_type, $entity_id, $fid = NULL) { */ function flag_user_login($account) { // Migrate anonymous flags to this user's account. - if (module_exists('session_api') && ($sid = flag_get_sid(0))) { + if (\Drupal::moduleHandler()->moduleExists('session_api') && ($sid = flag_get_sid(0))) { // Get a list of flagging IDs that will be moved over. $duplicate_flaggings = array(); $flaggings = db_select('flagging', 'fc') @@ -1903,7 +1903,7 @@ function flag_set_sid($uid = NULL, $create = TRUE) { // Set the sid if none has been set yet. If the caller specified to create an // sid and we have an invalid one (-1), create it. if (!isset($sids[$uid]) || ($sids[$uid] == -1 && $create)) { - if (module_exists('session_api') && session_api_available() && $uid == 0) { + if (\Drupal::moduleHandler()->moduleExists('session_api') && session_api_available() && $uid == 0) { // This returns one of the following: // - -1. This indicates that no session exists and none was created. // - A positive integer with the Session ID when it does exist. diff --git a/flag.tokens.inc b/flag.tokens.inc index d25967d..59f7c17 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -186,7 +186,7 @@ function theme_flag_tokens_browser($variables) { $types = $variables['types']; $global_types = $variables['global_types']; - if (module_exists('token')) { + if (\Drupal::moduleHandler()->moduleExists('token')) { return theme('token_tree', array('token_types' => $types, 'global_types' => $global_types)); } else { diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index f50b0e9..8c9a53b 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -300,7 +300,7 @@ public function save(array $form, array &$form_state) { } } /* - foreach (array_keys(user_roles(!module_exists('session_api'))) as $rid) { + foreach (array_keys(user_roles(!\Drupal::moduleHandler()->moduleExists('session_api'))) as $rid) { // Create an array of permissions, based on the checkboxes element name. $permissions = array( "flag $flag->name" => $flag->roles['flag'][$rid], diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 339d879..1f085f8 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -102,7 +102,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#title' => t('Display in contextual links'), '#default_value' => $this->showContextualLink(), '#description' => t('Note that not all entity types support contextual links.'), - '#access' => module_exists('contextual'), + '#access' => \Drupal::moduleHandler()->moduleExists('contextual'), '#weight' => 10, ); diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index e97fe9b..5430fd1 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -63,7 +63,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { ), //'#default_value' => $this->i18n, '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), - '#access' => module_exists('translation_helpers'), + '#access' => \Drupal::moduleHandler()->moduleExists('translation_helpers'), '#weight' => 5, ); From 3e8c82bead93046fcde06a5692c0513d8f88e91b Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 18 Jul 2014 20:43:47 +0200 Subject: [PATCH 454/629] Fix test group --- src/Tests/FlagSimpleTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 97d65bf..adf50ed 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -14,7 +14,7 @@ /** * Tests the Flag form actions (add/edit/delete). * - * @group Flag + * @group flag */ class FlagSimpleTest extends WebTestBase { From 3345ca37132fb775f2971ff203f5b9b9b18b5c3b Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Mon, 14 Jul 2014 11:47:35 +0200 Subject: [PATCH 455/629] Fix redirect on reload controller. --- src/Controller/ReloadLinkController.php | 30 ++++++++++++------------- src/FlaggingInterface.php | 10 ++++++++- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index b4dc711..e8d0999 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -19,27 +19,27 @@ class ReloadLinkController extends ControllerBase { public function flag(Request $request, $flag_id, $entity_id) { - + /* @var \Drupal\flag\FlaggingInterface $flagging */ $flagging = \Drupal::service('flag')->flag($flag_id, $entity_id); - // Get the destination. - $destination = $request->get('destination', $flagging->getFlaggable()->url()); - - //@todo SECURITY HOLE. Please fix! - return new RedirectResponse($destination); + // Redirect back to the entity. A passed in destination query parameter + // will automatically override this. + $url_info = $flagging->getFlaggable()->urlInfo(); + return $this->redirect($url_info->getRouteName(), $url_info->getRouteParameters()); } public function unflag(Request $request, $flag_id, $entity_id) { - $flagService = \Drupal::service('flag'); - $flagService->unflag($flag_id, $entity_id); - - $flag = $flagService->getFlagById($flag_id); - $entity = $flagService->getFlaggableById($flag, $entity_id); + /* @var \Drupal\flag\FlagService $flag_service */ + $flag_service = \Drupal::service('flag'); + $flag_service->unflag($flag_id, $entity_id); - $destination = \Drupal::request()->get('destination', $entity->url()); + $flag = $flag_service->getFlagById($flag_id); + $entity = $flag_service->getFlaggableById($flag, $entity_id); - //@todo SECURITY HOLE. Please fix! - return new RedirectResponse($destination); + // Redirect back to the entity. A passed in destination query parameter + // will automatically override this. + $url_info = $entity->urlInfo(); + return $this->redirect($url_info->getRouteName(), $url_info->getRouteParameters()); } -} \ No newline at end of file +} diff --git a/src/FlaggingInterface.php b/src/FlaggingInterface.php index e75dc72..6fbe5b9 100644 --- a/src/FlaggingInterface.php +++ b/src/FlaggingInterface.php @@ -14,4 +14,12 @@ interface FlaggingInterface extends ContentEntityInterface { public function getFlag(); -} \ No newline at end of file + /** + * Returns the flaggable entity. + * + * @return \Drupal\Core\Entity\EntityInterface + * The entity object. + */ + public function getFlaggable(); + +} From f6d736ac7edcbc48bc6a445bafb666ba614717e3 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Mon, 14 Jul 2014 12:31:31 +0200 Subject: [PATCH 456/629] Fix the destination path --- src/ActionLinkTypeBase.php | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 21749d6..a1001b1 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -44,7 +44,17 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi abstract public function routeName($action = NULL); /** - * @return string + * Returns a Url object for the given flag action. + * + * @param string $action + * The action, flag or unflag. + * @param \Drupal\flag\FlagInterface $flag + * The flag entity + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity. + * + * @return \Drupal\Core\Url + * The URL object. */ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) { $parameters = array( @@ -55,16 +65,20 @@ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) return new Url($this->routeName($action), $parameters); } + /** + * {@inheritdoc} + */ public function renderLink($action, FlagInterface $flag, EntityInterface $entity) { $url = $this->buildLink($action, $flag, $entity); - $url->setRouteParameter('destination', \Drupal::request()->getRequestUri()); + // @todo: Use whatever https://www.drupal.org/node/2302065 comes up with + // instead. + $url->setOption('destination', current_path()); $render = $url->toRenderArray(); $render['#type'] = 'link'; $render['#attributes']['id'] = 'flag-' . $flag->id() . '-id-' . $entity->id(); - //@todo check if flagged, assign flag or unflag text. if ($action === 'unflag') { $render['#title'] = $flag->unflag_short; $render['#alt'] = $flag->unflag_long; From 8f518bff43ccba41968428e59ad4eff7bde10f2c Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Mon, 14 Jul 2014 12:34:26 +0200 Subject: [PATCH 457/629] Use route parameter instead of option --- src/ActionLinkTypeBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index a1001b1..a1b1bc2 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -73,7 +73,7 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity // @todo: Use whatever https://www.drupal.org/node/2302065 comes up with // instead. - $url->setOption('destination', current_path()); + $url->setRouteParameter('destination', current_path()); $render = $url->toRenderArray(); $render['#type'] = 'link'; From 500a9696172ccb07d7a37b18f4d67110266c5f5e Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 18 Jul 2014 22:42:01 +0200 Subject: [PATCH 458/629] fix trailing whitespaces --- src/Controller/ReloadLinkController.php | 2 +- src/FlaggingInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index e8d0999..fd54d68 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -42,4 +42,4 @@ public function unflag(Request $request, $flag_id, $entity_id) { return $this->redirect($url_info->getRouteName(), $url_info->getRouteParameters()); } -} +} diff --git a/src/FlaggingInterface.php b/src/FlaggingInterface.php index 6fbe5b9..baf330e 100644 --- a/src/FlaggingInterface.php +++ b/src/FlaggingInterface.php @@ -22,4 +22,4 @@ public function getFlag(); */ public function getFlaggable(); -} +} From f469062ad2c317e4b1eadcbfb4f4a998e0628a53 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 09:46:50 +0200 Subject: [PATCH 459/629] Fixed flag deletion when user is deleted. --- flag.module | 16 ++++++++------- src/Tests/FlagSimpleTest.php | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/flag.module b/flag.module index c46afa3..e357441 100644 --- a/flag.module +++ b/flag.module @@ -16,6 +16,8 @@ use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\user\UserInterface; +use Symfony\Component\HttpFoundation\Request; // @todo: Implement flagging_view(). Not extremely useful. I already have it. @@ -818,21 +820,21 @@ function flag_user_cancel($edit, $account, $method) { /** * Implements hook_user_delete(). */ -function flag_user_delete($account) { +function flag_user_delete(UserInterface $account) { flag_user_account_removal($account); } /** * Shared helper for user account cancellation or deletion. - *//* -function flag_user_account_removal($account) { + */ +function flag_user_account_removal(UserInterface $account) { // Remove flags by this user. $query = db_select('flagging', 'fc'); $query->leftJoin('flag_counts', 'c', 'fc.entity_id = c.entity_id AND fc.entity_type = c.entity_type'); $result = $query ->fields('fc', array('fid', 'entity_id')) ->fields('c', array('count')) - ->condition('fc.uid', $account->uid) + ->condition('fc.uid', $account->id()) ->execute(); foreach ($result as $flag_data) { @@ -855,12 +857,12 @@ function flag_user_account_removal($account) { } } db_delete('flagging') - ->condition('uid', $account->uid) + ->condition('uid', $account->id()) ->execute(); // Remove flags that have been done to this user. - _flag_entity_delete('user', $account->uid); -}*/ + _flag_entity_delete('user', $account->id()); +} /** * Implements hook_user_view(). diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 16d2790..a50b6a8 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -176,6 +176,44 @@ public function doTestHideFlagLinkFromTeaser() { $this->assertNoLink('Flag this item'); $this->drupalGet('node/' . $node_id); + + } + + /** + * Creates user, sets flags and deletes user. + */ + public function doTestUserDeletion() { + $node = $this->drupalCreateNode(array('type' => $this->nodeType)); + $node_id = $node->id(); + + // Create and login a new user. + $user_1 = $this->drupalCreateUser(); + $this->drupalLogin($user_1); + + $this->drupalGet('node/' . $node_id); + $this->clickLink('Flag this item'); + $this->assertResponse(200); + $this->assertLink('Unflag this item'); + + $count_flags_before = \Drupal::entityQuery('flagging') + ->condition('uid', $user_1->id()) + ->condition('fid', $this->id) + ->condition('entity_type', $node->getEntityTypeId()) + ->condition('entity_id', $node_id) + ->execute(); + + assertCount(1, $count_flags_before); + + $user_1->delete(); + + $count_flags_after = \Drupal::entityQuery('flagging') + ->condition('uid', $user_1->id()) + ->condition('fid', $this->id) + ->condition('entity_type', $node->getEntityTypeId()) + ->condition('entity_id', $node_id) + ->execute(); + + assertCount(0, $count_flags_after); } /** From 00acf5c523bfd5d8bf3dcc8d23e46258a6baae9f Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 17:23:41 +0200 Subject: [PATCH 460/629] Corrected assertions. --- src/Tests/FlagSimpleTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index a50b6a8..570ddd5 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -193,16 +193,17 @@ public function doTestUserDeletion() { $this->drupalGet('node/' . $node_id); $this->clickLink('Flag this item'); $this->assertResponse(200); - $this->assertLink('Unflag this item'); + $this->assertLink('Unflag this item');dfdsffsf $count_flags_before = \Drupal::entityQuery('flagging') ->condition('uid', $user_1->id()) ->condition('fid', $this->id) ->condition('entity_type', $node->getEntityTypeId()) ->condition('entity_id', $node_id) + ->count() ->execute(); - assertCount(1, $count_flags_before); + $this->assertTrue(1, $count_flags_before); $user_1->delete(); @@ -211,9 +212,10 @@ public function doTestUserDeletion() { ->condition('fid', $this->id) ->condition('entity_type', $node->getEntityTypeId()) ->condition('entity_id', $node_id) + ->count() ->execute(); - assertCount(0, $count_flags_after); + $this->assertTrue(0, $count_flags_after); } /** From 612089bf4f4f32cffb37db2b08d184ccb3e70b41 Mon Sep 17 00:00:00 2001 From: James Cazzetta Date: Wed, 2 Jul 2014 17:30:33 +0200 Subject: [PATCH 461/629] Corrected assertions. --- flag.module | 1 - src/Tests/FlagSimpleTest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/flag.module b/flag.module index e357441..443488e 100644 --- a/flag.module +++ b/flag.module @@ -17,7 +17,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\user\UserInterface; -use Symfony\Component\HttpFoundation\Request; // @todo: Implement flagging_view(). Not extremely useful. I already have it. diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 570ddd5..af315a3 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -193,7 +193,7 @@ public function doTestUserDeletion() { $this->drupalGet('node/' . $node_id); $this->clickLink('Flag this item'); $this->assertResponse(200); - $this->assertLink('Unflag this item');dfdsffsf + $this->assertLink('Unflag this item'); $count_flags_before = \Drupal::entityQuery('flagging') ->condition('uid', $user_1->id()) From fa362415a8c7cc502f0d0bfd840e453c1d304057 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:12:20 -0700 Subject: [PATCH 462/629] Clean up automatically generated phpstorm docblock --- src/Controller/ReloadLinkController.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index b4dc711..e52d205 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -1,9 +1,7 @@ Date: Fri, 18 Jul 2014 14:13:21 -0700 Subject: [PATCH 463/629] Remove unused class imports --- src/Controller/ReloadLinkController.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index e52d205..9a478a7 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -7,10 +7,6 @@ namespace Drupal\flag\Controller; use Drupal\Core\Controller\ControllerBase; -use Drupal\flag\FlagInterface; -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Ajax\AjaxResponse; -use Drupal\Core\Ajax\ReplaceCommand; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; From 47a87da8fbfa0d86c0990546ff080c93434eab5c Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:13:53 -0700 Subject: [PATCH 464/629] Import new classes --- src/Controller/ReloadLinkController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 9a478a7..7fd11ca 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -9,6 +9,9 @@ use Drupal\Core\Controller\ControllerBase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\flag\FlagService; class ReloadLinkController extends ControllerBase { From 9654bd7b0c3f6568e692d0d551ae77d809d32481 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:18:19 -0700 Subject: [PATCH 465/629] Inject Flag service from container --- src/Controller/ReloadLinkController.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 7fd11ca..0ca9ee5 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -13,7 +13,24 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\flag\FlagService; -class ReloadLinkController extends ControllerBase { +class ReloadLinkController extends ControllerBase implements ContainerInjectionInterface { + + /** + * @var Drupal\flag\FlagService + */ + protected $flagService; + + public function __construct(FlagService $flag) + { + $this->flagService = $flag; + } + + public static function create(ContainerInterface $container) + { + return new static( + $container->get('flag') + ); + } public function flag(Request $request, $flag_id, $entity_id) { From 6e347bacdc4f58559cd79cf4ac22d099076daa29 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 18 Jul 2014 16:22:31 -0500 Subject: [PATCH 466/629] Removed hooks from flag.api.php that were replaced by plugins and events. --- flag.api.php | 189 --------------------------------------------------- 1 file changed, 189 deletions(-) diff --git a/flag.api.php b/flag.api.php index 9eaea26..4821198 100644 --- a/flag.api.php +++ b/flag.api.php @@ -10,37 +10,6 @@ * @{ */ -/** - * Define one or more flag types. - * - * This hook may be placed in a $module.flag.inc file. - * - * @return - * An array whose keys are flag type names and whose values are properties of - * the flag type. - * When a flag type is for an entity, the flag type name must match the entity - * type. - * Properties for flag types are as follows: - * - 'title': The main label of the flag type. - * - 'description': A longer description shown in the UI when creating a new - * flag. - * - 'handler': The name of the class implementing this flag type. - * - 'module': (optional) The name of the module that should be registered as a - * dependency for this flag type. - * - * @see flag_fetch_definition() - */ -function hook_flag_type_info() { - return array( - 'node' => array( - 'title' => t('Nodes'), - 'description' => t("Nodes are a Drupal site's primary content."), - 'handler' => 'flag_node', - 'module' => 'node', - ), - ); -} - /** * Alter flag type definitions provided by other modules. * @@ -53,43 +22,6 @@ function hook_flag_type_info_alter(&$definitions) { } -/** - * Define default flags. - */ -function hook_flag_default_flags() { - $flags = array(); - $flags['bookmarks'] = array ( - 'entity_type' => 'node', - 'title' => 'Bookmarks', - 'global' => FALSE, - 'types' => array ( - 0 => 'article', - 1 => 'blog', - ), - 'flag_short' => 'Bookmark this', - 'flag_long' => 'Add this post to your bookmarks', - 'flag_message' => 'This post has been added to your bookmarks', - 'unflag_short' => 'Unbookmark this', - 'unflag_long' => 'Remove this post from your bookmarks', - 'unflag_message' => 'This post has been removed from your bookmarks', - 'unflag_denied_text' => '', - 'link_type' => 'toggle', - 'weight' => 0, - 'show_in_links' => array ( - 'full' => TRUE, - 'token' => FALSE, - ), - 'show_as_field' => FALSE, - 'show_on_form' => FALSE, - 'access_author' => '', - 'show_contextual_link' => TRUE, - 'show_on_profile' => FALSE, - 'access_uid' => '', - 'api_version' => 3, - ); - return $flags; -} - /** * Allow modules to alter a flag when it is initially loaded. * @@ -118,41 +50,6 @@ function hook_flag_options_alter(&$options, $flag) { } -/** - * Act on an object being flagged. - * - * @param $flag - * The flag object. - * @param $entity_id - * The id of the entity the flag is on. - * @param $account - * The user account performing the action. - * @param $flagging_id - * The flagging entity. - */ -function hook_flag_flag($flag, $entity_id, $account, $flagging) { - -} - -/** - * Act on an object being unflagged. - * - * This is invoked after the flag count has been decreased, but before the - * flagging entity has been deleted. - * - * @param $flag - * The flag object. - * @param $entity_id - * The id of the entity the flag is on. - * @param $account - * The user account performing the action. - * @param $flagging - * The flagging entity. - */ -function hook_flag_unflag($flag, $entity_id, $account, $flagging) { - -} - /** * Perform custom validation on a flag before flagging/unflagging. * @@ -244,92 +141,6 @@ function hook_flag_access_multiple($flag, $entity_ids, $account) { } -/** - * Define one or more flag link types. - * - * Link types defined here must be returned by this module's hook_flag_link(). - * - * This hook may be placed in a $module.flag.inc file. - * - * @return - * An array of one or more types, keyed by the machine name of the type, and - * where each value is a link type definition as an array with the following - * properties: - * - 'title': The human-readable name of the type. - * - 'description': The description of the link type. - * - 'options': An array of extra options for the link type. - * - 'uses standard js': Boolean, indicates whether the link requires Flag - * module's own JS file for links. - * - 'uses standard css': Boolean, indicates whether the link requires Flag - * module's own CSS file for links. - * - 'provides form': (optional) Boolean indicating that this link type shows - * the user a flagging entity form. This property is used in the UI, eg to - * warn the admin user of link types that are not compatible with other - * flag options. Defaults to FALSE. - * - * @see flag_get_link_types() - * @see hook_flag_link_type_info_alter() - */ -function hook_flag_link_type_info() { - -} - -/** - * Alter other modules' definitions of flag link types. - * - * This hook may be placed in a $module.flag.inc file. - * - * @param $link_types - * An array of the link types defined by all modules. - * - * @see flag_get_link_types() - * @see hook_flag_link_type_info() - */ -function hook_flag_link_type_info_alter(&$link_types) { - -} - -/** - * Return the link for the link types this module defines. - * - * The type of link to be produced is given by $flag->link_type. - * - * When Flag uses a link type provided by this module, it will call this - * implementation of hook_flag_link(). This should return a single link's - * attributes, using the same structure as hook_link(). Note that "title" is - * provided by the Flag configuration if not specified here. - * - * @param $flag - * The full flag object for the flag link being generated. - * @param $action - * The action this link should perform. Either 'flag' or 'unflag'. - * @param $entity_id - * The ID of the node, comment, user, or other object being flagged. The type - * of the object can be deduced from the flag type. - * - * @return - * An array defining properties of the link. - * - * @see hook_flag_link_type_info() - * @see template_preprocess_flag() - */ -function hook_flag_link() { - -} - -/** - * Act on flag deletion. - * - * This is invoked after all the flag database tables have had their relevant - * entries deleted. - * - * @param $flag - * The flag object that has been deleted. - */ -function hook_flag_delete($flag) { - -} - /** * Act when a flag is reset. * From eb6d298cd5d5a196fcbb3bb44bfde35dfe7bbe53 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:31:10 -0700 Subject: [PATCH 467/629] Replace Drupal static use property flagService --- src/Controller/ReloadLinkController.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 0ca9ee5..3a6877c 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -33,8 +33,7 @@ public static function create(ContainerInterface $container) } public function flag(Request $request, $flag_id, $entity_id) { - - $flagging = \Drupal::service('flag')->flag($flag_id, $entity_id); + $flagging = $this->flagService->flag($flag_id, $entity_id); // Get the destination. $destination = $request->get('destination', $flagging->getFlaggable()->url()); @@ -44,13 +43,12 @@ public function flag(Request $request, $flag_id, $entity_id) { } public function unflag(Request $request, $flag_id, $entity_id) { - $flagService = \Drupal::service('flag'); - $flagService->unflag($flag_id, $entity_id); + $this->flagService->unflag($flag_id, $entity_id); - $flag = $flagService->getFlagById($flag_id); - $entity = $flagService->getFlaggableById($flag, $entity_id); + $flag = $this->flagService->getFlagById($flag_id); + $entity = $this->flagService->getFlaggableById($flag, $entity_id); - $destination = \Drupal::request()->get('destination', $entity->url()); + $destination = $request->get('destination', $entity->url()); //@todo SECURITY HOLE. Please fix! return new RedirectResponse($destination); From 3487adf7c4552f602905b9ceed990e84235c21ba Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:57:06 -0700 Subject: [PATCH 468/629] Add missing slash --- src/Controller/ReloadLinkController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 3a6877c..87ddb4e 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -1,7 +1,8 @@ Date: Fri, 18 Jul 2014 14:12:20 -0700 Subject: [PATCH 469/629] Clean up automatically generated phpstorm docblock --- src/Controller/ReloadLinkController.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index fd54d68..4f16c81 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -1,9 +1,7 @@ Date: Fri, 18 Jul 2014 14:13:21 -0700 Subject: [PATCH 470/629] Remove unused class imports --- src/Controller/ReloadLinkController.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 4f16c81..4456bbc 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -7,10 +7,6 @@ namespace Drupal\flag\Controller; use Drupal\Core\Controller\ControllerBase; -use Drupal\flag\FlagInterface; -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Ajax\AjaxResponse; -use Drupal\Core\Ajax\ReplaceCommand; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; From cfce22fb2816dcf7a59cc4d984e9ac873b75663d Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:13:53 -0700 Subject: [PATCH 471/629] Import new classes --- src/Controller/ReloadLinkController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 4456bbc..427df51 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -9,6 +9,9 @@ use Drupal\Core\Controller\ControllerBase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RedirectResponse; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\flag\FlagService; class ReloadLinkController extends ControllerBase { From 6d3649bec14308503db0070a84a751451aece7a8 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:18:19 -0700 Subject: [PATCH 472/629] Inject Flag service from container --- src/Controller/ReloadLinkController.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 427df51..4251e05 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -13,7 +13,24 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\flag\FlagService; -class ReloadLinkController extends ControllerBase { +class ReloadLinkController extends ControllerBase implements ContainerInjectionInterface { + + /** + * @var Drupal\flag\FlagService + */ + protected $flagService; + + public function __construct(FlagService $flag) + { + $this->flagService = $flag; + } + + public static function create(ContainerInterface $container) + { + return new static( + $container->get('flag') + ); + } public function flag(Request $request, $flag_id, $entity_id) { /* @var \Drupal\flag\FlaggingInterface $flagging */ From b717ffaeb03bb54a2f10a5edd3af5f6fee767c72 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 18 Jul 2014 17:08:33 -0500 Subject: [PATCH 473/629] Removed flag_fetch_definition(), flag_get_types(), replaced with FlagService calls. --- flag.module | 50 --------------------------------------- flag.tokens.inc | 4 ++-- src/FlagService.php | 2 ++ src/Form/FlagFormBase.php | 2 -- 4 files changed, 4 insertions(+), 54 deletions(-) diff --git a/flag.module b/flag.module index 443488e..58b2c44 100644 --- a/flag.module +++ b/flag.module @@ -231,56 +231,6 @@ function flag_help($route_name, RouteMatchInterface $route_match) { } } -/** - * Get a flag type definition. - * - * @param $entity_type - * (optional) The entity type to get the definition for, or NULL to return - * all flag types. - * - * @return - * The flag type definition array. - * - * @see hook_flag_type_info() - */ -function flag_fetch_definition($entity_type = NULL) { - $definitions = &drupal_static(__FUNCTION__); - if (!isset($definitions)) { - if ($cache = \Drupal::cache()->get('flag_type_info')) { - $definitions = $cache->data; - } - else { - $definitions = \Drupal::moduleHandler()->invokeAll('flag_type_info'); - \Drupal::moduleHandler()->alter('flag_type_info', $definitions); - - \Drupal::cache()->set('flag_type_info', $definitions); - } - } - - if (isset($entity_type)) { - if (isset($definitions[$entity_type])) { - return $definitions[$entity_type]; - } - } - else { - return $definitions; - } -} - -/** - * Returns all flag types defined on the system. - * - * @return - * An array of flag type names. - */ -function flag_get_types() { - $types = &drupal_static(__FUNCTION__); - if (!isset($types)) { - $types = array_keys(flag_fetch_definition()); - } - return $types; -} - /** * Implements hook_permission(). */ diff --git a/flag.tokens.inc b/flag.tokens.inc index 59f7c17..138c572 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -75,7 +75,7 @@ function flag_token_info() { ); // Add tokens for the flag count available at the node/comment/user level. - foreach (flag_get_types() as $flag_type) { + foreach (\Drupal::service('flag')->fetchDefinition() as $flag_type) { $flags = flag_get_flags($flag_type); foreach ($flags as $flag) { $tokens[$flag_type]['flag-' . str_replace('_', '-', $flag->name) . '-count'] = array( @@ -155,7 +155,7 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr } } - if (isset($data[$type]) && in_array($type, flag_get_types())) { + if (isset($data[$type]) && in_array($type, \Drupal::service('flag')->fetchDefinition())) { $flags = flag_get_flags($type); $object = $data[$type]; foreach ($flags as $flag) { diff --git a/src/FlagService.php b/src/FlagService.php index c459a49..e4b0242 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -45,6 +45,8 @@ public function __construct(ModuleHandlerInterface $module_handler) { * @see hook_flag_type_info() */ public function fetchDefinition($entity_type = NULL) { + //@todo Add caching, PLS! + if(!empty($entity_type)){ return \Drupal::service('plugin.manager.flag.flagtype')->getDefinition($entity_type); } diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 8c9a53b..f3bbfeb 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -19,8 +19,6 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) $flag = $this->entity; - $type_info = flag_fetch_definition($entity_type); - $form['#flag'] = $flag; $form['#flag_name'] = $flag->id; From 8e6797664974aa0960892314605d27abea745502 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:31:10 -0700 Subject: [PATCH 474/629] Replace Drupal static use property flagService --- src/Controller/ReloadLinkController.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 4251e05..d3da712 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -34,7 +34,7 @@ public static function create(ContainerInterface $container) public function flag(Request $request, $flag_id, $entity_id) { /* @var \Drupal\flag\FlaggingInterface $flagging */ - $flagging = \Drupal::service('flag')->flag($flag_id, $entity_id); + $flagging = $this->flagService->flag($flag_id, $entity_id); // Redirect back to the entity. A passed in destination query parameter // will automatically override this. @@ -43,12 +43,10 @@ public function flag(Request $request, $flag_id, $entity_id) { } public function unflag(Request $request, $flag_id, $entity_id) { - /* @var \Drupal\flag\FlagService $flag_service */ - $flag_service = \Drupal::service('flag'); - $flag_service->unflag($flag_id, $entity_id); + $this->flagService->unflag($flag_id, $entity_id); - $flag = $flag_service->getFlagById($flag_id); - $entity = $flag_service->getFlaggableById($flag, $entity_id); + $flag = $this->flagService->getFlagById($flag_id); + $entity = $this->flagService->getFlaggableById($flag, $entity_id); // Redirect back to the entity. A passed in destination query parameter // will automatically override this. From aba8eb993ae75f0c096a8a2134d54c8ca5126fc0 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 14:57:06 -0700 Subject: [PATCH 475/629] Add missing slash --- src/Controller/ReloadLinkController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index d3da712..35ea654 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -1,7 +1,8 @@ Date: Fri, 18 Jul 2014 15:11:45 -0700 Subject: [PATCH 476/629] Remove unused class imports --- src/Controller/ReloadLinkController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 35ea654..f4f4815 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -8,8 +8,6 @@ namespace Drupal\flag\Controller; use Drupal\Core\Controller\ControllerBase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RedirectResponse; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\flag\FlagService; From bbba42c3219c3a36be4f2ef5bd4726cd26b8b086 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 15:12:13 -0700 Subject: [PATCH 477/629] Remove unused paramater --- src/Controller/ReloadLinkController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index f4f4815..0d1bccb 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -31,7 +31,7 @@ public static function create(ContainerInterface $container) ); } - public function flag(Request $request, $flag_id, $entity_id) { + public function flag($flag_id, $entity_id) { /* @var \Drupal\flag\FlaggingInterface $flagging */ $flagging = $this->flagService->flag($flag_id, $entity_id); @@ -41,7 +41,7 @@ public function flag(Request $request, $flag_id, $entity_id) { return $this->redirect($url_info->getRouteName(), $url_info->getRouteParameters()); } - public function unflag(Request $request, $flag_id, $entity_id) { + public function unflag($flag_id, $entity_id) { $this->flagService->unflag($flag_id, $entity_id); $flag = $this->flagService->getFlagById($flag_id); From b301665f10867ac067bc4eabc38797b0187b8159 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 15:42:39 -0700 Subject: [PATCH 478/629] Add missing slash --- src/Controller/ReloadLinkController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 0d1bccb..9e7893d 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -15,7 +15,7 @@ class ReloadLinkController extends ControllerBase implements ContainerInjectionInterface { /** - * @var Drupal\flag\FlagService + * @var \Drupal\flag\FlagService */ protected $flagService; From 213536afdfc301a1274b65d89f5cc01d488ec715 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:30:51 -0700 Subject: [PATCH 479/629] Add arguments to service definition --- flag.services.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.services.yml b/flag.services.yml index 9ff8300..8fa2776 100644 --- a/flag.services.yml +++ b/flag.services.yml @@ -7,4 +7,4 @@ services: arguments: ['@container.namespaces', '@cache.default', '@module_handler'] flag: class: Drupal\flag\FlagService - arguments: ['@module_handler'] + arguments: ['@plugin.manager.flag.flagtype', '@event_dispatcher', '@entity.query', '@current_user', '@entity.manager'] From 795c59787eeff656a42296d42ae2bfa5c42c425c Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:31:41 -0700 Subject: [PATCH 480/629] Remove unused class import --- src/FlagService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/FlagService.php b/src/FlagService.php index e4b0242..79c453d 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -8,7 +8,6 @@ namespace Drupal\flag; -use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\flag\Entity\Flag; use Drupal\flag\Entity\Flagging; From 688f27d825facabc70fc279aefba381678d3bfa3 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:33:24 -0700 Subject: [PATCH 481/629] Import new classes --- src/FlagService.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/FlagService.php b/src/FlagService.php index 79c453d..a7f60cf 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -15,7 +15,10 @@ use Drupal\flag\Event\FlaggingEvent; use Drupal\flag\FlagInterface; use Drupal\Core\Entity\EntityInterface; - +use Drupal\flag\FlagTypePluginManager; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Drupal\Core\Entity\Query\QueryFactory; +use Drupal\Core\Entity\EntityManagerInterface; /** * Flag service. From 7935707c1c400744dc2d3e801a1d440c2c2cf35f Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:34:04 -0700 Subject: [PATCH 482/629] Add class properties --- src/FlagService.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/FlagService.php b/src/FlagService.php index a7f60cf..975eacc 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -25,6 +25,21 @@ */ class FlagService { + /* @var FlagTypePluginManager */ + private $flagType; + + /* @var EventDispatcherInterface */ + private $eventDispatcher; + + /* @var QueryFactory */ + private $entityQuery; + + /* @var AccountInterface */ + private $currentUser; + + /* @var EntityManagerInterface */ + private $entityManager; + /** * Constructor. * From 2b5430f698b51a3ff5607b2b096afcee19596344 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:34:35 -0700 Subject: [PATCH 483/629] Update class constructor --- src/FlagService.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index 975eacc..358b1fa 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -43,10 +43,19 @@ class FlagService { /** * Constructor. * - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ - public function __construct(ModuleHandlerInterface $module_handler) { - $this->moduleHandler = $module_handler; + public function __construct( + FlagTypePluginManager $flagType, + EventDispatcherInterface $eventDispatcher, + QueryFactory $entityQuery, + AccountInterface $currentUser, + EntityManagerInterface $entityManager + ) { + $this->flagType = $flagType; + $this->eventDispatcher = $eventDispatcher; + $this->entityQuery = $entityQuery; + $this->currentUser = $currentUser; + $this->entityManager = $entityManager; } /** From 4889d2b243a0d11eb3add1bf904f838096126278 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:35:05 -0700 Subject: [PATCH 484/629] Add return argument type --- src/FlagService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FlagService.php b/src/FlagService.php index 358b1fa..6736728 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -65,7 +65,7 @@ public function __construct( * (optional) The entity type to get the definition for, or NULL to return * all flag types. * - * @return + * @return array * The flag type definition array. * * @see hook_flag_type_info() From 772d27c88e66ecd642f3e1f877a3988c568d4a61 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:36:20 -0700 Subject: [PATCH 485/629] Remove Drupal static calls --- src/FlagService.php | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index 6736728..01e0fe6 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -74,10 +74,10 @@ public function fetchDefinition($entity_type = NULL) { //@todo Add caching, PLS! if(!empty($entity_type)){ - return \Drupal::service('plugin.manager.flag.flagtype')->getDefinition($entity_type); + return $this->flagType->getDefinition($entity_type); } - return \Drupal::service('plugin.manager.flag.flagtype')->getDefinitions(); + return $this->flagType->getDefinitions(); } /** @@ -98,7 +98,7 @@ public function fetchDefinition($entity_type = NULL) { * An array of the structure [fid] = flag_object. */ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $account = NULL) { - $query = \Drupal::entityQuery('flag'); + $query = $this->entityQuery->get('flag'); if($entity_type != NULL) { $query->condition('entity_type', $entity_type); @@ -128,10 +128,10 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { if($account == NULL) { - $account = \Drupal::currentUser(); + $account = $this->currentUser; } - $result = \Drupal::entityQuery('flagging') + $result = $this->entityQuery->get('flagging') ->condition('uid', $account->id()) ->condition('fid', $flag->id()) ->condition('entity_type', $entity->getEntityTypeId()) @@ -162,7 +162,7 @@ public function getFlaggableById(FlagInterface $flag, $entity_id) { public function flagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { if (empty($account)) { - $account = \Drupal::currentUser(); + $account = $this->currentUser; } $flagging = entity_create('flagging', array( @@ -177,14 +177,13 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $this->incrementFlagCounts($flag, $entity); - \Drupal::entityManager() + $this->entityManager ->getViewBuilder($entity->getEntityTypeId()) ->resetCache(array( $entity, )); - \Drupal::service('event_dispatcher') - ->dispatch(FlagEvents::ENTITY_FLAGGED, new FlaggingEvent($flag, $entity, 'flag')); + $this->eventDispatcher->dispatch(FlagEvents::ENTITY_FLAGGED, new FlaggingEvent($flag, $entity, 'flag')); return $flagging; } @@ -200,7 +199,7 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou */ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { - $account = \Drupal::currentUser(); + $account = $this->currentUser; } $flag = $this->getFlagById($flag_id); @@ -220,7 +219,7 @@ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { */ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { - $account = \Drupal::currentUser(); + $account = $this->currentUser; } $flag = $this->getFlagById($flag_id); @@ -231,10 +230,8 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { return $this->unflagByObject($flag, $entity, $account); } - public function unflagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { - \Drupal::service('event_dispatcher') - ->dispatch(FlagEvents::ENTITY_UNFLAGGED, new FlaggingEvent($flag, $entity, 'unflag')); + $this->eventDispatcher->dispatch(FlagEvents::ENTITY_UNFLAGGED, new FlaggingEvent($flag, $entity, 'unflag')); $out = array(); $flaggings = $this->getFlaggings($entity, $flag); From f772fd090679077c164b808603604e43a67f3497 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 18:36:26 -0700 Subject: [PATCH 486/629] Add return argument type --- src/FlagService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FlagService.php b/src/FlagService.php index 01e0fe6..fee00b3 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -94,7 +94,7 @@ public function fetchDefinition($entity_type = NULL) { * (optional) The user account to filter available flags. If not set, all * flags for the given entity and bundle will be returned. * - * @return + * @return array * An array of the structure [fid] = flag_object. */ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $account = NULL) { From e21c3c810d7be7f10fbd5b2d452ecbfdba72bb65 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 19:01:12 -0700 Subject: [PATCH 487/629] Add constructor docblock arguments --- src/FlagService.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/FlagService.php b/src/FlagService.php index fee00b3..96042fc 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -43,6 +43,11 @@ class FlagService { /** * Constructor. * + * @param FlagTypePluginManager $flagType + * @param EventDispatcherInterface $eventDispatcher + * @param QueryFactory $entityQuery + * @param AccountInterface $currentUser + * @param EntityManagerInterface $entityManager */ public function __construct( FlagTypePluginManager $flagType, From 94952933a48bac89c5917a20c4193106d47322f5 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 19:03:39 -0700 Subject: [PATCH 488/629] Add constructor docblock --- src/Controller/ReloadLinkController.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 9e7893d..d3c176b 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -19,6 +19,11 @@ class ReloadLinkController extends ControllerBase implements ContainerInjectionI */ protected $flagService; + /** + * Constructor. + * + * @param FlagService $flag + */ public function __construct(FlagService $flag) { $this->flagService = $flag; From 54ed30c7febf838bf0a5c4f5eb4d5dbecc453dc7 Mon Sep 17 00:00:00 2001 From: Jesus Manuel Olivas Date: Fri, 18 Jul 2014 19:03:51 -0700 Subject: [PATCH 489/629] Add create docblock --- src/Controller/ReloadLinkController.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index d3c176b..f8d290b 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -29,6 +29,12 @@ public function __construct(FlagService $flag) $this->flagService = $flag; } + /** + * Create. + * + * @param ContainerInterface $container + * @return static + */ public static function create(ContainerInterface $container) { return new static( From e9071a3be603c607dc896267e6cc344dd4e44549 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 19 Jul 2014 09:08:05 -0500 Subject: [PATCH 490/629] Fixed FlagService var names and docblocks. --- src/FlagService.php | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index 96042fc..52ce0ac 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -25,20 +25,30 @@ */ class FlagService { - /* @var FlagTypePluginManager */ - private $flagType; + /** + * @var FlagTypePluginManager + */ + private $flagTypeMgr; - /* @var EventDispatcherInterface */ + /** + * @var EventDispatcherInterface + */ private $eventDispatcher; - /* @var QueryFactory */ - private $entityQuery; + /* + * @var QueryFactory + */ + private $entityQueryMgr; - /* @var AccountInterface */ + /** + * @var AccountInterface + */ private $currentUser; - /* @var EntityManagerInterface */ - private $entityManager; + /* + * @var EntityManagerInterface + * */ + private $entityMgr; /** * Constructor. @@ -56,11 +66,11 @@ public function __construct( AccountInterface $currentUser, EntityManagerInterface $entityManager ) { - $this->flagType = $flagType; + $this->flagTypeMgr = $flagType; $this->eventDispatcher = $eventDispatcher; - $this->entityQuery = $entityQuery; + $this->entityQueryMgr = $entityQuery; $this->currentUser = $currentUser; - $this->entityManager = $entityManager; + $this->entityMgr = $entityManager; } /** @@ -79,10 +89,10 @@ public function fetchDefinition($entity_type = NULL) { //@todo Add caching, PLS! if(!empty($entity_type)){ - return $this->flagType->getDefinition($entity_type); + return $this->flagTypeMgr->getDefinition($entity_type); } - return $this->flagType->getDefinitions(); + return $this->flagTypeMgr->getDefinitions(); } /** @@ -103,7 +113,7 @@ public function fetchDefinition($entity_type = NULL) { * An array of the structure [fid] = flag_object. */ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $account = NULL) { - $query = $this->entityQuery->get('flag'); + $query = $this->entityQueryMgr->get('flag'); if($entity_type != NULL) { $query->condition('entity_type', $entity_type); @@ -136,7 +146,7 @@ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, Accou $account = $this->currentUser; } - $result = $this->entityQuery->get('flagging') + $result = $this->entityQueryMgr->get('flagging') ->condition('uid', $account->id()) ->condition('fid', $flag->id()) ->condition('entity_type', $entity->getEntityTypeId()) @@ -182,7 +192,7 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $this->incrementFlagCounts($flag, $entity); - $this->entityManager + $this->entityMgr ->getViewBuilder($entity->getEntityTypeId()) ->resetCache(array( $entity, From 1da93f027797bc9254c7ca4f0fb29cda34c7ad1e Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Sat, 19 Jul 2014 16:35:50 +0100 Subject: [PATCH 491/629] applied coding standard comments to the Events --- src/Event/FlagDeleteEvent.php | 13 +++++++++---- src/Event/FlagEventBase.php | 19 ++++++++++++++----- src/Event/FlagEvents.php | 5 +---- src/Event/FlaggingEvent.php | 28 ++++++++++++++++++++++++---- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/Event/FlagDeleteEvent.php b/src/Event/FlagDeleteEvent.php index b1ba5cf..7946aaf 100644 --- a/src/Event/FlagDeleteEvent.php +++ b/src/Event/FlagDeleteEvent.php @@ -1,9 +1,7 @@ flag = $flag; } diff --git a/src/Event/FlagEvents.php b/src/Event/FlagEvents.php index 65a2709..12a5d86 100644 --- a/src/Event/FlagEvents.php +++ b/src/Event/FlagEvents.php @@ -1,16 +1,13 @@ Date: Sat, 19 Jul 2014 11:27:41 -0500 Subject: [PATCH 492/629] Updated .gitignore to ignore patch files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 485dee6..7f5b539 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .idea +*.patch From 666b16cfdc9c4f73849c8428885fd846b051b1f0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 19 Jul 2014 11:28:09 -0500 Subject: [PATCH 493/629] Updated docblocks for annotations and controllers. --- src/Annotation/ActionLinkType.php | 6 ++---- src/Annotation/FlagType.php | 6 ++---- src/Controller/AJAXLinkController.php | 19 +++++++++++++++---- src/Controller/FlagListController.php | 22 ++++++++++++++++++---- src/Controller/ReloadLinkController.php | 23 +++++++++++++++++++++++ src/Entity/Flag.php | 4 +--- 6 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/Annotation/ActionLinkType.php b/src/Annotation/ActionLinkType.php index 418fbe1..ad9d087 100644 --- a/src/Annotation/ActionLinkType.php +++ b/src/Annotation/ActionLinkType.php @@ -1,9 +1,7 @@ flag($flag_id, $entity_id); @@ -32,9 +36,16 @@ public function flag($flag_id, $entity_id) { } /** + * Performs an unflagging when called via a route. + * + * This method is invoked when a user clicks an AJAX unflagging link provided + * by the AJAXactionLink plugin. + * * @param $flag_id * @param $entity_id * @return AjaxResponse + * + * @see \Drupal\flag\Plugin\ActionLink\AJAXactionLink */ public function unflag($flag_id, $entity_id) { $flagService = \Drupal::service('flag'); diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index a821f57..fc38ffc 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -1,9 +1,7 @@ flagService->flag($flag_id, $entity_id); @@ -52,6 +66,15 @@ public function flag($flag_id, $entity_id) { return $this->redirect($url_info->getRouteName(), $url_info->getRouteParameters()); } + /** + * Performs a flagging when called via a route. + * + * @param $flag_id + * @param $entity_id + * @return \Symfony\Component\HttpFoundation\RedirectResponse + * + * @see \Drupal\flag\Plugin\Reload + */ public function unflag($flag_id, $entity_id) { $this->flagService->unflag($flag_id, $entity_id); diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 0d877f6..6a356ec 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -16,7 +16,7 @@ use Drupal\flag\FlagInterface; /** - * Class Flag + * Provides the Flag configuration entity. * @package Drupal\flag\Entity * * @ConfigEntityType( @@ -45,8 +45,6 @@ */ class Flag extends ConfigEntityBase implements FlagInterface { - //@todo Add AccessController, ListController, and form controllers. See \Drupal\contact\Entity\Category - /** * The flag ID. * From d2657b01518e38ab3ea63cfbcb0db1dc7cfe0e12 Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Sat, 19 Jul 2014 18:26:04 +0100 Subject: [PATCH 494/629] applied coding standard changes ONLY to comments in ActionLink --- src/Plugin/ActionLink/AJAXactionLink.php | 10 ++++++++++ src/Plugin/ActionLink/ConfirmForm.php | 18 ++++++++++++++---- src/Plugin/ActionLink/Reload.php | 8 +++----- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/Plugin/ActionLink/AJAXactionLink.php b/src/Plugin/ActionLink/AJAXactionLink.php index 933b0c0..0197ab8 100644 --- a/src/Plugin/ActionLink/AJAXactionLink.php +++ b/src/Plugin/ActionLink/AJAXactionLink.php @@ -1,4 +1,8 @@ configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; diff --git a/src/Plugin/ActionLink/Reload.php b/src/Plugin/ActionLink/Reload.php index 69d0de1..3f6fd1a 100644 --- a/src/Plugin/ActionLink/Reload.php +++ b/src/Plugin/ActionLink/Reload.php @@ -1,9 +1,7 @@ Date: Sat, 19 Jul 2014 12:53:51 -0500 Subject: [PATCH 495/629] Updated docblocks for Flag and FlagInterface. --- src/Entity/Flag.php | 58 +++++++++++++++++++++++++++++++++++++------ src/FlagInterface.php | 57 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 103 insertions(+), 12 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 6a356ec..4bce17d 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -146,25 +146,45 @@ class Flag extends ConfigEntityBase implements FlagInterface { public $unflag_denied_text = ''; /** - * The plugin ID of the flag type. + * The ID of the FlagType plugin. * * @var string */ protected $flag_type; + /** + * A bag to store the FlagType plugin. + * + * @var \Drupal\Core\Plugin\DefaultSinglePluginBag + */ protected $flagTypeBag; + /** + * An array to store and load the FlagType plugin configuration. + * @var array + */ protected $flagTypeConfig = array(); /** - * The link type used by the flag, as defined in hook_flag_link_type_info(). + * The ID of the ActionLink plugin. * * @var string + * @see \Drupal\flag\ActionLinkTypeBase */ protected $link_type; + /** + * A bag to store the ActionLink plugin. + * + * @var \Drupal\Core\Plugin\DefaultSinglePluginBag + */ protected $linkTypeBag; + /** + * An array to store and load the ActionLink plugin configuration. + * + * @var array + */ protected $linkTypeConfig = array(); /** @@ -191,14 +211,23 @@ public function __construct(array $values, $entity_type) { } } + /** + * {@inheritdoc} + */ public function enable() { $this->enabled = TRUE; } + /** + * {@inheritdoc} + */ public function disable() { $this->enabled = FALSE; } + /** + * {@inheritdoc} + */ public function isFlagged(EntityInterface $entity, AccountInterface $account = NULL) { if($account == NULL) { $account = \Drupal::currentUser(); @@ -219,7 +248,7 @@ public function isFlagged(EntityInterface $entity, AccountInterface $account = N } /** - * + * {@inheritdoc} */ public function getPluginBags() { return array( @@ -283,10 +312,7 @@ public function setlinkTypePlugin($pluginID) { } /** - * Provides permissions for this flag. - * - * @return - * An array of permissions for hook_permission(). + * {@inheritdoc} */ function getPermissions() { return array( @@ -317,10 +343,16 @@ public function hasActionAccess($action, AccountInterface $account = NULL) { } } + /** + * {@inheritdoc} + */ public function isGlobal() { return $this->is_global; } + /** + * {@inheritdoc} + */ public function setGlobal($isGlobal = TRUE) { if ($isGlobal) { $this->is_global = TRUE; @@ -330,6 +362,11 @@ public function setGlobal($isGlobal = TRUE) { } } + /** + * Returns the flaggable entity type ID. + * + * @return string + */ public function getFlaggableEntityType() { return $this->entity_type; } @@ -357,6 +394,9 @@ public function preSave(EntityStorageInterface $storage) { } + /** + * {@inheritdoc} + */ public static function preDelete(EntityStorageInterface $storage, array $entities) { parent::preDelete($storage, $entities); @@ -366,7 +406,11 @@ public static function preDelete(EntityStorageInterface $storage, array $entitie } } + /** + * {@inheritdoc} + */ public function toArray() { + //@todo Do we need Flag::toArray() any longer? $properties = parent::toArray(); $names = array( 'flag_type', diff --git a/src/FlagInterface.php b/src/FlagInterface.php index a40a2ff..13b1040 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -1,9 +1,7 @@ Date: Sat, 19 Jul 2014 13:25:13 -0500 Subject: [PATCH 496/629] Updated the docblocks for the Flagging and FlaggingInterface --- src/Entity/Flag.php | 2 +- src/Entity/Flagging.php | 34 +++++++++++++++++++++++++++++----- src/FlaggingInterface.php | 16 ++++++++++++---- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 4bce17d..56fab92 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -364,7 +364,7 @@ public function setGlobal($isGlobal = TRUE) { /** * Returns the flaggable entity type ID. - * + * * @return string */ public function getFlaggableEntityType() { diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index fa6c70b..a6bb6db 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -1,9 +1,7 @@ get('fid')->value; } + /** + * Gets the parent flag entity. + * + * @return \Drupal\Core\Entity\EntityInterface|\Drupal\flag\FlagInterface + */ public function getFlag() { return entity_load('flag', $this->getFlagId()); } + /** + * Gets the entity type of the flaggable. + * @return string + */ public function getFlaggableType() { return $this->get('entity_type')->value; } + /** + * Gets the entity ID of the flaggable. + * @return string + */ public function getFlaggableId() { return $this->get('entity_id')->value; } + /** + * Gets the flaggable entity. + * @return \Drupal\Core\Entity\EntityInterface + */ public function getFlaggable() { return entity_load($this->getFlaggableType(), $this->getFlaggableId()); } + /** + * {@inheritdoc} + */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['id'] = FieldDefinition::create('integer') ->setLabel(t('Flagging ID')) diff --git a/src/FlaggingInterface.php b/src/FlaggingInterface.php index baf330e..9206b86 100644 --- a/src/FlaggingInterface.php +++ b/src/FlaggingInterface.php @@ -1,17 +1,25 @@ Date: Sat, 19 Jul 2014 13:31:15 -0500 Subject: [PATCH 497/629] Updated the docblocks for flag events. --- src/Event/FlagEvents.php | 9 +++++++++ src/Event/FlaggingEvent.php | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Event/FlagEvents.php b/src/Event/FlagEvents.php index 12a5d86..701fdbe 100644 --- a/src/Event/FlagEvents.php +++ b/src/Event/FlagEvents.php @@ -11,9 +11,18 @@ */ final class FlagEvents { + /** + * Event ID for when an entity is flagged. + */ const ENTITY_FLAGGED = 'flag.entity_flagged'; + /** + * Event ID for when a previously flagged entity is unflagged. + */ const ENTITY_UNFLAGGED = 'flag.entity_unflagged'; + /** + * Event ID for when a flag (not a flagging) is deleted. + */ const FLAG_DELETED = 'flag.flag_deleted'; } diff --git a/src/Event/FlaggingEvent.php b/src/Event/FlaggingEvent.php index 155b06b..e187d1d 100644 --- a/src/Event/FlaggingEvent.php +++ b/src/Event/FlaggingEvent.php @@ -18,7 +18,7 @@ class FlaggingEvent extends FlagEventBase { /** * The Flag in question. * - * @var Drupal\Core\Entity\EntityInterface + * @var \Drupal\Core\Entity\EntityInterface */ protected $entity; From 9f32d2b719280ed36a62963b84e252c77a67b7da Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 19 Jul 2014 15:07:29 -0500 Subject: [PATCH 498/629] Updated the docblocks for form classes. --- src/Form/FlagAddForm.php | 28 ++++++++++++----------- src/Form/FlagAddPageForm.php | 38 +++++++++++++++++++++++--------- src/Form/FlagDeleteForm.php | 28 +++++++++++++++++++---- src/Form/FlagEditForm.php | 18 +++++++++++---- src/Form/FlagFormBase.php | 19 +++++++++++----- src/Form/FlaggingConfirmForm.php | 38 ++++++++++++++++++++++++++++---- 6 files changed, 128 insertions(+), 41 deletions(-) diff --git a/src/Form/FlagAddForm.php b/src/Form/FlagAddForm.php index 78de632..bbae549 100644 --- a/src/Form/FlagAddForm.php +++ b/src/Form/FlagAddForm.php @@ -1,9 +1,7 @@ getDefinitions(); @@ -86,6 +96,9 @@ public function buildForm(array $form, array &$form_state) { return $form; } + /** + * {@inheritdoc} + */ public function validateForm(array &$form, array &$form_state) { /* $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); @@ -95,6 +108,9 @@ public function validateForm(array &$form, array &$form_state) { */ } + /** + * {@inheritdoc} + */ public function submitForm(array &$form, array &$form_state) { $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['flag_entity_type']; diff --git a/src/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php index 87855e4..9929201 100644 --- a/src/Form/FlagDeleteForm.php +++ b/src/Form/FlagDeleteForm.php @@ -1,9 +1,7 @@ $this->entity->label() )); } + /** + * {@inheritdoc} + */ public function getConfirmText() { return t('Delete'); } + /** + * {@inheritdoc} + */ public function getCancelRoute() { return new URL('flag.list'); } + /** + * {@inheritdoc} + */ public function submit(array $form, array &$form_state) { $this->entity->delete(); drupal_set_message(t('Flag %label was deleted.', array( diff --git a/src/Form/FlagEditForm.php b/src/Form/FlagEditForm.php index 3831ccd..b621b60 100644 --- a/src/Form/FlagEditForm.php +++ b/src/Form/FlagEditForm.php @@ -1,17 +1,27 @@ flag->getLinkTypePlugin(); @@ -43,6 +61,9 @@ public function getQuestion() { return $linkType->getFlagQuestion(); } + /** + * {@inheritdoc} + */ public function getCancelRoute() { $destination = \Drupal::request()->get('destination'); if (!empty($destination)) { @@ -54,6 +75,9 @@ public function getCancelRoute() { return new URL($route_name['canonical']); } + /** + * {@inheritdoc} + */ public function getDescription() { if ($this->isFlagged()) { return $this->flag->unflag_long; @@ -62,6 +86,9 @@ public function getDescription() { return $this->flag->flag_long; } + /** + * {@inheritdoc} + */ public function getConfirmText() { if ($this->isFlagged()) { return $this->t('Unflag'); @@ -74,6 +101,9 @@ protected function isFlagged() { return $this->flag->isFlagged($this->entity); } + /** + * {@inheritdoc} + */ public function submitForm(array &$form, array &$form_state) { if ($this->isFlagged()) { \Drupal::service('flag')->unflagByObject($this->flag, $this->entity); From 56f75637a91df265e979db7324b1cd17ea1964dc Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Sat, 19 Jul 2014 21:29:05 +0100 Subject: [PATCH 499/629] applied coding standard fixes to comments in Flag directory --- src/Plugin/Flag/CommentFlagType.php | 23 ++++++++++++++++++----- src/Plugin/Flag/EntityFlagType.php | 24 +++++++++++++++++++----- src/Plugin/Flag/NodeFlagType.php | 19 ++++++++++++++----- src/Plugin/Flag/UserFlagType.php | 20 +++++++++++++++----- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index a223a67..94db11a 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -1,9 +1,7 @@ 'radios', '#title' => t('Flag access by content authorship'), @@ -56,11 +60,17 @@ public function buildConfigurationForm(array $form, array &$form_state) { return $form; } + /** + * {@inheritdoc} + */ public function submitConfigurationForm(array &$form, array &$form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['access_author'] = $form_state['values']['access_author']; } + /** + * {@inheritdoc} + */ public function type_access_multiple($entity_ids, $account) { $access = array(); @@ -85,6 +95,9 @@ public function type_access_multiple($entity_ids, $account) { return $access; } + /** + * {@inheritdoc} + */ function getAccessAuthorSetting() { return $this->configuration['access_author']; } diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 1f085f8..30e791f 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -1,9 +1,7 @@ entity_type = $plugin_definition['entity_type']; parent::__construct($configuration, $plugin_id, $plugin_definition); } + /** + * {@inheritdoc} + */ public function defaultConfiguration() { $options = parent::defaultConfiguration(); $options += array( @@ -50,10 +59,12 @@ public function defaultConfiguration() { } /** - * Options form extras for the generic entity flag. + * {@inheritdoc} */ public function buildConfigurationForm(array $form, array &$form_state) { + /* Options form extras for the generic entity flag. */ + // Add checkboxes to show flag link on each entity view mode. $options = array(); $defaults = array(); @@ -109,6 +120,9 @@ public function buildConfigurationForm(array $form, array &$form_state) { return $form; } + /** + * {@inheritdoc} + */ public function submitConfigurationForm(array &$form, array &$form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['show_in_links'] = $form_state['values']['show_in_links']; diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index 5430fd1..b6d6536 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -1,9 +1,7 @@ 'radios', '#title' => t('Flag access by content authorship'), @@ -70,12 +73,18 @@ public function buildConfigurationForm(array $form, array &$form_state) { return $form; } + /** + * {@inheritdoc} + */ public function submitConfigurationForm(array &$form, array &$form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['access_author'] = $form_state['values']['access_author']; $this->configuration['i18n'] = $form_state['values']['i18n']; } + /** + * {@inheritdoc} + */ function type_access_multiple($entity_ids, $account) { $access = array(); diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 6e05c13..0fe4a23 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -1,9 +1,7 @@ configuration['access_uid'] = $form_state['values']['access']['access_uid']; $this->configuration['show_on_profile'] = $form_state['values']['display']['show_on_profile']; } + /** + * {@inheritdoc} + */ function type_access_multiple($entity_ids, $account) { $access = array(); From 32e25522284fa2f4069700747893f0014b7b8023 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 19 Jul 2014 15:44:57 -0500 Subject: [PATCH 500/629] Updated docblocks for link types. --- src/ActionLinkTypeBase.php | 27 ++++++++----------- src/ActionLinkTypePluginInterface.php | 33 +++++++++++++++++------- src/Plugin/ActionLink/AJAXactionLink.php | 15 ++++++++++- src/Plugin/ActionLink/ConfirmForm.php | 29 +++++++++++++++++---- src/Plugin/ActionLink/Reload.php | 10 +++---- 5 files changed, 76 insertions(+), 38 deletions(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index a1b1bc2..aaf9f9d 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -1,9 +1,7 @@ configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; } + /** + * Returns the flag confirm form question when flagging. + * @return string + */ public function getFlagQuestion() { return $this->configuration['flag_confirmation']; } + /** + * Returns the flag confirm form question when unflagging. + * @return string + */ public function getUnflagQuestion() { return $this->configuration['unflag_confirmation']; } diff --git a/src/Plugin/ActionLink/Reload.php b/src/Plugin/ActionLink/Reload.php index 69d0de1..6e1fecd 100644 --- a/src/Plugin/ActionLink/Reload.php +++ b/src/Plugin/ActionLink/Reload.php @@ -1,9 +1,7 @@ Date: Sat, 19 Jul 2014 22:57:50 -0500 Subject: [PATCH 501/629] Fixed several code style problems. --- flag.api.php | 2 +- flag.tokens.inc | 6 ++++++ flag.views.inc | 2 +- src/ActionLinkPluginManager.php | 2 +- src/BrokenFlagType.php | 2 +- src/Controller/FlagListController.php | 2 -- src/Controller/ReloadLinkController.php | 6 ++---- src/Entity/Flag.php | 8 ++++---- src/Event/FlagEvents.php | 1 - src/FlagService.php | 6 +++--- src/Form/FlagAddPageForm.php | 4 ++-- src/Form/FlagFormBase.php | 6 +++--- src/Plugin/Flag/CommentFlagType.php | 2 +- src/Plugin/Flag/EntityFlagType.php | 11 +++++++---- src/Plugin/Flag/NodeFlagType.php | 8 ++++---- src/Plugin/Flag/UserFlagType.php | 2 +- src/Plugin/views/field/FlagViewsLinkField.php | 3 ++- .../views/relationship/FlagViewsRelationship.php | 2 +- src/Plugin/views/sort/FlagViewsSortFlagged.php | 4 ++-- 19 files changed, 42 insertions(+), 37 deletions(-) diff --git a/flag.api.php b/flag.api.php index 4821198..d8b3b83 100644 --- a/flag.api.php +++ b/flag.api.php @@ -80,7 +80,7 @@ function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permissi $count = count($flags[$flag->name]); if ($count >= 2) { // Users may flag only 2 nodes with this flag. - return(array('access-denied' => t('You may only flag 2 nodes with the test flag.'))); + return (array('access-denied' => t('You may only flag 2 nodes with the test flag.'))); } } } diff --git a/flag.tokens.inc b/flag.tokens.inc index 138c572..8c962c7 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -110,6 +110,7 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr case 'name': $replacements[$original] = $sanitize ? check_plain($flag->name) : $flag->name; break; + case 'title': $replacements[$original] = $sanitize ? check_plain($flag->get_title()) : $flag->get_title(); break; @@ -136,18 +137,23 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr case 'action': $replacements[$original] = $action->action; break; + case 'entity-url': $replacements[$original] = $sanitize ? check_url($action->entity_url) : $action->entity_url; break; + case 'entity-title': $replacements[$original] = $sanitize ? check_plain($action->entity_title) : $action->entity_title; break; + case 'entity-type': $replacements[$original] = $action->entity_type; break; + case 'entity-id': $replacements[$original] = $action->entity_id; break; + case 'count': $replacements[$original] = $action->count; break; diff --git a/flag.views.inc b/flag.views.inc index e1adf4f..27fd743 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -100,7 +100,7 @@ function flag_views_data() { 'help' => t('The number of times a piece of content is flagged by any user.'), 'field' => array( 'id' => 'numeric', -// 'click sortable' => TRUE, + // 'click sortable' => TRUE, ), /*'sort' => array( 'id' => 'groupby_numeric', diff --git a/src/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php index 7e6bbec..7a01151 100644 --- a/src/ActionLinkPluginManager.php +++ b/src/ActionLinkPluginManager.php @@ -28,7 +28,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac public function getAllLinkTypes() { $linkTypes = array(); - foreach($this->getDefinitions() as $pluginID => $pluginDef) { + foreach ($this->getDefinitions() as $pluginID => $pluginDef) { $linkTypes[$pluginID] = t($pluginDef['label']); } diff --git a/src/BrokenFlagType.php b/src/BrokenFlagType.php index fa991bf..0dd98c7 100644 --- a/src/BrokenFlagType.php +++ b/src/BrokenFlagType.php @@ -18,7 +18,7 @@ */ class BrokenFlagType extends FlagTypeBase { - function options_form(&$form) { + public function options_form(&$form) { drupal_set_message(t("The module providing this flag wasn't found, or this flag type, %type, isn't valid.", array('%type' => $this->entity_type)), 'error'); $form = array(); } diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index fc38ffc..f2b532d 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -21,7 +21,6 @@ class FlagListController extends ConfigEntityListBuilder { * Overrides Drupal\Core\Entity\EntityListController::buildHeader(). */ public function buildHeader() { -// $header['id'] = t('Flag'); $header['label'] = t('Flag'); $header['roles'] = t('Roles'); $header['is_global'] = t('Global?'); @@ -110,7 +109,6 @@ public function render() { $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', array('@handbook-url' => 'http://drupal.org/handbook/modules/flag')) . '

'; - $build['markup'] = array( '#type' => 'markup', '#markup' => $output, diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 7d45ddb..255c797 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -29,8 +29,7 @@ class ReloadLinkController extends ControllerBase implements ContainerInjectionI * * @param FlagService $flag */ - public function __construct(FlagService $flag) - { + public function __construct(FlagService $flag) { $this->flagService = $flag; } @@ -40,8 +39,7 @@ public function __construct(FlagService $flag) * @param ContainerInterface $container * @return static */ - public static function create(ContainerInterface $container) - { + public static function create(ContainerInterface $container) { return new static( $container->get('flag') ); diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 56fab92..4181f13 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -229,7 +229,7 @@ public function disable() { * {@inheritdoc} */ public function isFlagged(EntityInterface $entity, AccountInterface $account = NULL) { - if($account == NULL) { + if ($account == NULL) { $account = \Drupal::currentUser(); } @@ -314,7 +314,7 @@ public function setlinkTypePlugin($pluginID) { /** * {@inheritdoc} */ - function getPermissions() { + public function getPermissions() { return array( "flag $this->id" => array( 'title' => t('Flag %flag_title', array( @@ -376,7 +376,7 @@ public function getFlaggableEntityType() { */ public function preSave(EntityStorageInterface $storage) { parent::preSave($storage); -/* + /* // Save the Flag Type configuration. $flagTypePlugin = $this->getFlagTypePlugin(); $this->set('flagTypeConfig', $flagTypePlugin->getConfiguration()); @@ -384,7 +384,7 @@ public function preSave(EntityStorageInterface $storage) { // Save the Link Type configuration. $linkTypePlugin = $this->getLinkTypePlugin(); $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); -*/ + */ // Reset the render cache for the entity. \Drupal::entityManager() ->getViewBuilder($this->getFlaggableEntityType()) diff --git a/src/Event/FlagEvents.php b/src/Event/FlagEvents.php index 701fdbe..a52fba6 100644 --- a/src/Event/FlagEvents.php +++ b/src/Event/FlagEvents.php @@ -7,7 +7,6 @@ /** * Contains all events thrown in the Flag module. - * */ final class FlagEvents { diff --git a/src/FlagService.php b/src/FlagService.php index 52ce0ac..a4dbd45 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -88,7 +88,7 @@ public function __construct( public function fetchDefinition($entity_type = NULL) { //@todo Add caching, PLS! - if(!empty($entity_type)){ + if (!empty($entity_type)) { return $this->flagTypeMgr->getDefinition($entity_type); } @@ -115,7 +115,7 @@ public function fetchDefinition($entity_type = NULL) { public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $account = NULL) { $query = $this->entityQueryMgr->get('flag'); - if($entity_type != NULL) { + if ($entity_type != NULL) { $query->condition('entity_type', $entity_type); } @@ -142,7 +142,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ } public function getFlaggings(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { - if($account == NULL) { + if ($account == NULL) { $account = $this->currentUser; } diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index 82e7c24..cb0a573 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -22,8 +22,8 @@ class FlagAddPageForm extends FormBase { /** - * {@inheritdoc} - */ + * {@inheritdoc} + */ public function getFormID() { return 'flag_add_page'; } diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 1c1d200..289fee7 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -162,7 +162,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#tree' => FALSE, '#weight' => 20, // @todo: Move flag_link_type_options_states() into controller? -// '#after_build' => array('flag_link_type_options_states'), + // '#after_build' => array('flag_link_type_options_states'), ); $form['display']['settings'] = array( @@ -178,7 +178,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) '#type' => 'radios', '#title' => t('Link type'), '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), -// '#after_build' => array('flag_check_link_types'), + // '#after_build' => array('flag_check_link_types'), '#default_value' => $flag->getLinkTypePlugin()->getPluginId(), // Give this a high weight so additions by the flag classes for entity- // specific options go above. @@ -290,7 +290,7 @@ public function save(array $form, array &$form_state) { } // We clear caches more vigorously if the flag was new. -// _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); + // _flag_clear_cache($flag->entity_type, !empty($flag->is_new)); // Save permissions. // This needs to be done after the flag cache has been cleared, so that diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index a223a67..156300d 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -85,7 +85,7 @@ public function type_access_multiple($entity_ids, $account) { return $access; } - function getAccessAuthorSetting() { + public function getAccessAuthorSetting() { return $this->configuration['access_author']; } } \ No newline at end of file diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 1f085f8..742e182 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -77,11 +77,12 @@ public function buildConfigurationForm(array $form, array &$form_state) { '#description' => t('Show the flag link as a pseudofield, which can be ordered among other entity elements in the "Manage display" settings for the entity type.'), '#default_value' => isset($this->show_as_field) ? $this->show_as_field : TRUE, ); - /* if (empty($entity_info['fieldable'])) { + /* + if (empty($entity_info['fieldable'])) { $form['display']['show_as_field']['#disabled'] = TRUE; $form['display']['show_as_field']['#description'] = t("This entity type is not fieldable."); } -*/ + */ $form['display']['show_on_form'] = array( '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), @@ -93,11 +94,13 @@ public function buildConfigurationForm(array $form, array &$form_state) { // require the entity to be fielable. Since this is a potential DX // headscratcher for a developer wondering where this option has gone, // we disable it and explain why. - /* if (empty($entity_info['fieldable'])) { + /* + if (empty($entity_info['fieldable'])) { $form['display']['show_on_form']['#disabled'] = TRUE; $form['display']['show_on_form']['#description'] = t('This is only possible on entities which are fieldable.'); } -*/ $form['display']['show_contextual_link'] = array( + */ + $form['display']['show_contextual_link'] = array( '#type' => 'checkbox', '#title' => t('Display in contextual links'), '#default_value' => $this->showContextualLink(), diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index 5430fd1..a55c192 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -76,7 +76,7 @@ public function submitConfigurationForm(array &$form, array &$form_state) { $this->configuration['i18n'] = $form_state['values']['i18n']; } - function type_access_multiple($entity_ids, $account) { + public function type_access_multiple($entity_ids, $account) { $access = array(); // If all subtypes are allowed, we have nothing to say here. @@ -97,11 +97,11 @@ function type_access_multiple($entity_ids, $account) { return $access; } - function getAccessAuthorSetting() { + public function getAccessAuthorSetting() { return $this->configuration['access_author']; } - function getInternationalizationSetting() { + public function getInternationalizationSetting() { $this->configuration['i18n']; } -} \ No newline at end of file +} diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 6e05c13..dd1d51b 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -67,7 +67,7 @@ public function submitConfigurationForm(array &$form, array &$form_state) { $this->configuration['show_on_profile'] = $form_state['values']['display']['show_on_profile']; } - function type_access_multiple($entity_ids, $account) { + public function type_access_multiple($entity_ids, $account) { $access = array(); // Exclude anonymous. diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index f261038..8ddb8cf 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -79,7 +79,8 @@ public function render(ResultRow $values) { * @param ResultRow $values */ protected function renderLink($entity, ResultRow $values) { - if (empty($entity)) { // || !$entity->access('view')) { + // if (empty($entity) || !$entity->access('view')) { + if (empty($entity)) { return t('N/A'); } diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index b8349f5..d811473 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -102,7 +102,7 @@ public function query() { } } -// parent::query(); + // parent::query(); } diff --git a/src/Plugin/views/sort/FlagViewsSortFlagged.php b/src/Plugin/views/sort/FlagViewsSortFlagged.php index 5253a28..76dad93 100644 --- a/src/Plugin/views/sort/FlagViewsSortFlagged.php +++ b/src/Plugin/views/sort/FlagViewsSortFlagged.php @@ -21,7 +21,7 @@ class FlagViewsSortFlagged extends SortPluginBase { * * Should be overridden by classes that don't override sort_form. */ - function sortOptions() { + protected function sortOptions() { return array( 'ASC' => t('Unflagged first'), 'DESC' => t('Flagged first'), @@ -31,7 +31,7 @@ function sortOptions() { /** * Display whether or not the sort order is ascending or descending */ - function adminSummary() { + public function adminSummary() { if (!empty($this->options['exposed'])) { return t('Exposed'); } From 00a9edec43298ba612215616690346dc8980430b Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 19 Jul 2014 23:14:59 -0500 Subject: [PATCH 502/629] Fixed additional code style problems in FlagEvents, FlagAddPageForm, css and JS files. --- src/Event/FlagEvents.php | 1 + src/Form/FlagAddPageForm.php | 2 +- theme/flag-admin.css | 1 - theme/flag-admin.js | 4 ++++ theme/flag.css | 3 +-- theme/flag.js | 4 ++++ 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Event/FlagEvents.php b/src/Event/FlagEvents.php index a52fba6..10981e5 100644 --- a/src/Event/FlagEvents.php +++ b/src/Event/FlagEvents.php @@ -3,6 +3,7 @@ * @file * Contains \Drupal\flag\Event\FlagEvents. */ + namespace Drupal\flag\Event; /** diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index cb0a573..fcd8cb6 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -25,7 +25,7 @@ class FlagAddPageForm extends FormBase { * {@inheritdoc} */ public function getFormID() { - return 'flag_add_page'; + return 'flag_add_page'; } /** diff --git a/theme/flag-admin.css b/theme/flag-admin.css index 2c6ac56..f7f1567 100644 --- a/theme/flag-admin.css +++ b/theme/flag-admin.css @@ -1,4 +1,3 @@ - table.flag-admin-table { width: auto; margin: 0; diff --git a/theme/flag-admin.js b/theme/flag-admin.js index 5e028ea..f8b0028 100644 --- a/theme/flag-admin.js +++ b/theme/flag-admin.js @@ -1,3 +1,7 @@ +/** + * @file + * Contains flag admin javascript. + */ (function ($) { /** diff --git a/theme/flag.css b/theme/flag.css index f43eb1b..7f666eb 100644 --- a/theme/flag.css +++ b/theme/flag.css @@ -1,4 +1,3 @@ - .flag-message { position: absolute; top: 1.7em; @@ -10,7 +9,7 @@ } .flag-message.flag-failure-message { - border: 1px solid ; + border: 1px solid; border-color: #ed5; color: #840; background-color: #fffce5; diff --git a/theme/flag.js b/theme/flag.js index 3f1aedc..908d3ff 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -1,3 +1,7 @@ +/** + * @file + * Contains Flag module javascript. + */ (function ($) { /** From 4ba7c1c4b45dc675c043478050848d3e1ae4c324 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 19 Jul 2014 23:21:59 -0500 Subject: [PATCH 503/629] Fixed even more JS code style problems. --- theme/flag-admin.js | 1 + theme/flag.js | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/theme/flag-admin.js b/theme/flag-admin.js index f8b0028..dcbc926 100644 --- a/theme/flag-admin.js +++ b/theme/flag-admin.js @@ -2,6 +2,7 @@ * @file * Contains flag admin javascript. */ + (function ($) { /** diff --git a/theme/flag.js b/theme/flag.js index 908d3ff..e60f2a4 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -2,6 +2,7 @@ * @file * Contains Flag module javascript. */ + (function ($) { /** @@ -79,7 +80,8 @@ Drupal.flagLink = function(context) { success: function (data) { data.link = $wrapper.get(0); $.event.trigger('flagGlobalBeforeLinkUpdate', [data]); - if (!data.preventDefault) { // A handler may cancel updating the link. + if (!data.preventDefault) { + // A handler may cancel updating the link. data.link = updateLink(element, data.newLink); } @@ -174,11 +176,13 @@ Drupal.flagAnonymousLinkTemplates = function(context) { * Written by Klaus Hartl. */ Drupal.flagCookie = function(name, value, options) { - if (typeof value != 'undefined') { // name and value given, set cookie + if (typeof value != 'undefined') { + // name and value given, set cookie options = options || {}; if (value === null) { value = ''; - options = $.extend({}, options); // clone object since it's unexpected behavior if the expired property were changed + // clone object since it's unexpected behavior if the expired property were changed + options = $.extend({}, options); options.expires = -1; } var expires = ''; @@ -190,7 +194,9 @@ Drupal.flagCookie = function(name, value, options) { } else { date = options.expires; } - expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE + + // use expires attribute, max-age is not supported by IE + expires = '; expires=' + date.toUTCString(); } // NOTE Needed to parenthesize options.path and options.domain // in the following expressions, otherwise they evaluate to undefined From 53d38e625c81f06301296bbe4a46204fcda03ddd Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 19 Jul 2014 23:27:58 -0500 Subject: [PATCH 504/629] Fixed a code style problem in flag.js. --- theme/flag.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/theme/flag.js b/theme/flag.js index e60f2a4..19b871d 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -205,7 +205,8 @@ Drupal.flagCookie = function(name, value, options) { var domain = options.domain ? '; domain=' + (options.domain) : ''; var secure = options.secure ? '; secure' : ''; document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); - } else { // only name given, get cookie + } else { + // only name given, get cookie var cookieValue = null; if (document.cookie && document.cookie != '') { var cookies = document.cookie.split(';'); From 7a73f41181cf45b42b6ab1a3a1e8016649c987c2 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 20 Jul 2014 11:20:13 -0500 Subject: [PATCH 505/629] Updated EntityFlagType due to https://www.drupal.org/node/2257811 --- src/Plugin/Derivative/EntityFlagType.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugin/Derivative/EntityFlagType.php b/src/Plugin/Derivative/EntityFlagType.php index bb675e9..4472d5f 100644 --- a/src/Plugin/Derivative/EntityFlagType.php +++ b/src/Plugin/Derivative/EntityFlagType.php @@ -6,12 +6,12 @@ namespace Drupal\flag\Plugin\Derivative; -use Drupal\Component\Plugin\Derivative\DerivativeBase; +use Drupal\Component\Plugin\Derivative\DeriverBase; /** * Derivative class for entity flag types plugin. */ -class EntityFlagType extends DerivativeBase { +class EntityFlagType extends DeriverBase { /* public function __construct($base_plugin_id, EntityStorageControllerInterface $storageController) { From c74b2c22e98a453a2edb237d62839cc909033a15 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 23 Jul 2014 17:12:29 -0500 Subject: [PATCH 506/629] Replaced 'Created by PHPStorm' file docblocks with proper ones. --- flag.views.inc | 6 ++---- src/BrokenFlagType.php | 6 ++---- src/FlagService.php | 6 ++---- src/FlagTypeBase.php | 6 ++---- src/FlagTypePluginInterface.php | 6 ++---- src/FlagTypePluginManager.php | 6 ++---- src/Plugin/views/field/FlagViewsFlaggedField.php | 6 ++---- src/Plugin/views/field/FlagViewsLinkField.php | 6 ++---- src/Plugin/views/filter/FlagViewsFilter.php | 1 + src/Plugin/views/relationship/FlagViewsRelationship.php | 6 ++---- 10 files changed, 19 insertions(+), 36 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 27fd743..b1e99b3 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -1,9 +1,7 @@ Date: Wed, 23 Jul 2014 17:20:39 -0500 Subject: [PATCH 507/629] Fixed documentation for ActionLinkPluginManager. --- src/ActionLinkPluginManager.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php index 7a01151..ad28530 100644 --- a/src/ActionLinkPluginManager.php +++ b/src/ActionLinkPluginManager.php @@ -13,7 +13,10 @@ use Drupal\Core\Plugin\DefaultPluginManager; /** - * Manages image effect plugins. + * Plugin manager for link types. + * @package Drupal\flag + * + * @see Drupal\flag\ActionLinkTypeBase */ class ActionLinkPluginManager extends DefaultPluginManager { @@ -26,6 +29,10 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac $this->setCacheBackend($cache_backend, 'flag_link_type_plugins'); } + /** + * Get an array of all link type labels keyed by plugin ID. + * @return array + */ public function getAllLinkTypes() { $linkTypes = array(); foreach ($this->getDefinitions() as $pluginID => $pluginDef) { From 8a74871f9916e34644fb1253ee5e71d119610571 Mon Sep 17 00:00:00 2001 From: Andy Postnikov Date: Mon, 28 Jul 2014 14:35:03 +0300 Subject: [PATCH 508/629] Rename getCancelRoute to getCancelUrl --- src/Form/FlagDeleteForm.php | 10 +++++----- src/Form/FlaggingConfirmForm.php | 17 ++++++----------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php index 9929201..c9a39f1 100644 --- a/src/Form/FlagDeleteForm.php +++ b/src/Form/FlagDeleteForm.php @@ -1,7 +1,7 @@ $this->entity->label(), ))); - $form_state['redirect_route']['route_name'] = 'flag.list'; + $form_state['redirect_route'] = $this->getCancelUrl(); } -} \ No newline at end of file +} diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index e0fc0ad..01038dc 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -1,16 +1,13 @@ get('destination'); if (!empty($destination)) { - return URL::createFromPath($destination); + return Url::createFromPath($destination); } - $route_name = $this->entity->urlInfo(); - - return new URL($route_name['canonical']); + return $this->entity->urlInfo(); } /** @@ -113,4 +108,4 @@ public function submitForm(array &$form, array &$form_state) { } } -} \ No newline at end of file +} From ac150435dd9764674320c592da4f45e0e06b123f Mon Sep 17 00:00:00 2001 From: David Valdez Date: Fri, 1 Aug 2014 02:29:46 -0500 Subject: [PATCH 509/629] $form_state is now a classed object --- src/ActionLinkTypeBase.php | 7 ++++--- src/FlagTypeBase.php | 9 +++++---- src/Form/FlagAddForm.php | 5 +++-- src/Form/FlagAddPageForm.php | 7 ++++--- src/Form/FlagDeleteForm.php | 3 ++- src/Form/FlagEditForm.php | 3 ++- src/Form/FlagFormBase.php | 11 ++++++----- src/Form/FlaggingConfirmForm.php | 5 +++-- src/Plugin/ActionLink/ConfirmForm.php | 5 +++-- src/Plugin/Flag/CommentFlagType.php | 5 +++-- src/Plugin/Flag/EntityFlagType.php | 5 +++-- src/Plugin/Flag/NodeFlagType.php | 5 +++-- src/Plugin/Flag/UserFlagType.php | 5 +++-- 13 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index aaf9f9d..aabaa38 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -13,6 +13,7 @@ use Drupal\flag\FlagInterface; use Drupal\flag\ActionLinkTypePluginInterface; use Drupal\flag\FlagService; +use Drupal\Core\Form\FormStateInterface; /** * Provides a base class for all link types. @@ -102,7 +103,7 @@ public function calculateDependencies() { * @return array * The configuration form array. */ - public function buildConfigurationForm(array $form, array &$form_state) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { return $form; } @@ -113,7 +114,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { * @param array $form * @param array $form_state */ - public function submitConfigurationForm(array &$form, array &$form_state) { + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. } @@ -124,7 +125,7 @@ public function submitConfigurationForm(array &$form, array &$form_state) { * @param array $form * @param array $form_state */ - public function validateConfigurationForm(array &$form, array &$form_state) { + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. } diff --git a/src/FlagTypeBase.php b/src/FlagTypeBase.php index 8c4d349..ead7632 100644 --- a/src/FlagTypeBase.php +++ b/src/FlagTypeBase.php @@ -9,6 +9,7 @@ use Drupal\flag\FlagTypePluginInterface; use Drupal\Component\Plugin\PluginBase; use Drupal\Core\Plugin\PluginFormInterface; +use Drupal\Core\Form\FormStateInterface; /** * Class FlagTypeBase @@ -65,12 +66,12 @@ public function setConfiguration(array $configuration) { * or editing the Flag. Derived classes should want to override this. * * @param array $form - * @param array $form_state + * @param FormStateInterface $form_state * @return array * The form array * @see \Drupal\flag\Form\FlagAddForm */ - public function buildConfigurationForm(array $form, array &$form_state) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { return $form; } @@ -82,7 +83,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { * @param array $form * @param array $form_state */ - public function submitConfigurationForm(array &$form, array &$form_state) { + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. } @@ -92,7 +93,7 @@ public function submitConfigurationForm(array &$form, array &$form_state) { * @param array $form * @param array $form_state */ - public function validateConfigurationForm(array &$form, array &$form_state) { + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. } diff --git a/src/Form/FlagAddForm.php b/src/Form/FlagAddForm.php index bbae549..c0e5e4b 100644 --- a/src/Form/FlagAddForm.php +++ b/src/Form/FlagAddForm.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Form; use Drupal\flag\Form\FlagFormBase; +use Drupal\Core\Form\FormStateInterface; /** * Provides the flag add form. @@ -23,7 +24,7 @@ class FlagAddForm extends FlagFormBase { /** * {@inheritdoc} */ - public function buildForm(array $form, array &$form_state, $entity_type = NULL) { + public function buildForm(array $form, FormStateInterface $form_state, $entity_type = NULL) { //@todo Check all non-form_* params with check_plain(). $tempstore = \Drupal::service('user.tempstore')->get('flag'); @@ -47,7 +48,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) /** * {@inheritdoc} */ - protected function actions(array $form, array &$form_state) { + protected function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); $actions['submit']['#value'] = t('Create Flag'); return $actions; diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index fcd8cb6..7fbdecc 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Form\FormBase; use Drupal\flag\Handlers\AbstractFlag; +use Drupal\Core\Form\FormStateInterface; /** * Provides the flag add page. @@ -31,7 +32,7 @@ public function getFormID() { /** * {@inheritdoc} */ - public function buildForm(array $form, array &$form_state) { + public function buildForm(array $form, FormStateInterface $form_state) { $form['flag_basic_info'] = array( '#type' => 'fieldset', @@ -99,7 +100,7 @@ public function buildForm(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function validateForm(array &$form, array &$form_state) { + public function validateForm(array &$form, FormStateInterface $form_state) { /* $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); if (get_class($flag) == 'BrokenFlag') { @@ -111,7 +112,7 @@ public function validateForm(array &$form, array &$form_state) { /** * {@inheritdoc} */ - public function submitForm(array &$form, array &$form_state) { + public function submitForm(array &$form, FormStateInterface $form_state) { $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . $form_state['values']['flag_entity_type']; diff --git a/src/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php index c9a39f1..38180c9 100644 --- a/src/Form/FlagDeleteForm.php +++ b/src/Form/FlagDeleteForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityConfirmFormBase; use Drupal\Core\Url; +use Drupal\Core\Form\FormStateInterface; /** * Provides the flag delete form. @@ -47,7 +48,7 @@ public function getCancelUrl() { /** * {@inheritdoc} */ - public function submit(array $form, array &$form_state) { + public function submit(array $form, FormStateInterface $form_state) { $this->entity->delete(); drupal_set_message(t('Flag %label was deleted.', array( '%label' => $this->entity->label(), diff --git a/src/Form/FlagEditForm.php b/src/Form/FlagEditForm.php index b621b60..cebfedb 100644 --- a/src/Form/FlagEditForm.php +++ b/src/Form/FlagEditForm.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Form; use Drupal\flag\Form\FlagFormBase; +use Drupal\Core\Form\FormStateInterface; /** * Provides the flag edit form. @@ -22,7 +23,7 @@ class FlagEditForm extends FlagFormBase { /** * {@inheritdoc} */ - protected function actions(array $form, array &$form_state) { + protected function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); $actions['submit']['#value'] = t('Save Flag'); return $actions; diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 289fee7..7360592 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityForm; use Drupal\flag\Handlers\AbstractFlag; +use Drupal\Core\Form\FormStateInterface; /** * Provides the base flag add/edit form. @@ -23,7 +24,7 @@ abstract class FlagFormBase extends EntityForm { /** * {@inheritdoc} */ - public function buildForm(array $form, array &$form_state, $entity_type = NULL) { + public function buildForm(array $form, FormStateInterface $form_state, $entity_type = NULL) { $form = parent::buildForm($form, $form_state); $flag = $this->entity; @@ -226,7 +227,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL) /** * Handles switching the configuration type selector. */ - public function updateSelectedPluginType($form, &$form_state) { + public function updateSelectedPluginType($form, $form_state) { return $form['display']['settings']; } @@ -245,7 +246,7 @@ public function submitSelectPlugin(array $form, array &$form_state) { /** * Overrides Drupal\Core\Entity\EntityFormController::validate(). */ - public function validate(array $form, array &$form_state) { + public function validate(array $form, FormStateInterface $form_state) { parent::validate($form, $form_state); $form_state['values']['label'] = trim($form_state['values']['label']); @@ -271,7 +272,7 @@ public function validate(array $form, array &$form_state) { /** * Overrides Drupal\Core\Entity\EntityFormController::save(). */ - public function save(array $form, array &$form_state) { + public function save(array $form, FormStateInterface $form_state) { $flag = $this->entity; $flag->getFlagTypePlugin()->submitConfigurationForm($form, $form_state); @@ -325,7 +326,7 @@ public function save(array $form, array &$form_state) { /** * Overrides Drupal\Core\Entity\EntityFormController::delete(). */ - public function delete(array $form, array &$form_state) { + public function delete(array $form, FormStateInterface $form_state) { $form_state['redirect'] = 'admin/structure/flags'; } diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index 01038dc..9a1eded 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Form\ConfirmFormBase; use Drupal\Core\Url; +use Drupal\Core\Form\FormStateInterface; /** * Provides the form page for the Confirm Form link type. @@ -29,7 +30,7 @@ class FlaggingConfirmForm extends ConfirmFormBase { /** * {@inheritdoc} */ - public function buildForm(array $form, array &$form_state, + public function buildForm(array $form, FormStateInterface $form_state, $flag_id = NULL, $entity_id = NULL) { $flagService = \Drupal::service('flag'); @@ -99,7 +100,7 @@ protected function isFlagged() { /** * {@inheritdoc} */ - public function submitForm(array &$form, array &$form_state) { + public function submitForm(array &$form, FormStateInterface $form_state) { if ($this->isFlagged()) { \Drupal::service('flag')->unflagByObject($this->flag, $this->entity); } diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index 655c5db..3bbc7ec 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\ActionLink; use Drupal\flag\ActionLinkTypeBase; +use Drupal\Core\Form\FormStateInterface; /** * Provides the Confirm Form link type. @@ -47,7 +48,7 @@ public function defaultConfiguration() { /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, array &$form_state) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); $form['display']['settings']['link_options_confirm'] = array( @@ -84,7 +85,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function submitConfigurationForm(array &$form, array &$form_state) { + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index 3a6ec00..0ee4f16 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\Flag; use Drupal\flag\Plugin\Flag\EntityFlagType; +use Drupal\Core\Form\FormStateInterface; /** * Class CommentFlagType @@ -37,7 +38,7 @@ public function defaultConfiguration() { /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, array &$form_state) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); @@ -63,7 +64,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function submitConfigurationForm(array &$form, array &$form_state) { + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['access_author'] = $form_state['values']['access_author']; } diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 7366f4d..0a68298 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\Flag; use Drupal\flag\FlagTypeBase; +use Drupal\Core\Form\FormStateInterface; /** * Class EntityFlagType @@ -61,7 +62,7 @@ public function defaultConfiguration() { /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, array &$form_state) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { /* Options form extras for the generic entity flag. */ @@ -126,7 +127,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function submitConfigurationForm(array &$form, array &$form_state) { + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['show_in_links'] = $form_state['values']['show_in_links']; $this->configuration['show_as_field'] = $form_state['values']['show_as_field']; diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index d030e49..f0e0ffc 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\Flag; use Drupal\flag\Plugin\Flag\EntityFlagType; +use Drupal\Core\Form\FormStateInterface; /** * Class NodeFlagType @@ -39,7 +40,7 @@ public function defaultConfiguration() { /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, array &$form_state) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); /* Options form extras for node flags. */ @@ -76,7 +77,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function submitConfigurationForm(array &$form, array &$form_state) { + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['access_author'] = $form_state['values']['access_author']; $this->configuration['i18n'] = $form_state['values']['i18n']; diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 62244ec..836d070 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\Flag; use Drupal\flag\FlagTypeBase; +use Drupal\Core\Form\FormStateInterface; /** * Class UserFlagType @@ -36,7 +37,7 @@ public function defaultConfiguration() { /** * {@inheritdoc} */ - public function buildConfigurationForm(array $form, array &$form_state) { + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); /* Options form extras for user flags */ @@ -68,7 +69,7 @@ public function buildConfigurationForm(array $form, array &$form_state) { /** * {@inheritdoc} */ - public function submitConfigurationForm(array &$form, array &$form_state) { + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['access_uid'] = $form_state['values']['access']['access_uid']; $this->configuration['show_on_profile'] = $form_state['values']['display']['show_on_profile']; From 458ac9cf4aaa30efa905fa30ae776ca0212fa7da Mon Sep 17 00:00:00 2001 From: David Valdez Date: Fri, 1 Aug 2014 11:27:09 -0500 Subject: [PATCH 510/629] adding the typehint in the rest of the functions with $form_state Also the .travis.yml file was updated for use the branch 8.0.x --- .travis.yml | 2 +- flag.module | 9 +++++---- src/Form/FlagFormBase.php | 4 ++-- src/Plugin/views/field/FlagViewsFlaggedField.php | 3 ++- src/Plugin/views/field/FlagViewsLinkField.php | 3 ++- src/Plugin/views/filter/FlagViewsFilter.php | 3 ++- src/Plugin/views/relationship/FlagViewsRelationship.php | 3 ++- 7 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index c204734..7e3f6c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ env: - MODULE_NAME='flag' - MODULE_TEST_GROUP='flag' - DRUPAL_REPO='git://drupalcode.org/project/drupal.git' - - DRUPAL_VERSION='8.x' + - DRUPAL_VERSION='8.0.x' - PHPCS_VERSION='2.0.*@dev' - CODER_VERSION='dev-8.x-2.x' diff --git a/flag.module b/flag.module index 58b2c44..5cea58b 100644 --- a/flag.module +++ b/flag.module @@ -17,6 +17,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\user\UserInterface; +use Drupal\Core\Form\FormStateInterface; // @todo: Implement flagging_view(). Not extremely useful. I already have it. @@ -257,7 +258,7 @@ function flag_permission() { * Disable permission on the permissions form that don't make sense for * anonymous users when Session API module is not enabled. */ -function flag_form_user_admin_permissions_alter(&$form, &$form_state, $form_id) { +function flag_form_user_admin_permissions_alter(&$form, FormStateInterface $form_state, $form_id) { if (!\Drupal::moduleHandler()->moduleExists('session_api')) { $flags = \Drupal::service('flag')->getFlags(); // Disable flag and unflag permission checkboxes for anonymous users. @@ -323,7 +324,7 @@ function flag_entity_extra_field_info() { /** * Implements hook_form_FORM_ID_alter(): node_type_form. */ -function flag_form_node_type_form_alter(&$form, &$form_state, $form_id) { +function flag_form_node_type_form_alter(&$form, FormStateInterface $form_state, $form_id) { global $user; $node_type = $form_state['controller']->getEntity(); $flags = \Drupal::service('flag')->getFlags('node', $node_type->id(), $user); @@ -374,7 +375,7 @@ function flag_node_links_alter(array &$links, NodeInterface $entity, array &$con * * @see flag_field_attach_submit(). */ -function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) { +function flag_field_attach_form($entity_type, $entity, &$form, FormStateInterface $form_state, $langcode) { $id = $entity->id; // Some modules are being stupid here. Commerce! @@ -479,7 +480,7 @@ function flag_field_attach_form($entity_type, $entity, &$form, &$form_state, $la * * @see flag_field_attach_form(). */ -function flag_field_attach_submit($entity_type, $entity, $form, &$form_state) { +function flag_field_attach_submit($entity_type, $entity, $form, FormStateInterface $form_state) { // This is invoked for each flag_field_attach_form(), but possibly more than // once for a particular form in the case that a form is showing multiple // entities (field collection, inline entity form). Hence we can't simply diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 7360592..5bd4068 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -227,14 +227,14 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t /** * Handles switching the configuration type selector. */ - public function updateSelectedPluginType($form, $form_state) { + public function updateSelectedPluginType($form, FormStateInterface $form_state) { return $form['display']['settings']; } /** * Handles submit call when sensor type is selected. */ - public function submitSelectPlugin(array $form, array &$form_state) { + public function submitSelectPlugin(array $form, FormStateInterface $form_state) { $this->entity = $this->buildEntity($form, $form_state); $form_state['rebuild'] = TRUE; diff --git a/src/Plugin/views/field/FlagViewsFlaggedField.php b/src/Plugin/views/field/FlagViewsFlaggedField.php index ddadeef..56f257d 100644 --- a/src/Plugin/views/field/FlagViewsFlaggedField.php +++ b/src/Plugin/views/field/FlagViewsFlaggedField.php @@ -9,6 +9,7 @@ use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\field\Boolean; +use Drupal\Core\Form\FormStateInterface; /** * Class FlagViewsFlaggedField @@ -35,7 +36,7 @@ protected function defineOptions() { return $options; } - public function buildOptionsForm(&$form, &$form_state) { + public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['relationship']['#default_value'] = $this->options['relationship']; parent::buildOptionsForm($form, $form_state); diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index 76c302e..e8d1306 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -8,6 +8,7 @@ use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\ResultRow; +use Drupal\Core\Form\FormStateInterface; /** * Class FlagViewsLinkField @@ -46,7 +47,7 @@ protected function defineOptions() { * @param $form * @param $form_state */ - public function buildOptionsForm(&$form, &$form_state) { + public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['text'] = array( '#type' => 'textfield', '#title' => t('Text to display'), diff --git a/src/Plugin/views/filter/FlagViewsFilter.php b/src/Plugin/views/filter/FlagViewsFilter.php index 795abaf..002db9c 100644 --- a/src/Plugin/views/filter/FlagViewsFilter.php +++ b/src/Plugin/views/filter/FlagViewsFilter.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\views\filter; use Drupal\views\Plugin\views\filter\BooleanOperator; +use Drupal\Core\Form\FormStateInterface; /** * Class FlagViewsFilter @@ -24,7 +25,7 @@ public function defineOptions() { return $options; } - public function buildOptionsForm(&$form, &$form_state) { + public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['value']['#type'] = 'radios'; $form['value']['#title'] = t('Status'); $form['value']['#options'] = array( diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 347bf77..4b065fa 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\views\relationship; use Drupal\views\Plugin\views\relationship\RelationshipPluginBase; +use Drupal\Core\Form\FormStateInterface; /** * Class FlagViewsRelationship @@ -23,7 +24,7 @@ public function defineOptions() { return $options; } - public function buildOptionsForm(&$form, &$form_state) { + public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $entity_type = $this->definition['flaggable']; From aa0b29ca49758919bdb636fb1b5a40351d3c2b37 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Sat, 19 Jul 2014 10:43:17 +0200 Subject: [PATCH 511/629] Fix fatal errors when flag_token_info() is called --- flag.module | 84 ++----------------------------------------------- flag.tokens.inc | 16 +++++----- 2 files changed, 10 insertions(+), 90 deletions(-) diff --git a/flag.module b/flag.module index 58b2c44..05c5209 100644 --- a/flag.module +++ b/flag.module @@ -11,7 +11,7 @@ define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); use Drupal\entity\Entity\EntityViewDisplay; -use Drupal\flag\Flag; +use Drupal\flag\Entity\Flag; use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; @@ -1376,87 +1376,7 @@ function flag_load_by_id($id) { * An array of the structure [fid] = flag_object. */ function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL) { - return entity_load_multiple('flag'); -/** - $flags = &drupal_static(__FUNCTION__); - - // Retrieve a list of all flags, regardless of the parameters. - if (!isset($flags)) { - $flags = array(); - - // Database flags. - $query = db_select('flag', 'f'); - $query->leftJoin('flag_types', 'fn', 'fn.fid = f.fid'); - $result = $query - ->fields('f', array('fid', 'entity_type', 'name', 'title', 'global', 'options')) - ->fields('fn', array('type')) - ->execute(); - foreach ($result as $row) { - if (!isset($flags[$row->name])) { - $flags[$row->name] = AbstractFlag::factory_by_row($row); - } - else { - $flags[$row->name]->types[] = $row->type; - } - } - - // Add code-based flags provided by modules. - $default_flags = flag_get_default_flags(); - foreach ($default_flags as $name => $default_flag) { - // Insert new enabled flags into the database to give them an FID. - if ($default_flag->status && !isset($flags[$name])) { - $default_flag->save(); - $flags[$name] = $default_flag; - } - - if (isset($flags[$name])) { - // Ensure overridden flags are associated with their parent module. - $flags[$name]->module = $default_flag->module; - - // Update the flag with any properties that are "locked" by the code version. - if (isset($default_flag->locked)) { - $flags[$name]->locked = $default_flag->locked; - foreach ($default_flag->locked as $property) { - $flags[$name]->$property = $default_flag->$property; - } - } - } - } - - // Sort the list of flags by weight. - uasort($flags, '_flag_compare_weight'); - - foreach ($flags as $flag) { - // Allow modules implementing hook_flag_alter(&$flag) to modify each flag. - drupal_alter('flag', $flag); - } - } - - // Make a variable copy to filter types and account. - $filtered_flags = $flags; - - // Filter out flags based on type and subtype. - if (isset($entity_type) || isset($content_subtype)) { - foreach ($filtered_flags as $name => $flag) { - if (!$flag->access_entity_enabled($entity_type, $content_subtype)) { - unset($filtered_flags[$name]); - } - } - } - - // Filter out flags based on account permissions. - if (isset($account) && $account->uid != 1) { - foreach ($filtered_flags as $name => $flag) { - // We test against the 'flag' action, which is the minimum permission to - // use a flag. - if (!$flag->user_access('flag', $account)) { - unset($filtered_flags[$name]); - } - } - } - - return $filtered_flags; - */ + return \Drupal::service('flag')->getFlags($entity_type, $content_subtype, $account); } /** diff --git a/flag.tokens.inc b/flag.tokens.inc index 8c962c7..e0439f0 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -75,16 +75,16 @@ function flag_token_info() { ); // Add tokens for the flag count available at the node/comment/user level. - foreach (\Drupal::service('flag')->fetchDefinition() as $flag_type) { - $flags = flag_get_flags($flag_type); + foreach (array_keys(\Drupal::service('flag')->fetchDefinition()) as $flag_type) { + $flags = \Drupal::service('flag')->getFlags($flag_type); foreach ($flags as $flag) { - $tokens[$flag_type]['flag-' . str_replace('_', '-', $flag->name) . '-count'] = array( - 'name' => t('@flag flag count', array('@flag' => $flag->get_title())), - 'description' => t('Total flag count for flag @flag', array('@flag' => $flag->get_title())), + $tokens[$flag_type]['flag-' . str_replace('_', '-', $flag->id()) . '-count'] = array( + 'name' => t('@flag flag count', array('@flag' => $flag->label())), + 'description' => t('Total flag count for flag @flag', array('@flag' => $flag->label())), ); - $tokens[$flag_type]['flag-' . str_replace('_', '-', $flag->name) . '-link'] = array( - 'name' => t('@flag flag link', array('@flag' => $flag->get_title())), - 'description' => t('Flag/unflag link for @flag', array('@flag' => $flag->get_title())), + $tokens[$flag_type]['flag-' . str_replace('_', '-', $flag->id()) . '-link'] = array( + 'name' => t('@flag flag link', array('@flag' => $flag->label())), + 'description' => t('Flag/unflag link for @flag', array('@flag' => $flag->label())), ); } } From 440b5540334223140eccbab93a304abeeebc6a02 Mon Sep 17 00:00:00 2001 From: Jibran Ijaz Date: Fri, 8 Aug 2014 21:10:58 +0500 Subject: [PATCH 512/629] Add build passing sign to README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de4f188..299406a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -flag-drupal8 +flag-drupal8 [![Build Status](https://travis-ci.org/socketwench/flag-drupal8.svg?branch=master)](https://travis-ci.org/socketwench/flag-drupal8) ============ Github sandbox for the Drupal 8 version of Flag module From 3143616679c146cb399828c0bad859509a610500 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 8 Aug 2014 14:11:39 +0200 Subject: [PATCH 513/629] Referenced class is not an entity access controller (now entity access control handler) --- src/Entity/Flagging.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index a6bb6db..d4df619 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -20,9 +20,6 @@ * @ContentEntityType( * id = "flagging", * label = @Translation("Flagging"), - * controllers = { - * "access" = "Drupal\flag\FlaggingAccessController", - * }, * base_table = "flagging", * fieldable = TRUE, * bundle_entity_type = "flag", @@ -131,4 +128,4 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { return $fields; } -} \ No newline at end of file +} From 95bea7e613ce20db19e3de79869965113146c545 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 8 Aug 2014 14:12:08 +0200 Subject: [PATCH 514/629] Use new setRedirectUrl() for form redirect --- src/Form/FlagDeleteForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php index 38180c9..b38d92e 100644 --- a/src/Form/FlagDeleteForm.php +++ b/src/Form/FlagDeleteForm.php @@ -54,7 +54,7 @@ public function submit(array $form, FormStateInterface $form_state) { '%label' => $this->entity->label(), ))); - $form_state['redirect_route'] = $this->getCancelUrl(); + $form_state->setRedirectUrl($this->getCancelUrl()); } } From f23504e44a160502a8da8bc794fdaadfd0b4253b Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 19 Aug 2014 00:05:26 -0500 Subject: [PATCH 515/629] Added flag views argument handler. --- flag.views.inc | 8 ++- .../argument/FlagViewsFlaggableArgument.php | 67 +++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/Plugin/views/argument/FlagViewsFlaggableArgument.php diff --git a/flag.views.inc b/flag.views.inc index b1e99b3..380eede 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -56,13 +56,17 @@ function flag_views_data() { ); $data['flagging']['entity_id'] = array( - 'title' => t('Entity ID'), - 'help' => t('The ID of the entity'), + 'title' => t('Flaggable ID'), + 'help' => t('The unique ID of the object that has been flagged.'), 'sort' => array( 'id' => 'standard', ), + 'argument' => array( + 'id' => 'FlagViewsFlaggableArgument', + ), ); + // Flag content links. $data['flagging']['link_flag'] = array( 'field' => array( diff --git a/src/Plugin/views/argument/FlagViewsFlaggableArgument.php b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php new file mode 100644 index 0000000..c41dae9 --- /dev/null +++ b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php @@ -0,0 +1,67 @@ +database = $database; + } + + public function getFlag() { + // When editing a view it's possible to delete the relationship (either by + // error or to later recreate it), so we have to guard against a missing + // one. + if (isset($this->view->relationship[$this->options['relationship']])) { + return $this->view->relationship[$this->options['relationship']]->getFlag(); + } + } + + public function titleQuery() { + $titles = array(); + + $flag = $this->getFlag(); + $entityType = $flag->getFlaggableEntityType(); + + $def = \Drupal::entityManager()->getDefinition($entityType); + $baseTable = $def->getBaseTable(); + $entityKeys = $def->getKeys(); + $idKey = $entityKeys['id']; + + $result = $this->database->select($def->getBaseTable(), 'o') + ->fields('o', $entityKeys['label']) + ->condition('o.' . $entityKeys['id'], $this->value, 'IN') + ->execute(); + + + foreach ($result as $title) { + $titles[] = String::check_plain($title->$entityKeys['label']); + } + + return $titles; + } + +} \ No newline at end of file From d3503ab9f24a22eea7246d8cda657150510304c0 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Wed, 20 Aug 2014 17:56:09 +0200 Subject: [PATCH 516/629] FieldDefinition is now BaseFieldDefinition --- src/Entity/Flagging.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index d4df619..83bda17 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -8,8 +8,7 @@ use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\ContentEntityBase; -use Drupal\Core\Entity\EntityStorageControllerInterface; -use Drupal\Core\Field\FieldDefinition; +use Drupal\Core\Field\BaseFieldDefinition; use Drupal\flag\FlaggingInterface; /** @@ -84,36 +83,36 @@ public function getFlaggable() { * {@inheritdoc} */ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { - $fields['id'] = FieldDefinition::create('integer') + $fields['id'] = BaseFieldDefinition::create('integer') ->setLabel(t('Flagging ID')) ->setDescription(t('The flagging ID.')) ->setReadOnly(TRUE); - $fields['uuid'] = FieldDefinition::create('uuid') + $fields['uuid'] = BaseFieldDefinition::create('uuid') ->setLabel(t('UUID')) ->setDescription(t('The flagging UUID.')) ->setReadOnly(TRUE); - $fields['fid'] = FieldDefinition::create('string') + $fields['fid'] = BaseFieldDefinition::create('string') ->setLabel(t('Flag ID')) ->setDescription(t('The Flag ID.')) ->setReadOnly(TRUE); - $fields['entity_type'] = FieldDefinition::create('string') + $fields['entity_type'] = BaseFieldDefinition::create('string') ->setLabel(t('Entity Type')) ->setDescription(t('The Entity Type.')); - $fields['entity_id'] = FieldDefinition::create('string') + $fields['entity_id'] = BaseFieldDefinition::create('string') ->setLabel(t('Entity ID')) ->setDescription(t('The Entity ID.')); - $fields['type'] = FieldDefinition::create('entity_reference') + $fields['type'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Type')) ->setDescription(t('The flag type.')) ->setSetting('target_type', 'flag') ->setReadOnly(TRUE); - $fields['uid'] = FieldDefinition::create('entity_reference') + $fields['uid'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('User ID')) ->setDescription(t('The user ID of the flagging user.')) ->setSettings(array( @@ -121,7 +120,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { 'default_value' => 0, )); - $fields['created'] = FieldDefinition::create('created') + $fields['created'] = BaseFieldDefinition::create('created') ->setLabel(t('Created')) ->setDescription(t('The time that the flagging was created.')); From 267ee96bda7056dfaf464d8edb54072fb4a85dc1 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Thu, 21 Aug 2014 08:03:13 +0200 Subject: [PATCH 517/629] Convert to field_ui_base_route, remove no longer existing bundle keys --- src/Entity/Flagging.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 83bda17..53e2ad4 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -22,16 +22,11 @@ * base_table = "flagging", * fieldable = TRUE, * bundle_entity_type = "flag", + * field_ui_base_route = "flag.edit", * entity_keys = { * "id" = "id", * "bundle" = "type", * "uuid" = "uuid" - * }, - * bundle_keys = { - * "bundle" = "type" - * }, - * links = { - * "admin-form" = "flag.edit" * } * ) */ From 06e3110f0c0b6cf13d158556cc9985dc7aa72891 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Thu, 21 Aug 2014 08:14:42 +0200 Subject: [PATCH 518/629] Update redirects and other form_state changes --- src/Form/FlagAddPageForm.php | 7 +++---- src/Form/FlagFormBase.php | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index 7fbdecc..3890220 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -113,10 +113,9 @@ public function validateForm(array &$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - $form_state['redirect'] = FLAG_ADMIN_PATH . '/add/' . - $form_state['values']['flag_entity_type']; + $form_state->setRedirect('flag.add', array('entity_type' => $form_state->getValue('flag_entity_type'))); $tempstore = \Drupal::service('user.tempstore')->get('flag'); - $tempstore->set('FlagAddPage', $form_state['values']); + $tempstore->set('FlagAddPage', $form_state->getValues()); } -} \ No newline at end of file +} diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 5bd4068..deffc0e 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -320,14 +320,14 @@ public function save(array $form, FormStateInterface $form_state) { // @todo: when we add database caching for flags we'll have to clear the // cache again here. - $form_state['redirect'] = 'admin/structure/flags'; + $form_state->setRedirect('flag.list'); } /** * Overrides Drupal\Core\Entity\EntityFormController::delete(). */ public function delete(array $form, FormStateInterface $form_state) { - $form_state['redirect'] = 'admin/structure/flags'; + $form_state->setRedirect('flag_list'); } } From 6319b8abf10ff2cba4708ea4c7d0bacdbf33d46c Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 21 Aug 2014 18:49:52 -0500 Subject: [PATCH 519/629] Fixed code style issues in flag.views.inc --- flag.views.inc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 380eede..834079b 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -4,6 +4,10 @@ * Contains views API hooks for Flag module. */ +/** + * Implements hook_views_data(). + * @return array + */ function flag_views_data() { $data = array(); $data['flagging']['table']['group'] = t('Flag'); @@ -13,7 +17,7 @@ function flag_views_data() { 'node' => array( 'type' => 'LEFT', 'left_field' => 'nid', - 'field' => 'entity_id', + 'field' => 'entity_id', ), ); @@ -66,7 +70,6 @@ function flag_views_data() { ), ); - // Flag content links. $data['flagging']['link_flag'] = array( 'field' => array( @@ -120,7 +123,7 @@ function flag_views_data() { 'help' => t('The time a piece of content was most recently flagged by any user.'), 'field' => array( 'id' => 'date', - //'click sortable' => TRUE, + // 'click sortable' => TRUE, ), /*'sort' => array( 'id' => 'date', @@ -136,6 +139,10 @@ function flag_views_data() { return $data; } +/** + * Implements hook_views_data_alter(). + * @param $data + */ function flag_views_data_alter(&$data) { $flags = \Drupal::service('flag')->getFlags(); From ba8667c922e6e53114e8a0b83ec444cbe2d6aba1 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 21 Aug 2014 20:45:15 -0500 Subject: [PATCH 520/629] Fixed code style issues in flag.api.php. --- flag.api.php | 68 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/flag.api.php b/flag.api.php index d8b3b83..71c5743 100644 --- a/flag.api.php +++ b/flag.api.php @@ -5,6 +5,9 @@ * Hooks provided by the Flag module. */ +use Drupal\flag\FlagInterface; +use Drupal\Core\Session\AccountInterface; +use Drupal\flag\FlaggingInterface; /** * @addtogroup hooks * @{ @@ -15,19 +18,22 @@ * * This hook may be placed in a $module.flag.inc file. * - * @param $definitions + * @param array $definitions * An array of flag definitions returned by hook_flag_type_info(). */ -function hook_flag_type_info_alter(&$definitions) { +function hook_flag_type_info_alter(array &$definitions) { } /** * Allow modules to alter a flag when it is initially loaded. * + * @param \Drupal\flag\FlagInterface $flag + * The flag to alter. + * * @see flag_get_flags(). */ -function hook_flag_alter(&$flag) { +function hook_flag_alter(FlagInterface &$flag) { } @@ -38,30 +44,30 @@ function hook_flag_alter(&$flag) { * them here so that their additions to the flag admin form are saved into the * flag object. * - * @param $options + * @param array $options * The array of default options for the flag type, with the options for the * flag's link type merged in. - * @param $flag + * @param \Drupal\flag\FlagInterface $flag * The flag object. * * @see flag_flag::options() */ -function hook_flag_options_alter(&$options, $flag) { +function hook_flag_options_alter(array &$options, FlagInterface $flag) { } /** * Perform custom validation on a flag before flagging/unflagging. * - * @param $action + * @param string $action * The action about to be carried out. Either 'flag' or 'unflag'. - * @param $flag + * @param \Drupal\flag\FlagInterface $flag * The flag object. - * @param $entity_id + * @param int $entity_id * The id of the entity the user is trying to flag or unflag. - * @param $account + * @param \Drupal\Core\Session\AccountInterface $account * The user account performing the action. - * @param $flagging + * @param \Drupal\flag\FlaggingInterface $flagging * The flagging entity. * * @return @@ -70,7 +76,9 @@ function hook_flag_options_alter(&$options, $flag) { * drupal_access_denied will be called and a 403 will be returned. * If validation is successful, do not return a value. */ -function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permission_check, $flagging) { +function hook_flag_validate($action, FlagInterface $flag, $entity_id, + AccountInterface $account, $skip_permission_check, + FlaggingInterface $flagging) { // We're only operating on the "test" flag, and users may always unflag. if ($flag->name == 'test' && $action == 'flag') { // Get all flags set by the current user. @@ -92,13 +100,13 @@ function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permissi * Called when displaying a single entity view or edit page. For flag access * checks from within Views, implement hook_flag_access_multiple(). * - * @param $flag + * @param \Drupal\flag\FlagInterface $flag * The flag object. - * @param $entity_id + * @param int $entity_id * The id of the entity in question. - * @param $action + * @param string $action * The action to test. Either 'flag' or 'unflag'. - * @param $account + * @param \Drupal\Core\Session\AccountInterface $account * The user on whose behalf to test the flagging action. * * @return @@ -113,7 +121,9 @@ function hook_flag_validate($action, $flag, $entity_id, $account, $skip_permissi * @see hook_flag_access_multiple() * @see flag_flag:access() */ -function hook_flag_access($flag, $entity_id, $action, $account) { +function hook_flag_access(FlagInterface $flag, + $entity_id, $action, + AccountInterface $account) { } @@ -123,11 +133,11 @@ function hook_flag_access($flag, $entity_id, $action, $account) { * Called when preparing a View or list of multiple flaggable entities. * For flag access checks for individual entities, see hook_flag_access(). * - * @param $flag + * @param \Drupal\flag\FlagInterface $flag * The flag object. - * @param $entity_ids + * @param array $entity_ids * An array of object ids to check access. - * @param $account + * @param \Drupal\Core\Session\AccountInterface $account * The user on whose behalf to test the flagging action. * * @return @@ -137,37 +147,39 @@ function hook_flag_access($flag, $entity_id, $action, $account) { * @see hook_flag_access() * @see flag_flag:access_multiple() */ -function hook_flag_access_multiple($flag, $entity_ids, $account) { +function hook_flag_access_multiple(FlagInterface $flag, + array $entity_ids, + AccountInterface $account) { } /** * Act when a flag is reset. * - * @param $flag + * @param \Drupal\flag\FlagInterface $flag * The flag object. - * @param $entity_id + * @param int $entity_id * The entity ID on which all flaggings are to be removed. May be NULL, in * which case all of this flag's entities are to be unflagged. - * @param $rows + * @param array $rows * Database rows from the {flagging} table. * * @see flag_reset_flag() */ -function hook_flag_reset($flag, $entity_id, $rows) { +function hook_flag_reset(FlagInterface $flag, $entity_id, array $rows) { } /** * Alter the javascript structure that describes the flag operation. * - * @param $flag + * @param \Drupal\flag\FlagInterface $flag * The full flag object. - * @param $entity_id + * @param int $entity_id * The ID of the node, comment, user or other object being flagged. * * @see flag_build_javascript_info() */ -function hook_flag_javascript_info_alter() { +function hook_flag_javascript_info_alter(FlagInterface $flag, $entity_id) { } From 10a43e4950cd4f307851bc63c65b39ae3d4824c1 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 21 Aug 2014 20:57:04 -0500 Subject: [PATCH 521/629] Fixed code style issues in flag.tpl.php --- theme/flag.tpl.php | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/theme/flag.tpl.php b/theme/flag.tpl.php index 60a3113..be526e4 100644 --- a/theme/flag.tpl.php +++ b/theme/flag.tpl.php @@ -2,31 +2,34 @@ /** * @file - * Default theme implementation to display a flag link, and a message after the action - * is carried out. + * Default theme implementation to display a flag link, and a message after the + * action is carried out. * * Available variables: * * - $flag: The flag object itself. You will only need to use it when the * following variables don't suffice. - * - $flag_name_css: The flag name, with all "_" replaced with "-". For use in 'class' - * attributes. - * - $flag_classes: A space-separated list of CSS classes that should be applied to the link. + * - $flag_name_css: The flag name, with all "_" replaced with "-". For use in + * 'class' attributes. + * - $flag_classes: A space-separated list of CSS classes that should be + * applied to the link. * - * - $action: The action the link is about to carry out, either "flag" or "unflag". + * - $action: The action the link is about to carry out, either "flag" or + * "unflag". * - $status: The status of the item; either "flagged" or "unflagged". * * - $link_href: The URL for the flag link. * - $link_text: The text to show for the link. * - $link_title: The title attribute for the link. * - * - $message_text: The long message to show after a flag action has been carried out. - * - $message_classes: A space-separated list of CSS classes that should be applied to - * the message. - * - $after_flagging: This template is called for the link both before and after being - * flagged. If displaying to the user immediately after flagging, this value - * will be boolean TRUE. This is usually used in conjunction with immedate - * JavaScript-based toggling of flags. + * - $message_text: The long message to show after a flag action has been + * carried out. + * - $message_classes: A space-separated list of CSS classes that should be + * applied to the message. + * - $after_flagging: This template is called for the link both before and + * after being flagged. If displaying to the user immediately after flagging, + * this value will be boolean TRUE. This is usually used in conjunction with + * immediate JavaScript-based toggling of flags. * - $needs_wrapping_element: Determines whether the flag displays a wrapping * HTML DIV element. * @@ -35,8 +38,8 @@ * - flag--name.tpl.php * - flag--link-type.tpl.php * - * NOTE: This template spaces out the tags for clarity only. When doing some - * advanced theming you may have to remove all the whitespace. + * NOTE: This template spaces out the tags for clarity only. When doing + * some advanced theming you may have to remove all the whitespace. */ ?> From fb4719ca1929521d2d6434bdd549241aecdb8f35 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 21 Aug 2014 21:08:15 -0500 Subject: [PATCH 522/629] Fixed code style issues in flag.tokens.inc. --- flag.tokens.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flag.tokens.inc b/flag.tokens.inc index e0439f0..7fcf735 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -6,7 +6,7 @@ */ /** - * Implements of hook_token_info(). + * Implements hook_token_info(). */ function flag_token_info() { $types = array(); @@ -183,12 +183,12 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr /** * Returns HTML for a tokens browser. * - * @param $variables + * @param array $variables * An associative array containing: * - types: An array naming the types of tokens to show. * - global_types: Whether to show global tokens. */ -function theme_flag_tokens_browser($variables) { +function theme_flag_tokens_browser(array $variables) { $types = $variables['types']; $global_types = $variables['global_types']; From a51e11c3e3d94261d64dc34792164fe7adf49ff9 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 21 Aug 2014 21:51:11 -0500 Subject: [PATCH 523/629] Fixed code style issues in flag.js. --- theme/flag.js | 15 ++++++++------- theme/flag.tpl.php | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/theme/flag.js b/theme/flag.js index 19b871d..9415551 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -51,7 +51,7 @@ Drupal.flagLink = function(context) { * A click handler that is attached to all elements. */ function flagClick(event) { - // Prevent the default browser click handler + // Prevent the default browser click handler. event.preventDefault(); // 'this' won't point to the element when it's inside the ajax closures, @@ -71,7 +71,7 @@ Drupal.flagLink = function(context) { // Hide any other active messages. $('span.flag-message:visible').fadeOut(); - // Send POST request + // Send POST request. $.ajax({ type: 'POST', url: element.href, @@ -100,7 +100,7 @@ Drupal.flagLink = function(context) { $.event.trigger('flagGlobalAfterLinkUpdate', [data]); }, error: function (xmlhttp) { - alert('An HTTP error '+ xmlhttp.status +' occurred.\n'+ element.href); + alert('An HTTP error ' + xmlhttp.status +' occurred.\n' + element.href); $wrapper.removeClass('flag-waiting'); } }); @@ -177,11 +177,12 @@ Drupal.flagAnonymousLinkTemplates = function(context) { */ Drupal.flagCookie = function(name, value, options) { if (typeof value != 'undefined') { - // name and value given, set cookie + // Name and value given, set cookie. options = options || {}; if (value === null) { value = ''; - // clone object since it's unexpected behavior if the expired property were changed + // Clone object since it's unexpected behavior if the expired property + // were changed. options = $.extend({}, options); options.expires = -1; } @@ -195,7 +196,7 @@ Drupal.flagCookie = function(name, value, options) { date = options.expires; } - // use expires attribute, max-age is not supported by IE + // Use expires attribute, max-age is not supported by IE. expires = '; expires=' + date.toUTCString(); } // NOTE Needed to parenthesize options.path and options.domain @@ -206,7 +207,7 @@ Drupal.flagCookie = function(name, value, options) { var secure = options.secure ? '; secure' : ''; document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); } else { - // only name given, get cookie + // Only name given, get cookie. var cookieValue = null; if (document.cookie && document.cookie != '') { var cookies = document.cookie.split(';'); diff --git a/theme/flag.tpl.php b/theme/flag.tpl.php index be526e4..64455f9 100644 --- a/theme/flag.tpl.php +++ b/theme/flag.tpl.php @@ -2,8 +2,7 @@ /** * @file - * Default theme implementation to display a flag link, and a message after the - * action is carried out. + * Default theme implementation to display a flag link. * * Available variables: * From 1afbb9c2eb2fde8118c64253b35c9de2334e7cee Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 21 Aug 2014 22:19:06 -0500 Subject: [PATCH 524/629] Fixed code style issues in flag.views.inc. --- flag.views.inc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 834079b..7260422 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -6,7 +6,9 @@ /** * Implements hook_views_data(). + * * @return array + * An array of views data. */ function flag_views_data() { $data = array(); @@ -141,9 +143,10 @@ function flag_views_data() { /** * Implements hook_views_data_alter(). - * @param $data + * @param array $data + * An array of views data. */ -function flag_views_data_alter(&$data) { +function flag_views_data_alter(array &$data) { $flags = \Drupal::service('flag')->getFlags(); foreach ($flags as $fid => $flag) { From 9f05926074168b1727f5081a6cb084ed0f1e86cf Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 22 Aug 2014 20:00:12 -0500 Subject: [PATCH 525/629] Fixed code style issues in ActionLinkType.php. --- flag.views.inc | 5 +++-- src/Annotation/ActionLinkType.php | 10 ++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 7260422..2fdf206 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -8,7 +8,7 @@ * Implements hook_views_data(). * * @return array - * An array of views data. + * An array of flag views data. */ function flag_views_data() { $data = array(); @@ -143,8 +143,9 @@ function flag_views_data() { /** * Implements hook_views_data_alter(). + * * @param array $data - * An array of views data. + * An array of views data. */ function flag_views_data_alter(array &$data) { $flags = \Drupal::service('flag')->getFlags(); diff --git a/src/Annotation/ActionLinkType.php b/src/Annotation/ActionLinkType.php index ad9d087..3d4cac7 100644 --- a/src/Annotation/ActionLinkType.php +++ b/src/Annotation/ActionLinkType.php @@ -9,13 +9,11 @@ use Drupal\Component\Annotation\Plugin; /** - * Class ActionLinkType - * @package Drupal\action_link\Annotation - * * Defines an ActionLink annotation object. * - * @Annotation + * @package Drupal\action_link\Annotation * + * @Annotation */ class ActionLinkType extends Plugin { @@ -36,10 +34,10 @@ class ActionLinkType extends Plugin { public $label; /** - * The plugin description + * The plugin description. * * @var string */ public $description; -} \ No newline at end of file +} From 879bbd54932f2a1652dac2fd45eaa38fd5dc83c7 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 22 Aug 2014 21:21:19 -0500 Subject: [PATCH 526/629] Fixed docblocks in FlaggingEvent and FlagService. --- flag.views.inc | 4 +- src/Event/FlaggingEvent.php | 8 ++- src/FlagService.php | 116 +++++++++++++++++++++++++++++------- 3 files changed, 103 insertions(+), 25 deletions(-) diff --git a/flag.views.inc b/flag.views.inc index 2fdf206..6552919 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -8,7 +8,7 @@ * Implements hook_views_data(). * * @return array - * An array of flag views data. + * The views provided by the flag module. */ function flag_views_data() { $data = array(); @@ -145,7 +145,7 @@ function flag_views_data() { * Implements hook_views_data_alter(). * * @param array $data - * An array of views data. + * The views data to alter. */ function flag_views_data_alter(array &$data) { $flags = \Drupal::service('flag')->getFlags(); diff --git a/src/Event/FlaggingEvent.php b/src/Event/FlaggingEvent.php index e187d1d..2692416 100644 --- a/src/Event/FlaggingEvent.php +++ b/src/Event/FlaggingEvent.php @@ -18,7 +18,7 @@ class FlaggingEvent extends FlagEventBase { /** * The Flag in question. * - * @var \Drupal\Core\Entity\EntityInterface + * @var \Drupal\Core\Entity\EntityInterface */ protected $entity; @@ -30,11 +30,13 @@ class FlaggingEvent extends FlagEventBase { protected $action; /** + * Builds a new FlaggingEvent. + * * @param \Drupal\flag\FlagInterface $flag * The flag. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to be acted upon. - * @param string + * @param string $action * The action to perform. One of 'flag' or 'unflag' */ public function __construct(FlagInterface $flag, EntityInterface $entity, $action) { @@ -44,4 +46,4 @@ public function __construct(FlagInterface $flag, EntityInterface $entity, $actio $this->action = $action; } -} \ No newline at end of file +} diff --git a/src/FlagService.php b/src/FlagService.php index 3770088..f58578b 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -52,18 +52,21 @@ class FlagService { * Constructor. * * @param FlagTypePluginManager $flagType + * The flag type plugin manager. * @param EventDispatcherInterface $eventDispatcher + * The event dispatcher service. * @param QueryFactory $entityQuery + * The entity query factory. * @param AccountInterface $currentUser + * The current user. * @param EntityManagerInterface $entityManager + * The entity manager. */ - public function __construct( - FlagTypePluginManager $flagType, - EventDispatcherInterface $eventDispatcher, - QueryFactory $entityQuery, - AccountInterface $currentUser, - EntityManagerInterface $entityManager - ) { + public function __construct(FlagTypePluginManager $flagType, + EventDispatcherInterface $eventDispatcher, + QueryFactory $entityQuery, + AccountInterface $currentUser, + EntityManagerInterface $entityManager) { $this->flagTypeMgr = $flagType; $this->eventDispatcher = $eventDispatcher; $this->entityQueryMgr = $entityQuery; @@ -74,7 +77,7 @@ public function __construct( /** * Get a flag type definition. * - * @param $entity_type + * @param string $entity_type * (optional) The entity type to get the definition for, or NULL to return * all flag types. * @@ -99,11 +102,11 @@ public function fetchDefinition($entity_type = NULL) { * If node type or account are entered, a list of all possible flags will be * returned. * - * @param $entity_type + * @param string $entity_type * (optional) The type of entity for which to load the flags. Usually 'node'. - * @param $bundle + * @param string $bundle * (optional) The bundle for which to load the flags. - * @param $account + * @param AccountInterface $account * (optional) The user account to filter available flags. If not set, all * flags for the given entity and bundle will be returned. * @@ -139,6 +142,19 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ return $filtered_flags; } + /** + * Get all flaggings for the given entity, flag, and optionally, user. + * + * @param EntityInterface $entity + * The flaggable entity. + * @param FlagInterface $flag + * The flag entity. + * @param AccountInterface $account + * Optional. The account of the flagging user. If NULL, flaggings for any + * user will be returned. + * @return array + * An array of flaggings. + */ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { if ($account == NULL) { $account = $this->currentUser; @@ -160,19 +176,44 @@ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, Accou } /** - * @todo Should not work like this, instead of the ID, the object itself should be passed along! + * Load the flag entity given the ID. + * + * @param int $flag_id + * The ID of the flag to load. + * @return FlagInterface|null + * The flag entity. */ public function getFlagById($flag_id) { return entity_load('flag', $flag_id); } /** - * @todo Should not work like this, instead of the ID, the object itself should be passed along! + * Loads the flaggable entity given the flag entity and entity ID. + * + * @param FlagInterface $flag + * The flag entity. + * @param int $entity_id + * The ID of the flaggable entity. + * @return EntityInterface|null + * The flaggable entity object. */ public function getFlaggableById(FlagInterface $flag, $entity_id) { return entity_load($flag->getFlaggableEntityType(), $entity_id); } + /** + * Flags the given entity given the flag and entity objects. + * + * @param FlagInterface $flag + * The flag entity. + * @param EntityInterface $entity + * The entity to flag. + * @param AccountInterface $account + * Optional. The account of the user flagging the entity. If not given, + * the current user is used. + * @return FlaggingInterface|null + * The flagging. + */ public function flagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { if (empty($account)) { $account = $this->currentUser; @@ -202,13 +243,19 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou } /** + * Flags an entity given the flag ID and entity ID. * * @api * - * @param $flag_id - * @param $entity_id + * @param int $flag_id + * The ID of the flag. + * @param int $entity_id + * The ID of the entity to flag. * @param AccountInterface $account - * @return EntityInterface + * Optional. The account of user flagging the entity. If not given, the + * current user is used. + * @return FlaggingInterface|null + * The flagging entity. */ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { @@ -222,13 +269,18 @@ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { } /** + * Unflags an entity given the flag ID and entity ID. * * @api * - * @param $flag_id - * @param $entity_id + * @param int $flag_id + * The ID of the flag. + * @param int $entity_id + * The ID of the flagged entity to unflag. * @param AccountInterface $account + * Optional. The account of the user that created the flagging. * @return array + * An array of flagging IDs to delete. */ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { @@ -243,18 +295,38 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { return $this->unflagByObject($flag, $entity, $account); } + /** + * Unflags the given entity for the given flag. + * + * @param FlagInterface $flag + * The flag being unflagged. + * @param EntityInterface $entity + * The entity to unflag. + * @param AccountInterface $account + * Optional. The account of the user that created the flagging. + * @return array + * An array of flagging IDs to delete. + */ public function unflagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { $this->eventDispatcher->dispatch(FlagEvents::ENTITY_UNFLAGGED, new FlaggingEvent($flag, $entity, 'unflag')); $out = array(); - $flaggings = $this->getFlaggings($entity, $flag); + $flaggings = $this->getFlaggings($entity, $flag, $account); foreach ($flaggings as $flagging) { - $out[] = $this->unflagByFlagging($flagging); + $out[] = $flagging->id(); + + $this->unflagByFlagging($flagging); } return $out; } + /** + * Deletes the given flagging. + * + * @param FlaggingInterface $flagging + * The flagging to delete. + */ public function unflagByFlagging(FlaggingInterface $flagging) { $flagging->delete(); } @@ -263,7 +335,9 @@ public function unflagByFlagging(FlaggingInterface $flagging) { * Increments count of flagged entities. * * @param FlagInterface $flag + * The flag to increment. * @param EntityInterface $entity + * The flaggable entity. */ protected function incrementFlagCounts(FlagInterface $flag, EntityInterface $entity) { db_merge('flag_counts') @@ -284,7 +358,9 @@ protected function incrementFlagCounts(FlagInterface $flag, EntityInterface $ent * Reverts incrementation of count of flagged entities. * * @param FlagInterface $flag + * The flag to decrement. * @param EntityInterface $entity + * The flaggable entity. */ protected function decrementFlagCounts(FlagInterface $flag, EntityInterface $entity) { $count_result = db_select('flag_counts') From d34d4a3036858563d917f00feb49a6d7e40796ee Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 22 Aug 2014 21:29:24 -0500 Subject: [PATCH 527/629] Fixed code style issues in FlagTypePluginManager.php. --- src/FlagTypePluginManager.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FlagTypePluginManager.php b/src/FlagTypePluginManager.php index 20ed9d6..087f505 100644 --- a/src/FlagTypePluginManager.php +++ b/src/FlagTypePluginManager.php @@ -17,7 +17,7 @@ class FlagTypePluginManager extends DefaultPluginManager { * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths - * keyed by the corresponding namespace to look for plugin implementations, + * keyed by the corresponding namespace to look for plugin implementations. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend instance to use. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler @@ -26,7 +26,7 @@ class FlagTypePluginManager extends DefaultPluginManager { public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { parent::__construct('Plugin/Flag', $namespaces, $module_handler, 'Drupal\flag\Annotation\FlagType'); - //$this->alterInfo('flag_type_info'); + // $this->alterInfo('flag_type_info'); $this->setCacheBackend($cache_backend, 'flag'); } @@ -47,4 +47,4 @@ public function getAllFlagTypes() { return $flag_types; } -} \ No newline at end of file +} From 3a4373220eccc6ed8ce9eef9b52f13f7322d0216 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 22 Aug 2014 21:34:18 -0500 Subject: [PATCH 528/629] Fixed code style issues in FlaggingConfirmForm.php. --- src/Form/FlaggingConfirmForm.php | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index 9a1eded..dd698a7 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -12,17 +12,22 @@ /** * Provides the form page for the Confirm Form link type. + * * @package Drupal\flag\Form * @see \Drupal\flag\Plugin\ActionLink\ConfirmForm */ class FlaggingConfirmForm extends ConfirmFormBase { /** + * The flaggable entity. + * * @var \Drupal\Core\Entity\EntityInterface */ protected $entity; /** + * The flag entity. + * * @var \Drupal\flag\FlagInterface */ protected $flag; @@ -33,9 +38,9 @@ class FlaggingConfirmForm extends ConfirmFormBase { public function buildForm(array $form, FormStateInterface $form_state, $flag_id = NULL, $entity_id = NULL) { - $flagService = \Drupal::service('flag'); - $this->flag = $flagService->getFlagByID($flag_id); - $this->entity = $flagService->getFlaggableById($this->flag, $entity_id); + $flag_service = \Drupal::service('flag'); + $this->flag = $flag_service->getFlagByID($flag_id); + $this->entity = $flag_service->getFlaggableById($this->flag, $entity_id); return parent::buildForm($form, $form_state); } @@ -50,13 +55,13 @@ public function getFormID() { * {@inheritdoc} */ public function getQuestion() { - $linkType = $this->flag->getLinkTypePlugin(); + $link_type = $this->flag->getLinkTypePlugin(); if ($this->isFlagged()) { - return $linkType->getUnflagQuestion(); + return $link_type->getUnflagQuestion(); } - return $linkType->getFlagQuestion(); + return $link_type->getFlagQuestion(); } /** @@ -93,6 +98,12 @@ public function getConfirmText() { return $this->t('Flag'); } + /** + * Helper method to determine if the entity has been flagged or not. + * + * @return bool + * TRUE if the current entity is flagged, FALSE otherwise. + */ protected function isFlagged() { return $this->flag->isFlagged($this->entity); } From 7998ec80f5742622ad6e6e2e2effc8a9a3dad2b8 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 22 Aug 2014 23:09:06 -0500 Subject: [PATCH 529/629] Fixed docblock issues in several files. --- flag.api.php | 50 ++++++++++++------------- src/ActionLinkTypePluginInterface.php | 10 +++-- src/Controller/AJAXLinkController.php | 46 ++++++++++++++++------- src/Controller/ReloadLinkController.php | 22 ++++++++--- src/FlagTypeBase.php | 36 +++++++++++------- src/FlagTypePluginInterface.php | 2 +- src/Form/FlaggingConfirmForm.php | 2 +- src/Plugin/Flag/CommentFlagType.php | 2 +- src/Plugin/Flag/NodeFlagType.php | 2 +- src/Plugin/Flag/UserFlagType.php | 2 +- 10 files changed, 109 insertions(+), 65 deletions(-) diff --git a/flag.api.php b/flag.api.php index 71c5743..6314d7c 100644 --- a/flag.api.php +++ b/flag.api.php @@ -19,7 +19,7 @@ * This hook may be placed in a $module.flag.inc file. * * @param array $definitions - * An array of flag definitions returned by hook_flag_type_info(). + * An array of flag definitions returned by hook_flag_type_info(). */ function hook_flag_type_info_alter(array &$definitions) { @@ -29,9 +29,9 @@ function hook_flag_type_info_alter(array &$definitions) { * Allow modules to alter a flag when it is initially loaded. * * @param \Drupal\flag\FlagInterface $flag - * The flag to alter. + * The flag to alter. * - * @see flag_get_flags(). + * @see flag_get_flags() */ function hook_flag_alter(FlagInterface &$flag) { @@ -45,10 +45,10 @@ function hook_flag_alter(FlagInterface &$flag) { * flag object. * * @param array $options - * The array of default options for the flag type, with the options for the - * flag's link type merged in. + * The array of default options for the flag type, with the options for the + * flag's link type merged in. * @param \Drupal\flag\FlagInterface $flag - * The flag object. + * The flag object. * * @see flag_flag::options() */ @@ -60,17 +60,17 @@ function hook_flag_options_alter(array &$options, FlagInterface $flag) { * Perform custom validation on a flag before flagging/unflagging. * * @param string $action - * The action about to be carried out. Either 'flag' or 'unflag'. + * The action about to be carried out. Either 'flag' or 'unflag'. * @param \Drupal\flag\FlagInterface $flag - * The flag object. + * The flag object. * @param int $entity_id - * The id of the entity the user is trying to flag or unflag. + * The id of the entity the user is trying to flag or unflag. * @param \Drupal\Core\Session\AccountInterface $account - * The user account performing the action. + * The user account performing the action. * @param \Drupal\flag\FlaggingInterface $flagging - * The flagging entity. + * The flagging entity. * - * @return + * @return array|null * Optional array: textual error with the error-name as the key. * If the error name is 'access-denied' and javascript is disabled, * drupal_access_denied will be called and a 403 will be returned. @@ -101,15 +101,15 @@ function hook_flag_validate($action, FlagInterface $flag, $entity_id, * checks from within Views, implement hook_flag_access_multiple(). * * @param \Drupal\flag\FlagInterface $flag - * The flag object. + * The flag object. * @param int $entity_id - * The id of the entity in question. + * The id of the entity in question. * @param string $action - * The action to test. Either 'flag' or 'unflag'. + * The action to test. Either 'flag' or 'unflag'. * @param \Drupal\Core\Session\AccountInterface $account - * The user on whose behalf to test the flagging action. + * The user on whose behalf to test the flagging action. * - * @return + * @return boolean|null * One of the following values: * - TRUE: User has access to the flag. * - FALSE: User does not have access to the flag. @@ -134,13 +134,13 @@ function hook_flag_access(FlagInterface $flag, * For flag access checks for individual entities, see hook_flag_access(). * * @param \Drupal\flag\FlagInterface $flag - * The flag object. + * The flag object. * @param array $entity_ids - * An array of object ids to check access. + * An array of object ids to check access. * @param \Drupal\Core\Session\AccountInterface $account - * The user on whose behalf to test the flagging action. + * The user on whose behalf to test the flagging action. * - * @return + * @return array * An array whose keys are the object IDs and values are booleans indicating * access. * @@ -157,12 +157,12 @@ function hook_flag_access_multiple(FlagInterface $flag, * Act when a flag is reset. * * @param \Drupal\flag\FlagInterface $flag - * The flag object. + * The flag object. * @param int $entity_id - * The entity ID on which all flaggings are to be removed. May be NULL, in - * which case all of this flag's entities are to be unflagged. + * The entity ID on which all flaggings are to be removed. May be NULL, in + * which case all of this flag's entities are to be unflagged. * @param array $rows - * Database rows from the {flagging} table. + * Database rows from the {flagging} table. * * @see flag_reset_flag() */ diff --git a/src/ActionLinkTypePluginInterface.php b/src/ActionLinkTypePluginInterface.php index 318392d..6a0f18b 100644 --- a/src/ActionLinkTypePluginInterface.php +++ b/src/ActionLinkTypePluginInterface.php @@ -12,7 +12,8 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface; /** - * Interface ActionLinkTypePluginInterface + * Provides an interface for link type plugins. + * * @package Drupal\flag */ interface ActionLinkTypePluginInterface extends PluginFormInterface, ConfigurablePluginInterface { @@ -35,11 +36,14 @@ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) /** * Generates a flag link as a render array. * - * @param $action + * @param string $action + * The action to perform, 'flag' and 'unflag'. * @param FlagInterface $flag + * The flag entity. * @param EntityInterface $entity + * The entity for which to create a flag link. * @return array * A render array of the flag link. */ public function renderLink($action, FlagInterface $flag, EntityInterface $entity); -} \ No newline at end of file +} diff --git a/src/Controller/AJAXLinkController.php b/src/Controller/AJAXLinkController.php index e52a152..4ad3c95 100644 --- a/src/Controller/AJAXLinkController.php +++ b/src/Controller/AJAXLinkController.php @@ -13,6 +13,11 @@ use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\ReplaceCommand; +/** + * Provides a controller for AJAX-ified flag links. + * + * @package Drupal\flag\Controller + */ class AJAXLinkController extends ControllerBase { /** @@ -21,9 +26,13 @@ class AJAXLinkController extends ControllerBase { * This method is invoked when a user clicks an AJAX flagging link provided * by the AJAXactionLink plugin. * - * @param $flag_id - * @param $entity_id + * @param int $flag_id + * The flag ID. + * @param int $entity_id + * The flaggable ID. * @return AjaxResponse + * The response object. + * * @see \Drupal\flag\Plugin\ActionLink\AJAXactionLink */ public function flag($flag_id, $entity_id) { @@ -41,44 +50,53 @@ public function flag($flag_id, $entity_id) { * This method is invoked when a user clicks an AJAX unflagging link provided * by the AJAXactionLink plugin. * - * @param $flag_id - * @param $entity_id + * @param int $flag_id + * The flag ID. + * @param int $entity_id + * The entity ID to unflag. * @return AjaxResponse + * The response object. * * @see \Drupal\flag\Plugin\ActionLink\AJAXactionLink */ public function unflag($flag_id, $entity_id) { - $flagService = \Drupal::service('flag'); - $flagService->unflag($flag_id, $entity_id); + $flag_service = \Drupal::service('flag'); + $flag_service->unflag($flag_id, $entity_id); - $flag = $flagService->getFlagById($flag_id); - $entity = $flagService->getFlaggableById($flag, $entity_id); + $flag = $flag_service->getFlagById($flag_id); + $entity = $flag_service->getFlaggableById($flag, $entity_id); return $this->generateResponse('flag', $flag, $entity); } /** - * @param $action + * Generates a response object after handing the un/flag request. + * + * @param string $action + * The action being performed, should be 'flag' or 'unflag'. * @param FlagInterface $flag + * The flag entity. * @param EntityInterface $entity + * The entity object. * @return AjaxResponse + * The response object. */ protected function generateResponse($action, FlagInterface $flag, EntityInterface $entity) { // Create a new AJAX response. $response = new AjaxResponse(); // Get the link type plugin. - $linkType = $flag->getLinkTypePlugin(); + $link_type = $flag->getLinkTypePlugin(); // Generate the link render array and get the link CSS ID. - $link = $linkType->renderLink($action, $flag, $entity); - $linkId = '#' . $link['#attributes']['id']; + $link = $link_type->renderLink($action, $flag, $entity); + $link_id = '#' . $link['#attributes']['id']; // Create a new JQuery Replace command to update the link display. - $replace = new ReplaceCommand($linkId, drupal_render($link)); + $replace = new ReplaceCommand($link_id, drupal_render($link)); $response->addCommand($replace); return $response; } -} \ No newline at end of file +} diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 255c797..fd30610 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -20,6 +20,8 @@ class ReloadLinkController extends ControllerBase implements ContainerInjectionInterface { /** + * The flag service. + * * @var \Drupal\flag\FlagService */ protected $flagService; @@ -28,6 +30,7 @@ class ReloadLinkController extends ControllerBase implements ContainerInjectionI * Constructor. * * @param FlagService $flag + * The flag service. */ public function __construct(FlagService $flag) { $this->flagService = $flag; @@ -37,7 +40,9 @@ public function __construct(FlagService $flag) { * Create. * * @param ContainerInterface $container - * @return static + * The container object. + * @return ReloadLinkController + * The reload link controller. */ public static function create(ContainerInterface $container) { return new static( @@ -48,9 +53,12 @@ public static function create(ContainerInterface $container) { /** * Performs a flagging when called via a route. * - * @param $flag_id - * @param $entity_id + * @param int $flag_id + * The flag ID. + * @param int $entity_id + * The flaggable ID. * @return \Symfony\Component\HttpFoundation\RedirectResponse + * The response object. * * @see \Drupal\flag\Plugin\Reload */ @@ -67,9 +75,12 @@ public function flag($flag_id, $entity_id) { /** * Performs a flagging when called via a route. * - * @param $flag_id - * @param $entity_id + * @param int $flag_id + * The flag ID. + * @param int $entity_id + * The flagging ID. * @return \Symfony\Component\HttpFoundation\RedirectResponse + * The response object. * * @see \Drupal\flag\Plugin\Reload */ @@ -86,3 +97,4 @@ public function unflag($flag_id, $entity_id) { } } + diff --git a/src/FlagTypeBase.php b/src/FlagTypeBase.php index ead7632..78c91c0 100644 --- a/src/FlagTypeBase.php +++ b/src/FlagTypeBase.php @@ -12,10 +12,11 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class FlagTypeBase + * Provides a base class for flag type plugins. + * * @package Drupal\flag\Plugin\Flag */ -abstract class FlagTypeBase extends PluginBase implements FlagTypePluginInterface{ +abstract class FlagTypeBase extends PluginBase implements FlagTypePluginInterface { /** * {@inheritdoc} @@ -29,6 +30,7 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi * Provides the default configuration values for the flag type. * * @return array + * The flag type's default plugin configuration. */ public function defaultConfiguration() { return array(); @@ -45,6 +47,7 @@ public function calculateDependencies() { * Returns this flag type plugin's configuration array. * * @return array + * The plugin configuration array. */ public function getConfiguration() { return $this->configuration; @@ -54,6 +57,7 @@ public function getConfiguration() { * Replaces the plugin's configurations with those given in the parameter. * * @param array $configuration + * The plugin configuration array. */ public function setConfiguration(array $configuration) { $this->configuration = $configuration; @@ -62,11 +66,13 @@ public function setConfiguration(array $configuration) { /** * Provides a form for this action link plugin settings. * - * The form provided by this method is displayed by the FlagAddForm when creating - * or editing the Flag. Derived classes should want to override this. + * The form provided by this method is displayed by the FlagAddForm when + * creating or editing the Flag. Derived classes should override this. * * @param array $form + * The form array. * @param FormStateInterface $form_state + * The form state. * @return array * The form array * @see \Drupal\flag\Form\FlagAddForm @@ -81,7 +87,9 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * Derived classes will want to override this. * * @param array $form - * @param array $form_state + * The form array. + * @param FormStateInterface $form_state + * The form state. */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. @@ -91,7 +99,9 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s * Handles the validation for the action link plugin settings form. * * @param array $form - * @param array $form_state + * The form array. + * @param FormStateInterface $form_state + * The form state. */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. @@ -102,13 +112,13 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form * * @abstract * - * @return - * An array keyed by entity ids, whose values represent the access to the - * corresponding entity. The access value may be FALSE if access should be - * denied, or NULL (or not set) if there is no restriction to be made. It - * should NOT be TRUE. + * @return array + * An array keyed by entity ids, whose values represent the access to the + * corresponding entity. The access value may be FALSE if access should be + * denied, or NULL (or not set) if there is no restriction to be made. It + * should NOT be TRUE. */ - public function type_access_multiple($entity_ids, $account) { + public function typeAccessMultiple($entity_ids, $account) { return array(); } -} \ No newline at end of file +} diff --git a/src/FlagTypePluginInterface.php b/src/FlagTypePluginInterface.php index 0b71e24..2a61bcd 100644 --- a/src/FlagTypePluginInterface.php +++ b/src/FlagTypePluginInterface.php @@ -14,5 +14,5 @@ * @package Drupal\flag */ interface FlagTypePluginInterface extends PluginFormInterface, ConfigurablePluginInterface { - public function type_access_multiple($entity_ids, $account); + public function typeAccessMultiple($entity_ids, $account); } \ No newline at end of file diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index dd698a7..b524313 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -12,7 +12,7 @@ /** * Provides the form page for the Confirm Form link type. - * + * * @package Drupal\flag\Form * @see \Drupal\flag\Plugin\ActionLink\ConfirmForm */ diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index 0ee4f16..690a1a3 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -72,7 +72,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * {@inheritdoc} */ - public function type_access_multiple($entity_ids, $account) { + public function typeAccessMultiple($entity_ids, $account) { $access = array(); // If all subtypes are allowed, we have nothing to say here. diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index f0e0ffc..3941846 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -86,7 +86,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * {@inheritdoc} */ - public function type_access_multiple($entity_ids, $account) { + public function typeAccessMultiple($entity_ids, $account) { $access = array(); // If all subtypes are allowed, we have nothing to say here. diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 836d070..a8750c6 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -78,7 +78,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * {@inheritdoc} */ - public function type_access_multiple($entity_ids, $account) { + public function typeAccessMultiple($entity_ids, $account) { $access = array(); // Exclude anonymous. From 0e8bd8056a9f58d8abbec255e646af8a3e164f58 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 23 Aug 2014 10:56:04 -0500 Subject: [PATCH 530/629] Fixed docblocks in several files. --- src/Plugin/Flag/UserFlagType.php | 21 ++++++++--- .../argument/FlagViewsFlaggableArgument.php | 31 ++++++++++------ .../views/field/FlagViewsFlaggedField.php | 18 ++++++++-- src/Plugin/views/field/FlagViewsLinkField.php | 35 +++++++++++++------ src/Plugin/views/filter/FlagViewsFilter.php | 17 ++++++--- .../relationship/FlagViewsRelationship.php | 22 +++++++++--- .../views/sort/FlagViewsSortFlagged.php | 9 +++-- src/Tests/FlagSimpleTest.php | 8 ++++- theme/flag.js | 3 +- 9 files changed, 123 insertions(+), 41 deletions(-) diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index a8750c6..254622b 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -10,7 +10,8 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class UserFlagType + * Provides a flag type for user entities. + * * @package Drupal\flag\Plugin\Flag * * @FlagType( @@ -51,14 +52,14 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['access']['access_uid'] = array( '#type' => 'checkbox', '#title' => t('Users may flag themselves'), - '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themself does not make sense.'), - '#default_value' => $this->configuration['access_uid'] ? 0 : 1, + '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themselves does not make sense.'), + '#default_value' => $this->getAccessUidSetting() ? 0 : 1, ); $form['display']['show_on_profile'] = array( '#type' => 'checkbox', '#title' => t('Display link on user profile page'), '#description' => t('Show the link formatted as a user profile element.'), - '#default_value' => $this->configuration['show_on_profile'], + '#default_value' => $this->showOnProfile(), // Put this above 'show on entity'. '#weight' => -1, ); @@ -94,10 +95,22 @@ public function typeAccessMultiple($entity_ids, $account) { return $access; } + /** + * Specifies if users are able to flag themselves. + * + * @return boolean|mixed + * TRUE if users are able to flag themselves, FALSE otherwise. + */ public function getAccessUidSetting() { return $this->configuration['access_uid']; } + /** + * Specifies if the flag link should appear on the user profile. + * + * @return boolean + * TRUE if the flag link appears on the user profile, FALSE otherwise. + */ public function showOnProfile() { return $this->configuration['show_on_profile']; } diff --git a/src/Plugin/views/argument/FlagViewsFlaggableArgument.php b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php index c41dae9..44d9eac 100644 --- a/src/Plugin/views/argument/FlagViewsFlaggableArgument.php +++ b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php @@ -11,7 +11,8 @@ use Drupal\Component\Utility\String; /** - * Class FlagViewsFlaggableArgument + * Provides an argument handler to get the title of flaggble content. + * * @package Drupal\flag\Plugin\views\argument * * @ViewsArgument("FlagViewsFlaggableArgument") @@ -25,12 +26,21 @@ class FlagViewsFlaggableArgument extends Numeric { */ protected $database; + /** + * {@inheritdoc} + */ public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->database = $database; } + /** + * Helper method to retrieve the flag entity from the views relationship. + * + * @return FlagInterface|null + * The flag entity selected in the relationship. + */ public function getFlag() { // When editing a view it's possible to delete the relationship (either by // error or to later recreate it), so we have to guard against a missing @@ -40,28 +50,29 @@ public function getFlag() { } } + /** + * {@inheritdoc} + */ public function titleQuery() { $titles = array(); $flag = $this->getFlag(); - $entityType = $flag->getFlaggableEntityType(); + $entity_type = $flag->getFlaggableEntityType(); - $def = \Drupal::entityManager()->getDefinition($entityType); - $baseTable = $def->getBaseTable(); - $entityKeys = $def->getKeys(); - $idKey = $entityKeys['id']; + $def = \Drupal::entityManager()->getDefinition($entity_type); + $entity_keys = $def->getKeys(); $result = $this->database->select($def->getBaseTable(), 'o') - ->fields('o', $entityKeys['label']) - ->condition('o.' . $entityKeys['id'], $this->value, 'IN') + ->fields('o', $entity_keys['label']) + ->condition('o.' . $entity_keys['id'], $this->value, 'IN') ->execute(); foreach ($result as $title) { - $titles[] = String::check_plain($title->$entityKeys['label']); + $titles[] = String::check_plain($title->$entity_keys['label']); } return $titles; } -} \ No newline at end of file +} diff --git a/src/Plugin/views/field/FlagViewsFlaggedField.php b/src/Plugin/views/field/FlagViewsFlaggedField.php index 56f257d..64a3bbf 100644 --- a/src/Plugin/views/field/FlagViewsFlaggedField.php +++ b/src/Plugin/views/field/FlagViewsFlaggedField.php @@ -12,13 +12,21 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class FlagViewsFlaggedField + * Provides a views field to show if the selected content is flagged or not. + * + * This field differs from FlagViewsLinkField in that it is display only. It + * does not provide an actionable link, but rather inherits from the Boolean + * views field handler. + * * @package Drupal\flag\Plugin\views\field * * @ViewsField("flag_flagged") */ class FlagViewsFlaggedField extends Boolean { + /** + * {@inheritdoc} + */ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); @@ -29,6 +37,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o // and b) they will not necessarily make sense in a static context. } + /** + * {@inheritdoc} + */ protected function defineOptions() { $options = parent::defineOptions(); $options['relationship'] = array('default' => 'flag_content_rel'); @@ -36,9 +47,12 @@ protected function defineOptions() { return $options; } + /** + * {@inheritdoc} + */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['relationship']['#default_value'] = $this->options['relationship']; parent::buildOptionsForm($form, $form_state); } -} \ No newline at end of file +} diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index e8d1306..9084d12 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -11,7 +11,11 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class FlagViewsLinkField + * Provides a views field to flag or unflag the selected content. + * + * Unlike FlagViewsFlaggedField, this views field handler provides an + * actionable link to flag or unflag the selected content. + * * @package Drupal\flag\Plugin\views\field * * @ViewsField("flag_link") @@ -27,6 +31,9 @@ public function getFlag() { } } + /** + * {@inheritdoc} + */ protected function defineOptions() { $options = parent::defineOptions(); @@ -44,8 +51,7 @@ protected function defineOptions() { } /** - * @param $form - * @param $form_state + * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['text'] = array( @@ -59,41 +65,48 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); } + /** + * {@inheritdoc} + */ public function query() { // Intentionally do nothing here since we're only providing a link and not // querying against a real table column. } /** - * @param ResultRow $values - * @return string|void + * {@inheritdoc} */ public function render(ResultRow $values) { - //$entity = $this->getEntity($values); + // $entity = $this->getEntity($values); return $this->renderLink($values->_entity, $values); } /** - * @param $data + * Creates a render array for flag links. + * + * @param EntityInterface $entity + * The entity object. * @param ResultRow $values + * The current result row. + * @return array + * The render array for the flag link. */ protected function renderLink($entity, ResultRow $values) { - // if (empty($entity) || !$entity->access('view')) { if (empty($entity)) { return t('N/A'); } $flag = $this->getFlag(); - $linkTypePlugin = $flag->getLinkTypePlugin(); + $link_type_plugin = $flag->getLinkTypePlugin(); $action = 'flag'; if ($flag->isFlagged($entity)) { $action = 'unflag'; } - $link = $linkTypePlugin->renderLink($action, $flag, $entity); + $link = $link_type_plugin->renderLink($action, $flag, $entity); return $link; } -} \ No newline at end of file +} diff --git a/src/Plugin/views/filter/FlagViewsFilter.php b/src/Plugin/views/filter/FlagViewsFilter.php index 002db9c..1e96026 100644 --- a/src/Plugin/views/filter/FlagViewsFilter.php +++ b/src/Plugin/views/filter/FlagViewsFilter.php @@ -10,13 +10,17 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class FlagViewsFilter + * Filters content by its flagging status in a view. + * * @package Drupal\flag\Plugin\views\filter * * @ViewsFilter("flag_filter") */ class FlagViewsFilter extends BooleanOperator { + /** + * {@inheritdoc} + */ public function defineOptions() { $options = parent::defineOptions(); $options['value'] = array('default' => 1); @@ -25,6 +29,9 @@ public function defineOptions() { return $options; } + /** + * {@inheritdoc} + */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['value']['#type'] = 'radios'; $form['value']['#title'] = t('Status'); @@ -32,7 +39,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { 1 => t('Flagged'), 0 => t('Not flagged'), // @todo Find out what in the hell filter type ALL is supposed to do. - //'All' => t('All'), + // 'All' => t('All'), ); $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; @@ -42,7 +49,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); } - + /** + * {@inheritdoc} + */ public function query() { $this->ensureMyTable(); @@ -51,4 +60,4 @@ public function query() { $this->query->addWhere($this->options['group'], "$this->tableAlias.uid", NULL, $operator); } -} \ No newline at end of file +} diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 4b065fa..8cb8056 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -10,12 +10,15 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class FlagViewsRelationship + * Provides a views relationship to select flag content by a flag. * * @ViewsRelationship("flag_relationship") */ class FlagViewsRelationship extends RelationshipPluginBase { + /** + * {@inheritdoc} + */ public function defineOptions() { $options = parent::defineOptions(); $options['flag'] = array('default' => NULL); @@ -24,6 +27,9 @@ public function defineOptions() { return $options; } + /** + * {@inheritdoc} + */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); @@ -33,7 +39,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $flags = \Drupal::service('flag')->getFlags($entity_type); $default_value = $this->options['flag']; - if (!empty($flags) ) { + if (!empty($flags)) { $default_value = current(array_keys($flags)); } @@ -70,6 +76,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } } + /** + * {@inheritdoc} + */ public function query() { if (!($flag = $this->getFlag())) { return; @@ -102,13 +111,18 @@ public function query() { } // parent::query(); - } + /** + * Get the flag of the relationship. + * + * @return FlagInterface|null + * The flag being selected by in the view. + */ public function getFlag() { $flaggable = $this->definition['flaggable']; $flag = \Drupal::service('flag')->getFlags($flaggable); $this->options['flag'] = $flag; return current($flag); } -} \ No newline at end of file +} diff --git a/src/Plugin/views/sort/FlagViewsSortFlagged.php b/src/Plugin/views/sort/FlagViewsSortFlagged.php index 76dad93..ea2297f 100644 --- a/src/Plugin/views/sort/FlagViewsSortFlagged.php +++ b/src/Plugin/views/sort/FlagViewsSortFlagged.php @@ -10,7 +10,7 @@ use Drupal\views\Plugin\views\sort\SortPluginBase; /** - * Class FlagViewsSortFlagged + * Sorts entities by flagged or unflagged in a view. * * @ViewsSort("flag_sort") */ @@ -29,7 +29,7 @@ protected function sortOptions() { } /** - * Display whether or not the sort order is ascending or descending + * Display whether or not the sort order is ascending or descending. */ public function adminSummary() { if (!empty($this->options['exposed'])) { @@ -41,9 +41,12 @@ public function adminSummary() { return $sort_options[strtoupper($this->options['order'])]; } + /** + * {@inheritdoc} + */ public function query() { $this->ensureMyTable(); $this->query->addOrderBy(NULL, "$this->tableAlias.uid", $this->options['order']); } -} \ No newline at end of file +} diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index af315a3..6784ab9 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -19,22 +19,28 @@ class FlagSimpleTest extends WebTestBase { /** + * The label of the flag to create for the test. + * * @var string */ protected $label = 'Test label 123'; /** + * The ID of the flag to create for the test. + * * @var string */ protected $id = 'test_label_123'; /** + * The flag link type. + * * @var string */ protected $flagLinkType; /** - * + * The node type to use in the test. * * @var string */ diff --git a/theme/flag.js b/theme/flag.js index 9415551..27cb150 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -100,7 +100,7 @@ Drupal.flagLink = function(context) { $.event.trigger('flagGlobalAfterLinkUpdate', [data]); }, error: function (xmlhttp) { - alert('An HTTP error ' + xmlhttp.status +' occurred.\n' + element.href); + alert('An HTTP error ' + xmlhttp.status + ' occurred.\n' + element.href); $wrapper.removeClass('flag-waiting'); } }); @@ -128,7 +128,6 @@ String.prototype.flagNameToCSS = function() { */ Drupal.flagAnonymousLinkTemplates = function(context) { // Swap in current links. Cookies are set by PHP's setcookie() upon flagging. - var templates = Drupal.settings.flag.templates; // Build a list of user-flags. From a92d98be339e23081266e4d7e4b95900243f3efd Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 23 Aug 2014 11:22:36 -0500 Subject: [PATCH 531/629] Fixed further code style issues in UserFlagType, FlagViewsFlaggableArguement, and FlagViewsLinkField. --- src/Plugin/Flag/UserFlagType.php | 4 ++-- .../views/argument/FlagViewsFlaggableArgument.php | 1 - src/Plugin/views/field/FlagViewsLinkField.php | 10 +++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 254622b..f81d3ad 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -98,7 +98,7 @@ public function typeAccessMultiple($entity_ids, $account) { /** * Specifies if users are able to flag themselves. * - * @return boolean|mixed + * @return bool|mixed * TRUE if users are able to flag themselves, FALSE otherwise. */ public function getAccessUidSetting() { @@ -108,7 +108,7 @@ public function getAccessUidSetting() { /** * Specifies if the flag link should appear on the user profile. * - * @return boolean + * @return bool * TRUE if the flag link appears on the user profile, FALSE otherwise. */ public function showOnProfile() { diff --git a/src/Plugin/views/argument/FlagViewsFlaggableArgument.php b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php index 44d9eac..8e7a4c1 100644 --- a/src/Plugin/views/argument/FlagViewsFlaggableArgument.php +++ b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php @@ -67,7 +67,6 @@ public function titleQuery() { ->condition('o.' . $entity_keys['id'], $this->value, 'IN') ->execute(); - foreach ($result as $title) { $titles[] = String::check_plain($title->$entity_keys['label']); } diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index 9084d12..e34a1df 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -9,6 +9,7 @@ use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\ResultRow; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Entity\EntityInterface; /** * Provides a views field to flag or unflag the selected content. @@ -22,6 +23,12 @@ */ class FlagViewsLinkField extends FieldPluginBase { + /** + * A helper method to retrieve the flag entity from the views relationship. + * + * @return FlagInterface|null + * The flag selected by the views relationship. + */ public function getFlag() { // When editing a view it's possible to delete the relationship (either by // error or to later recreate it), so we have to guard against a missing @@ -88,10 +95,11 @@ public function render(ResultRow $values) { * The entity object. * @param ResultRow $values * The current result row. + * * @return array * The render array for the flag link. */ - protected function renderLink($entity, ResultRow $values) { + protected function renderLink(EntityInterface $entity, ResultRow $values) { if (empty($entity)) { return t('N/A'); } From 410c4103b5295881399be54ba7b456f17f352f60 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 23 Aug 2014 11:37:01 -0500 Subject: [PATCH 532/629] Fixed code style issues in NodeFlagType.php. --- src/Plugin/Flag/NodeFlagType.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index 3941846..a5176fd 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -53,7 +53,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta 'own' => t('Users may only flag content they own'), 'others' => t('Users may only flag content of others'), ), - '#default_value' => $this->configuration['access_author'], + '#default_value' => $this->getAccessAuthorSetting(), '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), ); @@ -65,7 +65,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '1' => t('Flag translations of content as a group'), '0' => t('Flag each translation of content separately'), ), - //'#default_value' => $this->i18n, + '#default_value' => $this->getInternationalizationSetting(), '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), '#access' => \Drupal::moduleHandler()->moduleExists('translation_helpers'), '#weight' => 5, @@ -107,11 +107,28 @@ public function typeAccessMultiple($entity_ids, $account) { return $access; } + /** + * Returns the flag type access author setting. + * + * @return string + * The access author setting can be one of three values: + * - '' = No additional restrictions. + * - 'own' = Users may only flag content they own. + * - 'others' = Users may only flag content of others. + */ public function getAccessAuthorSetting() { return $this->configuration['access_author']; } + /** + * Returns the internationalization setting for the flag type. + * + * @return int + * The internationalization setting can be one of two values: + * - 1 = Flag translations of content as a group. + * - 0 = Flag each translation of content separately. + */ public function getInternationalizationSetting() { - $this->configuration['i18n']; + return $this->configuration['i18n']; } } From dbd972aef2f2ca664a3eb3a98fa12c451df9fb3c Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 24 Aug 2014 16:00:01 -0500 Subject: [PATCH 533/629] Refactored EntityFlagType.php and fixed some docbock issues. --- src/Plugin/Flag/EntityFlagType.php | 50 +++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 0a68298..433492d 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -10,7 +10,8 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class EntityFlagType + * Provides a flag type for all entity types. + * * @package Drupal\flag\Plugin\Flag * * Base entity flag handler. @@ -72,7 +73,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $view_modes = \Drupal::entityManager()->getViewModes($this->entity_type); foreach ($view_modes as $name => $view_mode) { $options[$name] = t('Display on @name view mode', array('@name' => $view_mode['label'])); - $defaults[$name] = !empty($this->show_in_links[$name]) ? $name : 0; + $defaults[$name] = $this->showInLinks($name); } $form['display']['show_in_links'] = array( @@ -87,7 +88,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#type' => 'checkbox', '#title' => t('Display link as field'), '#description' => t('Show the flag link as a pseudofield, which can be ordered among other entity elements in the "Manage display" settings for the entity type.'), - '#default_value' => isset($this->show_as_field) ? $this->show_as_field : TRUE, + '#default_value' => $this->showAsField(), ); /* if (empty($entity_info['fieldable'])) { @@ -135,19 +136,54 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s $this->configuration['show_contextual_link'] = $form_state['values']['show_contextual_link']; } - public function showInLinks() { - return $this->configuration['show_in_links']; + /** + * Return the show in links setting given a view mode. + * + * @param string $name + * The name of the view mode. + * + * @return mixed + * The name of the view mode if the flag appears in links, 0 otherwise. + */ + public function showInLinks($name) { + if (!empty($this->configuration['show_in_links'][$name])) { + return $name; + } + + return 0; } + /** + * Returns the show as field setting. + * + * @return bool + * TRUE if the flag should appear as a psudofield, FALSE otherwise. + */ public function showAsField() { - return $this->configuration['show_as_field']; + if (!empty($this->configuration['show_as_field'])) { + return $this->configuration['show_as_field']; + } + + return TRUE; } + /** + * Returns the show on form setting. + * + * @return bool + * TRUE if the flag should appear on the entity form, FALSE otherwise. + */ public function showOnForm() { return $this->configuration['show_on_form']; } + /** + * Returns the show on contextual link setting. + * + * @return bool + * TRUE if the flag should appear in contextual links, FALSE otherwise. + */ public function showContextualLink() { return $this->configuration['show_contextual_link']; } -} \ No newline at end of file +} From 92531198887b362943002d88b04f5dc2ef30a1a7 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 24 Aug 2014 17:16:04 -0500 Subject: [PATCH 534/629] Fixed docblocks in ActionLinkTypeBase.php. --- src/ActionLinkTypeBase.php | 47 +++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index aabaa38..318b92a 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -30,8 +30,11 @@ abstract class ActionLinkTypeBase extends PluginBase implements ActionLinkTypePl * Build a new link type instance and sets the configuration. * * @param array $configuration + * The configuration array with which to initialize this plugin. * @param string $plugin_id + * The ID with which to initialize this plugin. * @param array $plugin_definition + * The plugin definition array. */ public function __construct(array $configuration, $plugin_id, array $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); @@ -42,8 +45,9 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi /** * Returns a route name given an $action. * - * @param $action - * A string containing the action name. + * @param string|null $action + * A string containing the action name. + * * @return string * A string containing a route name. */ @@ -88,7 +92,7 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity } /** - * {@inhereitdoc} + * {@inheritdoc} */ public function calculateDependencies() { return array(); @@ -96,42 +100,52 @@ public function calculateDependencies() { /** * Provides a form array for the action link plugin's settings form. + * * Derived classes will want to override this method. * * @param array $form - * @param array $form_state + * The form array. + * @param FormStateInterface $form_state + * The form state. * @return array - * The configuration form array. + * The modified form array. */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { return $form; } /** - * Processes the action link setting form submit. Derived classes will want to - * override this method. + * Processes the action link setting form submit. + * + * Derived classes will want to override this method. * * @param array $form - * @param array $form_state + * The form array. + * @param FormStateInterface $form_state + * The form state. */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. } /** - * Validates the action link setting form. Derived classes will want to override - * this method. + * Validates the action link setting form. + * + * Derived classes will want to override this method. * * @param array $form - * @param array $form_state + * The form array. + * @param FormStateInterface $form_state + * The form state. */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { // Override this. } /** - * Provides the action link plugin's default configuration. Derived classes - * will want to override this method. + * Provides the action link plugin's default configuration. + * + * Derived classes will want to override this method. * * @return array * The plugin configuration array. @@ -141,17 +155,18 @@ public function defaultConfiguration() { } /** - * Provides the action link plugin's current configuraiton array. + * Provides the action link plugin's current configuration array. * * @return array - * An array containing the plugin's currnt configuration. + * An array containing the plugin's current configuration. */ public function getConfiguration() { return $this->configuration; } /** - * Replaces the plugin's current configuration with that given in the parameter. + * Updates the plugin's current configuration. + * * @param array $configuration * An array containing the plugin's configuration. */ From b88f7018d41660172c118e386e4077d42a9f86ea Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 24 Aug 2014 17:18:37 -0500 Subject: [PATCH 535/629] Reformatted a long line of commented out code that cuased phpcs to barf in FlagAddPageForm.php. --- src/Form/FlagAddPageForm.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index 3890220..a6a3a56 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -104,7 +104,9 @@ public function validateForm(array &$form, FormStateInterface $form_state) { /* $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); if (get_class($flag) == 'BrokenFlag') { - form_set_error('type', t("This flag type, %type, isn't valid.", array('%type' => $form_state['values']['type']))); + form_set_error('type', + t("This flag type, %type, isn't valid.", + array('%type' => $form_state['values']['type']))); } */ } From e142188000df9c9b3e984157c89fb949f1c06c52 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 24 Aug 2014 17:22:05 -0500 Subject: [PATCH 536/629] Fixed code style isues in FlagAddForm.php. --- src/Form/FlagAddForm.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Form/FlagAddForm.php b/src/Form/FlagAddForm.php index c0e5e4b..f130d49 100644 --- a/src/Form/FlagAddForm.php +++ b/src/Form/FlagAddForm.php @@ -25,8 +25,7 @@ class FlagAddForm extends FlagFormBase { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $entity_type = NULL) { - //@todo Check all non-form_* params with check_plain(). - + // @todo Check all non-form_* params with check_plain(). $tempstore = \Drupal::service('user.tempstore')->get('flag'); $step1_form = $tempstore->get('FlagAddPage'); @@ -53,4 +52,4 @@ protected function actions(array $form, FormStateInterface $form_state) { $actions['submit']['#value'] = t('Create Flag'); return $actions; } -} \ No newline at end of file +} From 43e067ce083080b2571a272dcc9ebf2c09c60ee6 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 24 Aug 2014 17:24:33 -0500 Subject: [PATCH 537/629] Fixed a code style issue, in FlagDeleteForm.php. --- src/Form/FlagDeleteForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php index b38d92e..d314af6 100644 --- a/src/Form/FlagDeleteForm.php +++ b/src/Form/FlagDeleteForm.php @@ -27,7 +27,7 @@ class FlagDeleteForm extends EntityConfirmFormBase { */ public function getQuestion() { return t('Are you sure you want to delete the Flag %label?', array( - '%label' => $this->entity->label() + '%label' => $this->entity->label(), )); } From 18eaf4f20228456645cec3f0ee0bb0752d5353cc Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 24 Aug 2014 17:39:10 -0500 Subject: [PATCH 538/629] Fixed a code style issue in FlagEditForm.php. --- src/Form/FlagEditForm.php | 2 +- src/Form/FlagFormBase.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Form/FlagEditForm.php b/src/Form/FlagEditForm.php index cebfedb..7695520 100644 --- a/src/Form/FlagEditForm.php +++ b/src/Form/FlagEditForm.php @@ -29,4 +29,4 @@ protected function actions(array $form, FormStateInterface $form_state) { return $actions; } -} \ No newline at end of file +} diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index deffc0e..3ac86a9 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -309,7 +309,7 @@ public function save(array $form, FormStateInterface $form_state) { } /* foreach (array_keys(user_roles(!\Drupal::moduleHandler()->moduleExists('session_api'))) as $rid) { - // Create an array of permissions, based on the checkboxes element name. + // Create an array of permissions. $permissions = array( "flag $flag->name" => $flag->roles['flag'][$rid], "unflag $flag->name" => $flag->roles['unflag'][$rid], From de0e6cd7bbfe371637b957045d53c4be4a861bc8 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 24 Aug 2014 17:56:53 -0500 Subject: [PATCH 539/629] Fixed code style issues in FlagInterface, deleted unused BrokenFlagType. --- src/BrokenFlagType.php | 24 ------------------------ src/Entity/Flag.php | 4 ++-- src/FlagInterface.php | 17 ++++++++++++----- 3 files changed, 14 insertions(+), 31 deletions(-) delete mode 100644 src/BrokenFlagType.php diff --git a/src/BrokenFlagType.php b/src/BrokenFlagType.php deleted file mode 100644 index db8da36..0000000 --- a/src/BrokenFlagType.php +++ /dev/null @@ -1,24 +0,0 @@ - $this->entity_type)), 'error'); - $form = array(); - } - -} \ No newline at end of file diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 4181f13..769dce0 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -353,8 +353,8 @@ public function isGlobal() { /** * {@inheritdoc} */ - public function setGlobal($isGlobal = TRUE) { - if ($isGlobal) { + public function setGlobal($is_global = TRUE) { + if ($is_global) { $this->is_global = TRUE; } else { diff --git a/src/FlagInterface.php b/src/FlagInterface.php index 13b1040..bf9331b 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -18,7 +18,7 @@ */ interface FlagInterface extends ConfigEntityInterface, EntityWithPluginBagsInterface { - //@todo: Add getters and setters as necessary. + /* @todo: Add getters and setters as necessary. */ /** * Enables the Flag for use. @@ -34,8 +34,12 @@ public function disable(); * Returns true of there's a flagging for this flag and the given entity. * * @param EntityInterface $entity + * The flaggable entity. * @param AccountInterface $account - * @return boolean + * Optional. The account of the user that flagged the entity. + * + * @return bool + * True if the given entity is flagged, FALSE otherwise. */ public function isFlagged(EntityInterface $entity, AccountInterface $account = NULL); @@ -48,6 +52,7 @@ public function isFlagged(EntityInterface $entity, AccountInterface $account = N * permission. * * @return array + * An array of permissions. * * @see \Drupal\flag\Entity\Flag::getPermissions() */ @@ -61,17 +66,19 @@ public function getPermissions(); * once for all users. * * @return boolean + * TRUE if the flag is global, FALSE otherwise. */ public function isGlobal(); /** * Sets the flag as global or not. * - * @param $isGlobal + * @param bool $is_global * TRUE to mark the flag as global, FALSE for the default behavior. + * * @see \Drupal\flag\Entity\Flag::isGlobal() */ - public function setGlobal($isGlobal); + public function setGlobal($is_global); /** * {@inheritdoc} @@ -93,4 +100,4 @@ public function getPluginBags(); */ public function hasActionAccess($action, AccountInterface $account = NULL); -} \ No newline at end of file +} From 72cb77277879e6442da9fee078655848bdd3d453 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 25 Aug 2014 21:51:00 -0500 Subject: [PATCH 540/629] Fixed docblock and code style issues in FlagService.php. --- src/FlagService.php | 60 ++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index f58578b..c661685 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -24,21 +24,29 @@ class FlagService { /** + * The flag type plugin manager injected into the service. + * * @var FlagTypePluginManager */ private $flagTypeMgr; /** + * The event dispatcher injected into the service. + * * @var EventDispatcherInterface */ private $eventDispatcher; - /* + /** + * The entity query manager injected into the service. + * * @var QueryFactory */ private $entityQueryMgr; /** + * The current user injected into the service. + * * @var AccountInterface */ private $currentUser; @@ -51,27 +59,27 @@ class FlagService { /** * Constructor. * - * @param FlagTypePluginManager $flagType + * @param FlagTypePluginManager $flag_type * The flag type plugin manager. - * @param EventDispatcherInterface $eventDispatcher + * @param EventDispatcherInterface $event_dispatcher * The event dispatcher service. - * @param QueryFactory $entityQuery + * @param QueryFactory $entity_query * The entity query factory. - * @param AccountInterface $currentUser + * @param AccountInterface $current_user * The current user. - * @param EntityManagerInterface $entityManager + * @param EntityManagerInterface $entity_manager * The entity manager. */ - public function __construct(FlagTypePluginManager $flagType, - EventDispatcherInterface $eventDispatcher, - QueryFactory $entityQuery, - AccountInterface $currentUser, - EntityManagerInterface $entityManager) { - $this->flagTypeMgr = $flagType; - $this->eventDispatcher = $eventDispatcher; - $this->entityQueryMgr = $entityQuery; - $this->currentUser = $currentUser; - $this->entityMgr = $entityManager; + public function __construct(FlagTypePluginManager $flag_type, + EventDispatcherInterface $event_dispatcher, + QueryFactory $entity_query, + AccountInterface $current_user, + EntityManagerInterface $entity_manager) { + $this->flagTypeMgr = $flag_type; + $this->eventDispatcher = $event_dispatcher; + $this->entityQueryMgr = $entity_query; + $this->currentUser = $current_user; + $this->entityMgr = $entity_manager; } /** @@ -87,8 +95,7 @@ public function __construct(FlagTypePluginManager $flagType, * @see hook_flag_type_info() */ public function fetchDefinition($entity_type = NULL) { - //@todo Add caching, PLS! - + // @todo Add caching, PLS! if (!empty($entity_type)) { return $this->flagTypeMgr->getDefinition($entity_type); } @@ -103,7 +110,7 @@ public function fetchDefinition($entity_type = NULL) { * returned. * * @param string $entity_type - * (optional) The type of entity for which to load the flags. Usually 'node'. + * (optional) The type of entity for which to load the flags. * @param string $bundle * (optional) The bundle for which to load the flags. * @param AccountInterface $account @@ -152,6 +159,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ * @param AccountInterface $account * Optional. The account of the flagging user. If NULL, flaggings for any * user will be returned. + * * @return array * An array of flaggings. */ @@ -180,6 +188,7 @@ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, Accou * * @param int $flag_id * The ID of the flag to load. + * * @return FlagInterface|null * The flag entity. */ @@ -194,6 +203,7 @@ public function getFlagById($flag_id) { * The flag entity. * @param int $entity_id * The ID of the flaggable entity. + * * @return EntityInterface|null * The flaggable entity object. */ @@ -211,6 +221,7 @@ public function getFlaggableById(FlagInterface $flag, $entity_id) { * @param AccountInterface $account * Optional. The account of the user flagging the entity. If not given, * the current user is used. + * * @return FlaggingInterface|null * The flagging. */ @@ -245,8 +256,6 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou /** * Flags an entity given the flag ID and entity ID. * - * @api - * * @param int $flag_id * The ID of the flag. * @param int $entity_id @@ -254,8 +263,11 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou * @param AccountInterface $account * Optional. The account of user flagging the entity. If not given, the * current user is used. + * * @return FlaggingInterface|null * The flagging entity. + * + * @api */ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { @@ -271,16 +283,17 @@ public function flag($flag_id, $entity_id, AccountInterface $account = NULL) { /** * Unflags an entity given the flag ID and entity ID. * - * @api - * * @param int $flag_id * The ID of the flag. * @param int $entity_id * The ID of the flagged entity to unflag. * @param AccountInterface $account * Optional. The account of the user that created the flagging. + * * @return array * An array of flagging IDs to delete. + * + * @api */ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { if (empty($account)) { @@ -304,6 +317,7 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { * The entity to unflag. * @param AccountInterface $account * Optional. The account of the user that created the flagging. + * * @return array * An array of flagging IDs to delete. */ From 3db6ab71e8e3c67b7f7cdd5530a78d6c015c1ec9 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 25 Aug 2014 22:19:49 -0500 Subject: [PATCH 541/629] Fixed docblock issues in AJAXLinkController.php. --- src/Controller/AJAXLinkController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Controller/AJAXLinkController.php b/src/Controller/AJAXLinkController.php index 4ad3c95..9dd826d 100644 --- a/src/Controller/AJAXLinkController.php +++ b/src/Controller/AJAXLinkController.php @@ -8,7 +8,6 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\flag\FlagInterface; -use Drupal\flag\FlaggingInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\ReplaceCommand; @@ -30,6 +29,7 @@ class AJAXLinkController extends ControllerBase { * The flag ID. * @param int $entity_id * The flaggable ID. + * * @return AjaxResponse * The response object. * @@ -54,6 +54,7 @@ public function flag($flag_id, $entity_id) { * The flag ID. * @param int $entity_id * The entity ID to unflag. + * * @return AjaxResponse * The response object. * @@ -78,6 +79,7 @@ public function unflag($flag_id, $entity_id) { * The flag entity. * @param EntityInterface $entity * The entity object. + * * @return AjaxResponse * The response object. */ From 258b3a3b1056c9271b1c14a96ee7a9a24d904d6c Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 25 Aug 2014 22:22:36 -0500 Subject: [PATCH 542/629] Fixed docblock issues in ReloadLinkController.php. --- src/Controller/ReloadLinkController.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index fd30610..6a81532 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -41,6 +41,7 @@ public function __construct(FlagService $flag) { * * @param ContainerInterface $container * The container object. + * * @return ReloadLinkController * The reload link controller. */ @@ -57,6 +58,7 @@ public static function create(ContainerInterface $container) { * The flag ID. * @param int $entity_id * The flaggable ID. + * * @return \Symfony\Component\HttpFoundation\RedirectResponse * The response object. * @@ -79,6 +81,7 @@ public function flag($flag_id, $entity_id) { * The flag ID. * @param int $entity_id * The flagging ID. + * * @return \Symfony\Component\HttpFoundation\RedirectResponse * The response object. * @@ -97,4 +100,3 @@ public function unflag($flag_id, $entity_id) { } } - From 1103e967a79bf4271505bbcfcb8917db5f076217 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 25 Aug 2014 22:35:49 -0500 Subject: [PATCH 543/629] Fixed docblock issues in FlagListController.php. --- src/Controller/FlagListController.php | 13 ++++++++----- src/Controller/ReloadLinkController.php | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index f2b532d..16f6005 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -32,21 +32,24 @@ public function buildHeader() { * Creates a displayable string of roles that may use the flag. * * @param FlagInterface $flag + * The flag entity. + * * @return string + * An HTML sting of roles. */ protected function getFlagRoles(FlagInterface $flag) { $out = ''; - $allRoles = array(); + $all_roles = array(); foreach ($flag->getPermissions() as $perm => $pinfo) { $roles = user_roles(FALSE, $perm); foreach ($roles as $rid => $role) { - $allRoles[$rid] = $role->label(); + $all_roles[$rid] = $role->label(); } } - $out = implode(', ', $allRoles); + $out = implode(', ', $all_roles); if (empty($out)) { return 'None'; @@ -79,7 +82,7 @@ public function render() { $output = ""; - //@todo Move this too hook_help()? + // @todo Move this too hook_help()? if (!\Drupal::moduleHandler()->moduleExists('views')) { $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; } @@ -117,4 +120,4 @@ public function render() { return $build; } -} \ No newline at end of file +} diff --git a/src/Controller/ReloadLinkController.php b/src/Controller/ReloadLinkController.php index 6a81532..730928e 100644 --- a/src/Controller/ReloadLinkController.php +++ b/src/Controller/ReloadLinkController.php @@ -41,7 +41,7 @@ public function __construct(FlagService $flag) { * * @param ContainerInterface $container * The container object. - * + * * @return ReloadLinkController * The reload link controller. */ From ac7f079d8d32defeb652690cfe6f7f20564c7c17 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 27 Aug 2014 18:48:54 -0500 Subject: [PATCH 544/629] Fixed docblock for NodeFlagType. --- src/Plugin/Flag/NodeFlagType.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index a5176fd..9fc7a1e 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -10,10 +10,9 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class NodeFlagType - * @package Drupal\flag\Plugin\Flag + * Provides a flag type for all content entities. * - * Implements a node flag type. + * @package Drupal\flag\Plugin\Flag * * @FlagType( * id = "flagtype_node", From 84a5f91f01280a3a329d50e845da4d5b01e479fd Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 27 Aug 2014 22:20:01 -0500 Subject: [PATCH 545/629] Fixed docblock issues in CommentFlagType.php. --- src/Plugin/Flag/CommentFlagType.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index 690a1a3..2359eaa 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -10,10 +10,9 @@ use Drupal\Core\Form\FormStateInterface; /** - * Class CommentFlagType - * @package Drupal\flag\Plugin\Flag + * Provides a flag type for comments. * - * Implements a comment flag. + * @package Drupal\flag\Plugin\Flag * * @FlagType( * id = "flagtype_comment", @@ -102,4 +101,4 @@ public function typeAccessMultiple($entity_ids, $account) { public function getAccessAuthorSetting() { return $this->configuration['access_author']; } -} \ No newline at end of file +} From ac1eb7fe29943d31bb7d05ab7486fb6802dcfa85 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 27 Aug 2014 22:34:45 -0500 Subject: [PATCH 546/629] Corrected ending newline in Derivative/EntityFlagType.php. --- src/Plugin/Derivative/EntityFlagType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/Derivative/EntityFlagType.php b/src/Plugin/Derivative/EntityFlagType.php index 4472d5f..71156e1 100644 --- a/src/Plugin/Derivative/EntityFlagType.php +++ b/src/Plugin/Derivative/EntityFlagType.php @@ -48,4 +48,4 @@ public function getDerivativeDefinitions($base_plugin_def) { return $derivatives; } -} \ No newline at end of file +} From 1d60d3125293f9cbc543ece4c939a9aa2ff48c33 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 31 Aug 2014 19:59:51 -0500 Subject: [PATCH 547/629] Updated all array()s to []. --- flag.api.php | 15 +- flag.install | 44 +++--- flag.module | 22 +-- flag.views.inc | 118 ++++++++-------- src/ActionLinkPluginManager.php | 10 +- src/ActionLinkTypeBase.php | 11 +- src/ActionLinkTypePluginInterface.php | 3 +- src/Controller/FlagListController.php | 24 ++-- src/Entity/Flag.php | 68 ++++----- src/Entity/Flagging.php | 11 +- src/Event/FlagDeleteEvent.php | 4 +- src/Event/FlagEventBase.php | 7 +- src/FlagInterface.php | 4 +- src/FlagService.php | 32 ++--- src/FlagTypeBase.php | 19 +-- src/FlagTypePluginInterface.php | 22 ++- src/FlagTypePluginManager.php | 6 +- src/FlaggingAccessController.php | 2 +- src/Form/FlagAddPageForm.php | 50 +++---- src/Form/FlagDeleteForm.php | 8 +- src/Form/FlagFormBase.php | 132 +++++++++--------- src/Plugin/ActionLink/AJAXactionLink.php | 4 +- src/Plugin/ActionLink/ConfirmForm.php | 16 ++- src/Plugin/ActionLink/Reload.php | 2 +- src/Plugin/Derivative/EntityFlagType.php | 8 +- src/Plugin/Flag/CommentFlagType.php | 17 ++- src/Plugin/Flag/EntityFlagType.php | 28 ++-- src/Plugin/Flag/NodeFlagType.php | 24 ++-- src/Plugin/Flag/UserFlagType.php | 18 +-- .../argument/FlagViewsFlaggableArgument.php | 8 +- .../views/field/FlagViewsFlaggedField.php | 5 +- src/Plugin/views/field/FlagViewsLinkField.php | 10 +- src/Plugin/views/filter/FlagViewsFilter.php | 4 +- .../relationship/FlagViewsRelationship.php | 42 +++--- .../views/sort/FlagViewsSortFlagged.php | 4 +- src/Tests/FlagSimpleTest.php | 30 ++-- 36 files changed, 429 insertions(+), 403 deletions(-) diff --git a/flag.api.php b/flag.api.php index 6314d7c..645e206 100644 --- a/flag.api.php +++ b/flag.api.php @@ -67,6 +67,8 @@ function hook_flag_options_alter(array &$options, FlagInterface $flag) { * The id of the entity the user is trying to flag or unflag. * @param \Drupal\Core\Session\AccountInterface $account * The user account performing the action. + * @param bool $skip_permission_check + * TRUE to skip the permission check, FALSE otherwise. * @param \Drupal\flag\FlaggingInterface $flagging * The flagging entity. * @@ -79,19 +81,6 @@ function hook_flag_options_alter(array &$options, FlagInterface $flag) { function hook_flag_validate($action, FlagInterface $flag, $entity_id, AccountInterface $account, $skip_permission_check, FlaggingInterface $flagging) { - // We're only operating on the "test" flag, and users may always unflag. - if ($flag->name == 'test' && $action == 'flag') { - // Get all flags set by the current user. - $flags = flag_get_user_flags('node', NULL, $account->uid, $sid = NULL, $reset = FALSE); - // Check if this user has any flags of this type set. - if (isset($flags['test'])) { - $count = count($flags[$flag->name]); - if ($count >= 2) { - // Users may flag only 2 nodes with this flag. - return (array('access-denied' => t('You may only flag 2 nodes with the test flag.'))); - } - } - } } /** diff --git a/flag.install b/flag.install index 2af50ac..52e6bf5 100644 --- a/flag.install +++ b/flag.install @@ -9,47 +9,47 @@ * Implements hook_schema(). */ function flag_schema() { - $schema = array(); + $schema = []; - $schema['flag_counts'] = array( + $schema['flag_counts'] = [ 'description' => 'The number of times an item has been flagged.', - 'fields' => array( - 'fid' => array( + 'fields' => [ + 'fid' => [ 'type' => 'varchar', 'length' => '32', - ), - 'entity_type' => array( + ], + 'entity_type' => [ 'description' => 'The flag type, usually one of "node", "comment", "user".', 'type' => 'varchar', 'length' => '128', - ), - 'entity_id' => array( + ], + 'entity_id' => [ 'description' => 'The unique ID of the content, usually either the {cid}, {uid}, or {nid}.', 'type' => 'int', 'unsigned' => TRUE, 'disp-width' => '10', - ), - 'count' => array( + ], + 'count' => [ 'description' => 'The number of times this object has been flagged for this flag.', 'type' => 'int', 'unsigned' => TRUE, 'disp-width' => '10', - ), - 'last_updated' => array( + ], + 'last_updated' => [ 'description' => 'The UNIX time stamp representing when the flag was last updated.', 'type' => 'int', 'unsigned' => TRUE, 'disp-size' => 11, - ) - ), - 'primary key' => array('fid', 'entity_id'), - 'indexes' => array( - 'fid_entity_type' => array('fid', 'entity_type'), - 'entity_type_entity_id' => array('entity_type', 'entity_id'), - 'fid_count' => array('fid', 'count'), - 'fid_last_updated' => array('fid', 'last_updated'), - ), - ); + ], + ], + 'primary key' => ['fid', 'entity_id'], + 'indexes' => [ + 'fid_entity_type' => ['fid', 'entity_type'], + 'entity_type_entity_id' => ['entity_type', 'entity_id'], + 'fid_count' => ['fid', 'count'], + 'fid_last_updated' => ['fid', 'last_updated'], + ], + ]; return $schema; } diff --git a/flag.module b/flag.module index c4c8522..c5dbaa2 100644 --- a/flag.module +++ b/flag.module @@ -86,31 +86,31 @@ function flag_admin_menu_map() { return; } - $map = array(); - $map[FLAG_ADMIN_PATH . '/manage/%flag'] = array( + $map = []; + $map[FLAG_ADMIN_PATH . '/manage/%flag'] = [ 'parent' => FLAG_ADMIN_PATH, - 'arguments' => array( - array( + 'arguments' => [ + [ '%flag' => array_keys(flag_get_flags()), - ), - ), - ); + ], + ], + ]; if (\Drupal::moduleHandler()->moduleExists('field_ui')) { foreach (entity_get_info() as $obj_type => $info) { if ($obj_type == 'flagging') { foreach ($info['bundles'] as $bundle_name => $bundle_info) { if (isset($bundle_info['admin'])) { - $fields = array(); + $fields = []; foreach (field_info_instances($obj_type, $bundle_name) as $field) { $fields[] = $field['field_name']; } - $arguments = array( - '%flag' => array($bundle_name), + $arguments = [ + '%flag' => [$bundle_name], '%field_ui_menu' => $fields, - ); + ]; $path = $bundle_info['admin']['path']; $map["$path/fields/%field_ui_menu"]['parent'] = "$path/fields"; diff --git a/flag.views.inc b/flag.views.inc index 6552919..12e16a4 100644 --- a/flag.views.inc +++ b/flag.views.inc @@ -6,109 +6,106 @@ /** * Implements hook_views_data(). - * - * @return array - * The views provided by the flag module. */ function flag_views_data() { - $data = array(); + $data = []; $data['flagging']['table']['group'] = t('Flag'); $data['flag_counts']['table']['group'] = t('Flaggings'); - $data['flagging']['table']['join'] = array( - 'node' => array( + $data['flagging']['table']['join'] = [ + 'node' => [ 'type' => 'LEFT', 'left_field' => 'nid', 'field' => 'entity_id', - ), - ); + ], + ]; - $data['flagging']['uid'] = array( + $data['flagging']['uid'] = [ 'title' => t('User uid'), 'help' => t('The user that flagged an item. If you need more fields than the uid add the "Flags: User" relationship.'), - 'relationship' => array( + 'relationship' => [ 'base' => 'users', 'title' => t('User'), 'help' => t('Relate an item to the user that flagged it.'), 'id' => 'standard', 'label' => t('Flag user'), - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'numeric', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'numeric', - ), - 'field' => array( + ], + 'field' => [ 'id' => 'user', - ), - ); + ], + ]; - $data['flagging']['created'] = array( + $data['flagging']['created'] = [ 'title' => t('Last Flagged Time'), 'help' => t('Display latest time the content was flagged by a user.'), - 'field' => array( + 'field' => [ 'id' => 'date', - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'date', - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'date', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'date', - ), - ); + ], + ]; - $data['flagging']['entity_id'] = array( + $data['flagging']['entity_id'] = [ 'title' => t('Flaggable ID'), 'help' => t('The unique ID of the object that has been flagged.'), - 'sort' => array( + 'sort' => [ 'id' => 'standard', - ), - 'argument' => array( + ], + 'argument' => [ 'id' => 'FlagViewsFlaggableArgument', - ), - ); + ], + ]; // Flag content links. - $data['flagging']['link_flag'] = array( - 'field' => array( + $data['flagging']['link_flag'] = [ + 'field' => [ 'title' => t('Flag Links'), 'help' => t('Display flag/unflag link.'), 'id' => 'flag_link', - ), - ); + ], + ]; // Specialized is null/is not null filter. - $data['flagging']['flagged'] = array( + $data['flagging']['flagged'] = [ 'title' => t('Flagged'), 'real field' => 'uid', - 'field' => array( + 'field' => [ 'id' => 'flag_flagged', 'label' => t('Flagged'), 'help' => t('A boolean field to show whether the flag is set or not.'), - ), - 'filter' => array( + ], + 'filter' => [ 'id' => 'flag_filter', 'label' => t('Flagged'), 'help' => t('Filter to ensure content has or has not been flagged.'), - ), - 'sort' => array( + ], + 'sort' => [ 'id' => 'flag_sort', 'label' => t('Flagged'), 'help' => t('Sort by whether entities have or have not been flagged.'), - ), - ); + ], + ]; - $data['flag_counts']['count'] = array( + $data['flag_counts']['count'] = [ 'title' => t('Flag counter'), 'help' => t('The number of times a piece of content is flagged by any user.'), - 'field' => array( + 'field' => [ 'id' => 'numeric', // 'click sortable' => TRUE, - ), + ], /*'sort' => array( 'id' => 'groupby_numeric', ), @@ -118,15 +115,15 @@ function flag_views_data() { 'argument' => array( 'id' => 'numeric', ),*/ - ); + ]; - $data['flag_counts']['last_updated'] = array( + $data['flag_counts']['last_updated'] = [ 'title' => t('Time last flagged'), 'help' => t('The time a piece of content was most recently flagged by any user.'), - 'field' => array( + 'field' => [ 'id' => 'date', // 'click sortable' => TRUE, - ), + ], /*'sort' => array( 'id' => 'date', ), @@ -136,16 +133,13 @@ function flag_views_data() { 'argument' => array( 'id' => 'date', ),*/ - ); + ]; return $data; } /** * Implements hook_views_data_alter(). - * - * @param array $data - * The views data to alter. */ function flag_views_data_alter(array &$data) { $flags = \Drupal::service('flag')->getFlags(); @@ -162,10 +156,10 @@ function flag_views_data_alter(array &$data) { $base_table = $info->getDataTable(); } - $data[$base_table]['flag_content_rel'] = array( - 'title' => t('@entity_label flag', array('@entity_label' => $entity_type)), + $data[$base_table]['flag_content_rel'] = [ + 'title' => t('@entity_label flag', ['@entity_label' => $entity_type]), 'help' => t('Limit results to only those entity flagged by a certain flag; Or display information about the flag set on a entity.'), - 'relationship' => array( + 'relationship' => [ 'group' => t('Flag'), 'label' => t('Flags'), 'base' => 'flagging', @@ -173,8 +167,8 @@ function flag_views_data_alter(array &$data) { 'relationship field' => $info->getKey('id'), 'id' => 'flag_relationship', 'flaggable' => $entity_type, - ), - ); + ], + ]; } } diff --git a/src/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php index ad28530..b643fae 100644 --- a/src/ActionLinkPluginManager.php +++ b/src/ActionLinkPluginManager.php @@ -31,15 +31,17 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac /** * Get an array of all link type labels keyed by plugin ID. + * * @return array + * An array of all link type plugins. */ public function getAllLinkTypes() { - $linkTypes = array(); - foreach ($this->getDefinitions() as $pluginID => $pluginDef) { - $linkTypes[$pluginID] = t($pluginDef['label']); + $link_types = []; + foreach ($this->getDefinitions() as $plugin_id => $plugin_def) { + $link_types[$plugin_id] = t($plugin_def['label']); } - return $linkTypes; + return $link_types; } } diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 318b92a..6d6eb8c 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -49,7 +49,7 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi * A string containing the action name. * * @return string - * A string containing a route name. + * A string containing a route name. */ abstract public function routeName($action = NULL); @@ -57,10 +57,10 @@ abstract public function routeName($action = NULL); * {@inheritdoc} */ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) { - $parameters = array( + $parameters = [ 'flag_id' => $flag->id(), 'entity_id' => $entity->id(), - ); + ]; return new Url($this->routeName($action), $parameters); } @@ -95,7 +95,7 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity * {@inheritdoc} */ public function calculateDependencies() { - return array(); + return []; } /** @@ -107,6 +107,7 @@ public function calculateDependencies() { * The form array. * @param FormStateInterface $form_state * The form state. + * * @return array * The modified form array. */ @@ -151,7 +152,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form * The plugin configuration array. */ public function defaultConfiguration() { - return array(); + return []; } /** diff --git a/src/ActionLinkTypePluginInterface.php b/src/ActionLinkTypePluginInterface.php index 6a0f18b..0e79efc 100644 --- a/src/ActionLinkTypePluginInterface.php +++ b/src/ActionLinkTypePluginInterface.php @@ -42,8 +42,9 @@ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) * The flag entity. * @param EntityInterface $entity * The entity for which to create a flag link. + * * @return array - * A render array of the flag link. + * A render array of the flag link. */ public function renderLink($action, FlagInterface $flag, EntityInterface $entity); } diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 16f6005..df2d3cb 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -39,7 +39,7 @@ public function buildHeader() { */ protected function getFlagRoles(FlagInterface $flag) { $out = ''; - $all_roles = array(); + $all_roles = []; foreach ($flag->getPermissions() as $perm => $pinfo) { $roles = user_roles(FALSE, $perm); @@ -84,38 +84,38 @@ public function render() { // @todo Move this too hook_help()? if (!\Drupal::moduleHandler()->moduleExists('views')) { - $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', array('@views-url' => url('http://drupal.org/project/views'))) . '

'; + $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', ['@views-url' => url('http://drupal.org/project/views')]) . '

'; } else { $output .= '

'; - $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', array('@views-url' => url('admin/structure/views'))); + $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', ['@views-url' => url('admin/structure/views')]); if (flag_get_flag('bookmarks')) { - $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', array('@views-url' => url('admin/structure/views', array('query' => array('tag' => 'flag'))))); + $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', ['@views-url' => url('admin/structure/views', ['query' => ['tag' => 'flag']])]); } - $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', array('@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954')); + $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', ['@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954']); $output .= '

'; } if (!\Drupal::moduleHandler()->moduleExists('flag_actions')) { - $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules'))) . '

'; + $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', ['@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules')]) . '

'; } else { - $output .= '

' . t('Flagging an item may trigger actions.', array('@actions-url' => url(FLAG_ADMIN_PATH . '/actions'))) . '

'; + $output .= '

' . t('Flagging an item may trigger actions.', ['@actions-url' => url(FLAG_ADMIN_PATH . '/actions')]) . '

'; } if (!\Drupal::moduleHandler()->moduleExists('rules')) { - $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', array('@rules-url' => url('http://drupal.org/node/407070'))) . '

'; + $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', ['@rules-url' => url('http://drupal.org/node/407070')]) . '

'; } else { - $output .= '

' . t('Flagging an item may trigger rules.', array('@rules-url' => url('admin/config/workflow/rules'))) . '

'; + $output .= '

' . t('Flagging an item may trigger rules.', ['@rules-url' => url('admin/config/workflow/rules')]) . '

'; } - $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', array('@handbook-url' => 'http://drupal.org/handbook/modules/flag')) . '

'; + $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', ['@handbook-url' => 'http://drupal.org/handbook/modules/flag']) . '

'; - $build['markup'] = array( + $build['markup'] = [ '#type' => 'markup', '#markup' => $output, - ); + ]; return $build; } diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 769dce0..2dc01e8 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -94,7 +94,7 @@ class Flag extends ConfigEntityBase implements FlagInterface { * * @var array */ - public $types = array(); + public $types = []; /** * The text for the "flag this" link for this flag. @@ -163,7 +163,7 @@ class Flag extends ConfigEntityBase implements FlagInterface { * An array to store and load the FlagType plugin configuration. * @var array */ - protected $flagTypeConfig = array(); + protected $flagTypeConfig = []; /** * The ID of the ActionLink plugin. @@ -185,7 +185,7 @@ class Flag extends ConfigEntityBase implements FlagInterface { * * @var array */ - protected $linkTypeConfig = array(); + protected $linkTypeConfig = []; /** * The weight of the flag. @@ -195,7 +195,7 @@ class Flag extends ConfigEntityBase implements FlagInterface { public $weight = 0; /** - * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(); + * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct(). */ public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); @@ -251,16 +251,17 @@ public function isFlagged(EntityInterface $entity, AccountInterface $account = N * {@inheritdoc} */ public function getPluginBags() { - return array( + return [ 'flagTypeConfig' => $this->flagTypeBag, 'linkTypeConfig' => $this->linkTypeBag, - ); + ]; } /** * Get the flag type plugin for this flag. * - * @return FlagTypePluginInterface + * @return \Drupal\flag\FlagTypePluginInterface + * The flag type plugin for this flag. */ public function getFlagTypePlugin() { return $this->flagTypeBag->get($this->flag_type); @@ -269,12 +270,12 @@ public function getFlagTypePlugin() { /** * Set the flag type plugin. * - * @param string $pluginID + * @param string $plugin_id * A string containing the flag type plugin ID. */ - public function setFlagTypePlugin($pluginID) { - $this->flag_type = $pluginID; - //$this->flagTypeBag->addInstanceId($pluginID); + public function setFlagTypePlugin($plugin_id) { + $this->flag_type = $plugin_id; + // $this->flagTypeBag->addInstanceId($pluginID); // Workaround for https://www.drupal.org/node/2288805 $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), @@ -282,14 +283,15 @@ public function setFlagTypePlugin($pluginID) { // Get the entity type from the plugin definition. $plugin = $this->getFlagTypePlugin(); - $pluginDef = $plugin->getPluginDefinition(); - $this->entity_type = $pluginDef['entity_type']; + $plugin_def = $plugin->getPluginDefinition(); + $this->entity_type = $plugin_def['entity_type']; } /** * Get the link type plugin for this flag. * - * @return LinkTypePluginInterface + * @return \Drupal\flag\ActionLinkTypePluginInterface + * The link type plugin for the flag. */ public function getLinkTypePlugin() { return $this->linkTypeBag->get($this->link_type); @@ -298,13 +300,13 @@ public function getLinkTypePlugin() { /** * Set the link type plugin. * - * @param string $pluginID + * @param string $plugin_id * A string containing the link type plugin ID. */ - public function setlinkTypePlugin($pluginID) { - $this->link_type = $pluginID; + public function setlinkTypePlugin($plugin_id) { + $this->link_type = $plugin_id; - //$this->linkTypeBag->addInstanceId($pluginID); + // $this->linkTypeBag->addInstanceId($pluginID); // Workaround for https://www.drupal.org/node/2288805 $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), @@ -315,22 +317,22 @@ public function setlinkTypePlugin($pluginID) { * {@inheritdoc} */ public function getPermissions() { - return array( - "flag $this->id" => array( - 'title' => t('Flag %flag_title', array( + return [ + "flag $this->id" => [ + 'title' => t('Flag %flag_title', [ '%flag_title' => $this->label, - )), - ), - "unflag $this->id" => array( - 'title' => t('Unflag %flag_title', array( + ]), + ], + "unflag $this->id" => [ + 'title' => t('Unflag %flag_title', [ '%flag_title' => $this->label, - )), - ), - ); + ]), + ], + ]; } /** - * {@inheritdoc}. + * {@inheritdoc} */ public function hasActionAccess($action, AccountInterface $account = NULL) { if ($action === 'flag' || $action === 'unflag') { @@ -366,6 +368,7 @@ public function setGlobal($is_global = TRUE) { * Returns the flaggable entity type ID. * * @return string + * The flaggable entity ID. */ public function getFlaggableEntityType() { return $this->entity_type; @@ -386,6 +389,7 @@ public function preSave(EntityStorageInterface $storage) { $this->set('linkTypeConfig', $linkTypePlugin->getConfiguration()); */ // Reset the render cache for the entity. + // @todo Inject the entity manager into the object? \Drupal::entityManager() ->getViewBuilder($this->getFlaggableEntityType()) ->resetCache(); @@ -410,14 +414,14 @@ public static function preDelete(EntityStorageInterface $storage, array $entitie * {@inheritdoc} */ public function toArray() { - //@todo Do we need Flag::toArray() any longer? + // @todo Do we need Flag::toArray() any longer? $properties = parent::toArray(); - $names = array( + $names = [ 'flag_type', 'link_type', 'flagTypeConfig', 'linkTypeConfig', - ); + ]; foreach ($names as $name) { $properties[$name] = $this->get($name); diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 53e2ad4..aaa8f3c 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -35,7 +35,7 @@ class Flagging extends ContentEntityBase implements FlaggingInterface { /** * Gets the flag ID for the parent flag. * @return string - * The flag ID. + * The flag ID. */ public function getFlagId() { return $this->get('fid')->value; @@ -45,6 +45,7 @@ public function getFlagId() { * Gets the parent flag entity. * * @return \Drupal\Core\Entity\EntityInterface|\Drupal\flag\FlagInterface + * The flag related this this flagging. */ public function getFlag() { return entity_load('flag', $this->getFlagId()); @@ -53,6 +54,7 @@ public function getFlag() { /** * Gets the entity type of the flaggable. * @return string + * A string containing the flaggable type ID. */ public function getFlaggableType() { return $this->get('entity_type')->value; @@ -61,6 +63,7 @@ public function getFlaggableType() { /** * Gets the entity ID of the flaggable. * @return string + * A string containing the flaggable ID. */ public function getFlaggableId() { return $this->get('entity_id')->value; @@ -68,7 +71,9 @@ public function getFlaggableId() { /** * Gets the flaggable entity. + * * @return \Drupal\Core\Entity\EntityInterface + * The flaggable entity. */ public function getFlaggable() { return entity_load($this->getFlaggableType(), $this->getFlaggableId()); @@ -110,10 +115,10 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['uid'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('User ID')) ->setDescription(t('The user ID of the flagging user.')) - ->setSettings(array( + ->setSettings([ 'target_type' => 'user', 'default_value' => 0, - )); + ]); $fields['created'] = BaseFieldDefinition::create('created') ->setLabel(t('Created')) diff --git a/src/Event/FlagDeleteEvent.php b/src/Event/FlagDeleteEvent.php index 7946aaf..9c27fbc 100644 --- a/src/Event/FlagDeleteEvent.php +++ b/src/Event/FlagDeleteEvent.php @@ -15,10 +15,12 @@ class FlagDeleteEvent extends FlagEventBase { /** + * Build the flag delete event. + * * @param \Drupal\flag\FlagInterface $flag * The flag to delete. */ public function __construct(FlagInterface $flag) { parent::__construct($flag); } -} \ No newline at end of file +} diff --git a/src/Event/FlagEventBase.php b/src/Event/FlagEventBase.php index 8d23124..885d36c 100644 --- a/src/Event/FlagEventBase.php +++ b/src/Event/FlagEventBase.php @@ -12,7 +12,8 @@ /** * Base Event from which other flag event are defined. */ -abstract class FlagEventBase extends Event{ + +abstract class FlagEventBase extends Event { /** * The Flag in question. @@ -22,6 +23,8 @@ abstract class FlagEventBase extends Event{ protected $flag; /** + * Build the flag event class. + * * @param \Drupal\flag\FlagInterface $flag * The flag to be acted upon. */ @@ -29,4 +32,4 @@ public function __construct(FlagInterface $flag) { $this->flag = $flag; } -} \ No newline at end of file +} diff --git a/src/FlagInterface.php b/src/FlagInterface.php index bf9331b..48c2ffe 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -65,7 +65,7 @@ public function getPermissions(); * user being able to flag or unflag the entity, a global flag may be flagged * once for all users. * - * @return boolean + * @return bool * TRUE if the flag is global, FALSE otherwise. */ public function isGlobal(); @@ -74,7 +74,7 @@ public function isGlobal(); * Sets the flag as global or not. * * @param bool $is_global - * TRUE to mark the flag as global, FALSE for the default behavior. + * TRUE to mark the flag as global, FALSE for the default behavior. * * @see \Drupal\flag\Entity\Flag::isGlobal() */ diff --git a/src/FlagService.php b/src/FlagService.php index c661685..f2c228d 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -139,7 +139,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ return $flags; } - $filtered_flags = array(); + $filtered_flags = []; foreach ($flags as $flag) { if ($flag->hasActionAccess('flag ' . $flag->id(), $account) || $flag->hasActionAccess('unflag ' . $flag->id(), $account)) { $filtered_flags[] = $flag; @@ -175,7 +175,7 @@ public function getFlaggings(EntityInterface $entity, FlagInterface $flag, Accou ->condition('entity_id', $entity->id()) ->execute(); - $flaggings = array(); + $flaggings = []; foreach ($result as $flagging_id) { $flaggings[$flagging_id] = entity_load('flagging', $flagging_id); } @@ -230,13 +230,13 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $account = $this->currentUser; } - $flagging = entity_create('flagging', array( + $flagging = entity_create('flagging', [ 'type' => 'flag', 'uid' => $account->id(), 'fid' => $flag->id(), 'entity_id' => $entity->id(), 'entity_type' => $entity->getEntityTypeId(), - )); + ]); $flagging->save(); @@ -244,9 +244,9 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $this->entityMgr ->getViewBuilder($entity->getEntityTypeId()) - ->resetCache(array( + ->resetCache([ $entity, - )); + ]); $this->eventDispatcher->dispatch(FlagEvents::ENTITY_FLAGGED, new FlaggingEvent($flag, $entity, 'flag')); @@ -324,7 +324,7 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { public function unflagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { $this->eventDispatcher->dispatch(FlagEvents::ENTITY_UNFLAGGED, new FlaggingEvent($flag, $entity, 'unflag')); - $out = array(); + $out = []; $flaggings = $this->getFlaggings($entity, $flag, $account); foreach ($flaggings as $flagging) { $out[] = $flagging->id(); @@ -349,22 +349,22 @@ public function unflagByFlagging(FlaggingInterface $flagging) { * Increments count of flagged entities. * * @param FlagInterface $flag - * The flag to increment. + * The flag to increment. * @param EntityInterface $entity - * The flaggable entity. + * The flaggable entity. */ protected function incrementFlagCounts(FlagInterface $flag, EntityInterface $entity) { db_merge('flag_counts') - ->key(array( + ->key([ 'fid' => $flag->id(), 'entity_id' => $entity->id(), 'entity_type' => $entity->getEntityTypeId(), - )) - ->fields(array( + ]) + ->fields([ 'last_updated' => REQUEST_TIME, 'count' => 1, - )) - ->expression('count', 'count + :inc', array(':inc' => 1)) + ]) + ->expression('count', 'count + :inc', [':inc' => 1]) ->execute(); } @@ -372,13 +372,13 @@ protected function incrementFlagCounts(FlagInterface $flag, EntityInterface $ent * Reverts incrementation of count of flagged entities. * * @param FlagInterface $flag - * The flag to decrement. + * The flag to decrement. * @param EntityInterface $entity * The flaggable entity. */ protected function decrementFlagCounts(FlagInterface $flag, EntityInterface $entity) { $count_result = db_select('flag_counts') - ->fields(NULL, array('fid', 'entity_id', 'entity_type', 'count')) + ->fields(NULL, ['fid', 'entity_id', 'entity_type', 'count']) ->condition('fid', $flag->id()) ->condition('entity_id', $entity->id()) ->condition('entity_type', $entity->getEntityTypeId()) diff --git a/src/FlagTypeBase.php b/src/FlagTypeBase.php index 78c91c0..51d539b 100644 --- a/src/FlagTypeBase.php +++ b/src/FlagTypeBase.php @@ -33,14 +33,14 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi * The flag type's default plugin configuration. */ public function defaultConfiguration() { - return array(); + return []; } /** - * {@inhereitdoc} + * {@inheritdoc} */ public function calculateDependencies() { - return array(); + return []; } /** @@ -73,6 +73,7 @@ public function setConfiguration(array $configuration) { * The form array. * @param FormStateInterface $form_state * The form state. + * * @return array * The form array * @see \Drupal\flag\Form\FlagAddForm @@ -108,17 +109,9 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form } /** - * Implements access_multiple() implemented by each child class. - * - * @abstract - * - * @return array - * An array keyed by entity ids, whose values represent the access to the - * corresponding entity. The access value may be FALSE if access should be - * denied, or NULL (or not set) if there is no restriction to be made. It - * should NOT be TRUE. + * {@inheritdoc} */ public function typeAccessMultiple($entity_ids, $account) { - return array(); + return []; } } diff --git a/src/FlagTypePluginInterface.php b/src/FlagTypePluginInterface.php index 2a61bcd..2cb2e87 100644 --- a/src/FlagTypePluginInterface.php +++ b/src/FlagTypePluginInterface.php @@ -10,9 +10,27 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface; /** - * Interface FlagTypePluginInterface + * Provides an interface for all flag type plugins. + * * @package Drupal\flag */ interface FlagTypePluginInterface extends PluginFormInterface, ConfigurablePluginInterface { + + /** + * Implements access_multiple() implemented by each child class. + * + * @abstract + * + * @param array $entity_ids + * An array of entity IDs. + * @param \Drupal\Core\Session\AccountInterface $account + * An account to test for access. + * + * @return array + * An array keyed by entity ids, whose values represent the access to the + * corresponding entity. The access value may be FALSE if access should be + * denied, or NULL (or not set) if there is no restriction to be made. It + * should NOT be TRUE. + */ public function typeAccessMultiple($entity_ids, $account); -} \ No newline at end of file +} diff --git a/src/FlagTypePluginManager.php b/src/FlagTypePluginManager.php index 087f505..f3c0684 100644 --- a/src/FlagTypePluginManager.php +++ b/src/FlagTypePluginManager.php @@ -10,6 +10,10 @@ use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; +/** + * Class FlagTypePluginManager + * @package Drupal\flag + */ class FlagTypePluginManager extends DefaultPluginManager { /** @@ -37,7 +41,7 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac * Returns all flag types. */ public function getAllFlagTypes() { - $flag_types = array(); + $flag_types = []; foreach ($this->getDefinitions() as $plugin_id => $plugin_def) { $flag_types[$plugin_id] = $plugin_def['title']; diff --git a/src/FlaggingAccessController.php b/src/FlaggingAccessController.php index bc70b14..b239a70 100644 --- a/src/FlaggingAccessController.php +++ b/src/FlaggingAccessController.php @@ -52,4 +52,4 @@ public function checkUnflag(Request $request) { return AccessInterface::DENY; } -} \ No newline at end of file +} diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index a6a3a56..cefc2c9 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -34,65 +34,65 @@ public function getFormID() { */ public function buildForm(array $form, FormStateInterface $form_state) { - $form['flag_basic_info'] = array( + $form['flag_basic_info'] = [ '#type' => 'fieldset', '#title' => t('Flag basic info'), '#collapsable' => FALSE, '#weight' => -10, - ); - $form['flag_basic_info']['label'] = array( + ]; + $form['flag_basic_info']['label'] = [ '#type' => 'textfield', '#title' => t('Label'), '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), '#maxlength' => 255, '#required' => TRUE, '#weight' => -3, - ); - $form['flag_basic_info']['id'] = array( + ]; + $form['flag_basic_info']['id'] = [ '#type' => 'machine_name', '#title' => t('Machine name'), '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), '#weight' => -2, - '#machine_name' => array( + '#machine_name' => [ 'exists' => 'flag_load_by_id', - 'source' => array('flag_basic_info', 'label'), - ), - ); + 'source' => ['flag_basic_info', 'label'], + ], + ]; - $form['flag_type_info'] = array( + $form['flag_type_info'] = [ '#type' => 'fieldset', '#title' => t('Type and Action'), - '#attributes' => array( - 'class' => array('container-inline'), - ), - ); + '#attributes' => [ + 'class' => ['container-inline'], + ], + ]; - $form['flag_type_info']['flag_entity_type'] = array( + $form['flag_type_info']['flag_entity_type'] = [ '#type' => 'select', '#title' => t('Flag'), '#options' => \Drupal::service('plugin.manager.flag.flagtype')->getAllFlagTypes(), '#default_value' => 'flagtype_node', - ); + ]; - $form['flag_type_info']['flag_link_type'] = array( + $form['flag_type_info']['flag_link_type'] = [ '#type' => 'select', '#title' => t('using'), '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), '#default_value' => 'reload', - ); + ]; - $types = array(); + $types = []; $plugins = \Drupal::service('plugin.manager.flag.flagtype')->getDefinitions(); - $form['actions'] = array( + $form['actions'] = [ '#type' => 'actions', - ); + ]; - $form['actions']['submit'] = array( + $form['actions']['submit'] = [ '#type' => 'submit', '#value' => t('Continue'), - ); + ]; return $form; } @@ -115,7 +115,9 @@ public function validateForm(array &$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { - $form_state->setRedirect('flag.add', array('entity_type' => $form_state->getValue('flag_entity_type'))); + $form_state->setRedirect('flag.add', [ + 'entity_type' => $form_state->getValue('flag_entity_type') + ]); $tempstore = \Drupal::service('user.tempstore')->get('flag'); $tempstore->set('FlagAddPage', $form_state->getValues()); diff --git a/src/Form/FlagDeleteForm.php b/src/Form/FlagDeleteForm.php index d314af6..1042fa3 100644 --- a/src/Form/FlagDeleteForm.php +++ b/src/Form/FlagDeleteForm.php @@ -26,9 +26,9 @@ class FlagDeleteForm extends EntityConfirmFormBase { * {@inheritdoc} */ public function getQuestion() { - return t('Are you sure you want to delete the Flag %label?', array( + return t('Are you sure you want to delete the Flag %label?', [ '%label' => $this->entity->label(), - )); + ]); } /** @@ -50,9 +50,9 @@ public function getCancelUrl() { */ public function submit(array $form, FormStateInterface $form_state) { $this->entity->delete(); - drupal_set_message(t('Flag %label was deleted.', array( + drupal_set_message(t('Flag %label was deleted.', [ '%label' => $this->entity->label(), - ))); + ])); $form_state->setRedirectUrl($this->getCancelUrl()); } diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 3ac86a9..6663416 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -32,7 +32,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $form['#flag'] = $flag; $form['#flag_name'] = $flag->id; - $form['label'] = array( + $form['label'] = [ '#type' => 'textfield', '#title' => t('Label'), '#default_value' => $flag->label, @@ -40,91 +40,91 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#maxlength' => 255, '#required' => TRUE, '#weight' => -3, - ); + ]; - $form['id'] = array( + $form['id'] = [ '#type' => 'machine_name', '#title' => t('Machine name'), '#default_value' => $flag->id, '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), '#weight' => -2, - '#machine_name' => array( + '#machine_name' => [ 'exists' => 'flag_load_by_id', - ), + ], '#disabled' => !$flag->isNew(), - '#submit' => array(array($this, 'submitSelectPlugin')), + '#submit' => [[$this, 'submitSelectPlugin']], '#required' => TRUE, '#executes_submit_callback' => TRUE, - '#ajax' => array( - 'callback' => array($this, 'updateSelectedPluginType'), + '#ajax' => [ + 'callback' => [$this, 'updateSelectedPluginType'], 'wrapper' => 'monitoring-sensor-plugin', 'method' => 'replace', - ), - ); + ], + ]; - $form['is_global'] = array( + $form['is_global'] = [ '#type' => 'checkbox', '#title' => t('Global flag'), '#default_value' => $flag->isGlobal(), '#description' => t('If checked, flag is considered "global" and each entity is either flagged or not. If unchecked, each user has individual flags on entities.'), '#weight' => -1, - ); + ]; - $form['messages'] = array( + $form['messages'] = [ '#type' => 'fieldset', '#title' => t('Messages'), - ); + ]; - $form['messages']['flag_short'] = array( + $form['messages']['flag_short'] = [ '#type' => 'textfield', '#title' => t('Flag link text'), '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), '#description' => t('The text for the "flag this" link for this flag.'), '#required' => TRUE, - ); + ]; - $form['messages']['flag_long'] = array( + $form['messages']['flag_long'] = [ '#type' => 'textfield', '#title' => t('Flag link description'), '#default_value' => $flag->flag_long, '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'), - ); + ]; - $form['messages']['flag_message'] = array( + $form['messages']['flag_message'] = [ '#type' => 'textfield', '#title' => t('Flagged message'), '#default_value' => $flag->flag_message, '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - ); + ]; - $form['messages']['unflag_short'] = array( + $form['messages']['unflag_short'] = [ '#type' => 'textfield', '#title' => t('Unflag link text'), '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), '#description' => t('The text for the "unflag this" link for this flag.'), '#required' => TRUE, - ); + ]; - $form['messages']['unflag_long'] = array( + $form['messages']['unflag_long'] = [ '#type' => 'textfield', '#title' => t('Unflag link description'), '#default_value' => $flag->unflag_long, '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'), - ); + ]; - $form['messages']['unflag_message'] = array( + $form['messages']['unflag_message'] = [ '#type' => 'textfield', '#title' => t('Unflagged message'), '#default_value' => $flag->unflag_message, '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), - ); + ]; - $form['access'] = array( + $form['access'] = [ '#type' => 'fieldset', '#title' => t('Flag access'), '#tree' => FALSE, '#weight' => 10, - ); + ]; // Switch plugin type in case a different is chosen. @@ -138,7 +138,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t } // Flag classes will want to override this form element. - $form['access']['types'] = array( + $form['access']['types'] = [ '#type' => 'checkboxes', '#title' => t('Flaggable types'), '#options' => $entity_bundles, @@ -146,17 +146,17 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#description' => t('Check any sub-types that this flag may be used on.'), '#required' => TRUE, '#weight' => 10, - ); + ]; - $form['access']['unflag_denied_text'] = array( + $form['access']['unflag_denied_text'] = [ '#type' => 'textfield', '#title' => t('Unflag not allowed text'), '#default_value' => $flag->unflag_denied_text, '#description' => t('If a user is allowed to flag but not unflag, this text will be displayed after flagging. Often this is the past-tense of the link text, such as "flagged".'), '#weight' => -1, - ); + ]; - $form['display'] = array( + $form['display'] = [ '#type' => 'fieldset', '#title' => t('Display options'), '#description' => t('Flags are usually controlled through links that allow users to toggle their behavior. You can choose how users interact with flags by changing options here. It is legitimate to have none of the following checkboxes ticked, if, for some reason, you wish to place the the links on the page yourself.', array('@placement-url' => 'http://drupal.org/node/295383')), @@ -164,18 +164,18 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#weight' => 20, // @todo: Move flag_link_type_options_states() into controller? // '#after_build' => array('flag_link_type_options_states'), - ); + ]; - $form['display']['settings'] = array( + $form['display']['settings'] = [ '#type' => 'container', '#prefix' => '', '#weight' => 21, - ); + ]; $form = $flag_type_plugin->buildConfigurationForm($form, $form_state); - $form['display']['link_type'] = array( + $form['display']['link_type'] = [ '#type' => 'radios', '#title' => t('Link type'), '#options' => \Drupal::service('plugin.manager.flag.linktype')->getAllLinkTypes(), @@ -184,38 +184,38 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t // Give this a high weight so additions by the flag classes for entity- // specific options go above. '#weight' => 18, - '#attached' => array( - 'js' => array(drupal_get_path('module', 'flag') . '/theme/flag-admin.js'), - ), - '#attributes' => array( - 'class' => array('flag-link-options'), - ), - '#limit_validation_errors' => array(array('link_type')), - '#submit' => array(array($this, 'submitSelectPlugin')), + '#attached' => [ + 'js' => [drupal_get_path('module', 'flag') . '/theme/flag-admin.js'], + ], + '#attributes' => [ + 'class' => ['flag-link-options'], + ], + '#limit_validation_errors' => [['link_type']], + '#submit' => [[$this, 'submitSelectPlugin']], '#required' => TRUE, '#executes_submit_callback' => TRUE, - '#ajax' => array( - 'callback' => array($this, 'updateSelectedPluginType'), + '#ajax' => [ + 'callback' => [$this, 'updateSelectedPluginType'], 'wrapper' => 'link-type-settings-wrapper', 'event' => 'change', 'method' => 'replace', - ), - ); - $form['display']['link_type_submit'] = array( + ], + ]; + $form['display']['link_type_submit'] = [ '#type' => 'submit', '#value' => $this->t('Update'), - '#submit' => array(array($this, 'submitSelectPlugin')), + '#submit' => [[$this, 'submitSelectPlugin']], '#weight' => 20, - '#attributes' => array('class' => array('js-hide')), - ); + '#attributes' => ['class' => ['js-hide']], + ]; // Add the descriptions to each ratio button element. These attach to the // elements when FormAPI expands them. $action_link_plugin_defs = \Drupal::service('plugin.manager.flag.linktype')->getDefinitions(); foreach ($action_link_plugin_defs as $key => $info) { $form['display']['link_type'][$key]['#description'] = $info['description']; - $form['display']['link_type'][$key]['#submit'] = array(array($this, 'submitSelectPlugin')); + $form['display']['link_type'][$key]['#submit'] = [[$this, 'submitSelectPlugin']]; $form['display']['link_type'][$key]['#executes_submit_callback'] = TRUE; - $form['display']['link_type'][$key]['#limit_validation_errors'] = array(array('link_type')); + $form['display']['link_type'][$key]['#limit_validation_errors'] = [['link_type']]; } $action_link_plugin = $flag->getLinkTypePlugin(); @@ -238,8 +238,8 @@ public function submitSelectPlugin(array $form, FormStateInterface $form_state) $this->entity = $this->buildEntity($form, $form_state); $form_state['rebuild'] = TRUE; - // @todo: This is necessary because there are two different instances of the - // form object. Core should handle this. + // This is necessary because there are two different instances of the form + // object. Core should handle this. $form_state['build_info']['callback_object'] = $form_state['controller']; } @@ -252,7 +252,7 @@ public function validate(array $form, FormStateInterface $form_state) { $form_state['values']['label'] = trim($form_state['values']['label']); $form_values = $form_state['values']; - //@todo Move this to the validation method for the confirm form plugin + // @todo Move this to the validation method for the confirm form plugin /* if ($form_values['link_type'] == 'confirm') { if (empty($form_values['flag_confirmation'])) { @@ -282,12 +282,12 @@ public function save(array $form, FormStateInterface $form_state) { $status = $flag->save(); $url = $flag->url(); if ($status == SAVED_UPDATED) { - drupal_set_message(t('Flag %label has been updated.', array('%label' => $flag->label()))); - watchdog('flag', 'Flag %label has been updated.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); + drupal_set_message(t('Flag %label has been updated.', ['%label' => $flag->label()])); + watchdog('flag', 'Flag %label has been updated.', ['%label' => $flag->label()], WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); } else { - drupal_set_message(t('Flag %label has been added.', array('%label' => $flag->label()))); - watchdog('flag', 'Flag %label has been added.', array('%label' => $flag->label()), WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); + drupal_set_message(t('Flag %label has been added.', ['%label' => $flag->label()])); + watchdog('flag', 'Flag %label has been added.', ['%label' => $flag->label()], WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); } // We clear caches more vigorously if the flag was new. @@ -296,13 +296,13 @@ public function save(array $form, FormStateInterface $form_state) { // Save permissions. // This needs to be done after the flag cache has been cleared, so that // the new permissions are picked up by hook_permission(). - // This may need to move to the flag class when we implement extra permissions - // for different flag types: http://drupal.org/node/879988 + // This may need to move to the flag class when we implement extra + // permissions for different flag types: http://drupal.org/node/879988 - // If the flag machine name as changed, clean up all the obsolete permissions. + // If the flag ID has changed, clean up all the obsolete permissions. if ($flag->id != $form['#flag_name']) { $old_name = $form['#flag_name']; - $permissions = array("flag $old_name", "unflag $old_name"); + $permissions = ["flag $old_name", "unflag $old_name"]; foreach (array_keys(user_roles()) as $rid) { user_role_revoke_permissions($rid, $permissions); } diff --git a/src/Plugin/ActionLink/AJAXactionLink.php b/src/Plugin/ActionLink/AJAXactionLink.php index f1ebc78..6fea78f 100644 --- a/src/Plugin/ActionLink/AJAXactionLink.php +++ b/src/Plugin/ActionLink/AJAXactionLink.php @@ -22,7 +22,7 @@ * description = "An AJAX JavaScript request will be made without reloading the page." * ) */ -class AJAXactionLink extends ActionLinkTypeBase{ +class AJAXactionLink extends ActionLinkTypeBase { /** * {@inheritdoc} @@ -45,4 +45,4 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity return $render; } -} \ No newline at end of file +} diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index 3bbc7ec..d123e15 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -51,7 +51,7 @@ public function defaultConfiguration() { public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); - $form['display']['settings']['link_options_confirm'] = array( + $form['display']['settings']['link_options_confirm'] = [ '#type' => 'fieldset', '#title' => t('Options for the "Confirmation form" link type'), // Any "link type" provider module must put its settings fields inside @@ -59,25 +59,25 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta // the machine-name of the link type. This is necessary for the // radiobutton's JavaScript dependency feature to work. '#id' => 'link-options-confirm', - ); + ]; - $form['display']['settings']['link_options_confirm']['flag_confirmation'] = array( + $form['display']['settings']['link_options_confirm']['flag_confirmation'] = [ '#type' => 'textfield', '#title' => t('Flag confirmation message'), '#default_value' => $this->configuration['flag_confirmation'], '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, - ); + ]; - $form['display']['settings']['link_options_confirm']['unflag_confirmation'] = array( + $form['display']['settings']['link_options_confirm']['unflag_confirmation'] = [ '#type' => 'textfield', '#title' => t('Unflag confirmation message'), '#default_value' => $this->configuration['unflag_confirmation'], '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, - ); + ]; return $form; } @@ -94,6 +94,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * Returns the flag confirm form question when flagging. * @return string + * A string containing the flag question to display. */ public function getFlagQuestion() { return $this->configuration['flag_confirmation']; @@ -102,9 +103,10 @@ public function getFlagQuestion() { /** * Returns the flag confirm form question when unflagging. * @return string + * A string containing the unflag question to display. */ public function getUnflagQuestion() { return $this->configuration['unflag_confirmation']; } -} \ No newline at end of file +} diff --git a/src/Plugin/ActionLink/Reload.php b/src/Plugin/ActionLink/Reload.php index 6e1fecd..651125a 100644 --- a/src/Plugin/ActionLink/Reload.php +++ b/src/Plugin/ActionLink/Reload.php @@ -30,4 +30,4 @@ public function routeName($action = NULL) { return 'flag_link_flag.html'; } -} \ No newline at end of file +} diff --git a/src/Plugin/Derivative/EntityFlagType.php b/src/Plugin/Derivative/EntityFlagType.php index 71156e1..aa6d575 100644 --- a/src/Plugin/Derivative/EntityFlagType.php +++ b/src/Plugin/Derivative/EntityFlagType.php @@ -23,13 +23,13 @@ public function __construct($base_plugin_id, * * @var array */ - protected $ignoredEntities = array( + protected $ignoredEntities = [ 'flag_flag', 'flagging', 'node', 'user', 'comment', - ); + ]; /** * {@inheritdoc} @@ -40,10 +40,10 @@ public function getDerivativeDefinitions($base_plugin_def) { if (in_array($entity_id, $this->ignoredEntities)) { continue; } - $derivatives[$entity_id] = array( + $derivatives[$entity_id] = [ 'title' => $entity_type->getLabel(), 'entity_type' => $entity_id, - ) + $base_plugin_def; + ] + $base_plugin_def; } return $derivatives; diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index 2359eaa..5111362 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -6,7 +6,6 @@ namespace Drupal\flag\Plugin\Flag; -use Drupal\flag\Plugin\Flag\EntityFlagType; use Drupal\Core\Form\FormStateInterface; /** @@ -28,9 +27,9 @@ class CommentFlagType extends EntityFlagType { */ public function defaultConfiguration() { $options = parent::defaultConfiguration(); - $options += array( + $options += [ 'access_author' => '', - ); + ]; return $options; } @@ -43,19 +42,19 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta /* Options form extras for comment flags. */ - $form['access']['access_author'] = array( + $form['access']['access_author'] = [ '#type' => 'radios', '#title' => t('Flag access by content authorship'), - '#options' => array( + '#options' => [ '' => t('No additional restrictions'), 'comment_own' => t('Users may only flag own comments'), 'comment_others' => t('Users may only flag comments by others'), 'node_own' => t('Users may only flag comments of nodes they own'), 'node_others' => t('Users may only flag comments of nodes by others'), - ), + ], '#default_value' => $this->configuration['access_author'], '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), - ); + ]; return $form; } @@ -72,7 +71,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s * {@inheritdoc} */ public function typeAccessMultiple($entity_ids, $account) { - $access = array(); + $access = []; // If all subtypes are allowed, we have nothing to say here. if (empty($this->types)) { @@ -84,7 +83,7 @@ public function typeAccessMultiple($entity_ids, $account) { $query = db_select('comment', 'c'); $query->innerJoin('node', 'n', 'c.nid = n.nid'); $result = $query - ->fields('c', array('cid')) + ->fields('c', ['cid']) ->condition('c.cid', $entity_ids, 'IN') ->condition('n.type', $this->types, 'NOT IN') ->execute(); diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 433492d..0339c90 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -44,19 +44,19 @@ public function __construct(array $configuration, $plugin_id, array $plugin_defi */ public function defaultConfiguration() { $options = parent::defaultConfiguration(); - $options += array( + $options += [ // Output the flag in the entity links. // This is empty for now and will get overriden for different // entities. // @see hook_entity_view(). - 'show_in_links' => array(), + 'show_in_links' => [], // Output the flag as individual pseudofields. 'show_as_field' => FALSE, // Add a checkbox for the flag in the entity form. // @see hook_field_attach_form(). 'show_on_form' => FALSE, 'show_contextual_link' => FALSE, - ); + ]; return $options; } @@ -68,40 +68,40 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta /* Options form extras for the generic entity flag. */ // Add checkboxes to show flag link on each entity view mode. - $options = array(); - $defaults = array(); + $options = []; + $defaults = []; $view_modes = \Drupal::entityManager()->getViewModes($this->entity_type); foreach ($view_modes as $name => $view_mode) { - $options[$name] = t('Display on @name view mode', array('@name' => $view_mode['label'])); + $options[$name] = t('Display on @name view mode', ['@name' => $view_mode['label']]); $defaults[$name] = $this->showInLinks($name); } - $form['display']['show_in_links'] = array( + $form['display']['show_in_links'] = [ '#type' => 'checkboxes', '#title' => t('Display in entity links'), '#description' => t('Show the flag link with the other links on the entity.'), '#options' => $options, '#default_value' => $defaults, - ); + ]; - $form['display']['show_as_field'] = array( + $form['display']['show_as_field'] = [ '#type' => 'checkbox', '#title' => t('Display link as field'), '#description' => t('Show the flag link as a pseudofield, which can be ordered among other entity elements in the "Manage display" settings for the entity type.'), '#default_value' => $this->showAsField(), - ); + ]; /* if (empty($entity_info['fieldable'])) { $form['display']['show_as_field']['#disabled'] = TRUE; $form['display']['show_as_field']['#description'] = t("This entity type is not fieldable."); } */ - $form['display']['show_on_form'] = array( + $form['display']['show_on_form'] = [ '#type' => 'checkbox', '#title' => t('Display checkbox on entity edit form'), '#default_value' => $this->showOnForm(), '#weight' => 5, - ); + ]; // We use FieldAPI to put the flag checkbox on the entity form, so therefore // require the entity to be fielable. Since this is a potential DX @@ -113,14 +113,14 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['display']['show_on_form']['#description'] = t('This is only possible on entities which are fieldable.'); } */ - $form['display']['show_contextual_link'] = array( + $form['display']['show_contextual_link'] = [ '#type' => 'checkbox', '#title' => t('Display in contextual links'), '#default_value' => $this->showContextualLink(), '#description' => t('Note that not all entity types support contextual links.'), '#access' => \Drupal::moduleHandler()->moduleExists('contextual'), '#weight' => 10, - ); + ]; return $form; } diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index 9fc7a1e..6708562 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -29,10 +29,10 @@ class NodeFlagType extends EntityFlagType { public function defaultConfiguration() { $options = parent::defaultConfiguration(); // Use own display settings in the meanwhile. - $options += array( + $options += [ 'i18n' => 0, 'access_author' => '', - ); + ]; return $options; } @@ -44,31 +44,31 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta /* Options form extras for node flags. */ - $form['access']['access_author'] = array( + $form['access']['access_author'] = [ '#type' => 'radios', '#title' => t('Flag access by content authorship'), - '#options' => array( + '#options' => [ '' => t('No additional restrictions'), 'own' => t('Users may only flag content they own'), 'others' => t('Users may only flag content of others'), - ), + ], '#default_value' => $this->getAccessAuthorSetting(), '#description' => t("Restrict access to this flag based on the user's ownership of the content. Users must also have access to the flag through the role settings."), - ); + ]; // Support for i18n flagging requires Translation helpers module. - $form['i18n'] = array( + $form['i18n'] = [ '#type' => 'radios', '#title' => t('Internationalization'), - '#options' => array( + '#options' => [ '1' => t('Flag translations of content as a group'), '0' => t('Flag each translation of content separately'), - ), + ], '#default_value' => $this->getInternationalizationSetting(), '#description' => t('Flagging translations as a group effectively allows users to flag the original piece of content regardless of the translation they are viewing. Changing this setting will not update content that has been flagged already.'), '#access' => \Drupal::moduleHandler()->moduleExists('translation_helpers'), '#weight' => 5, - ); + ]; return $form; } @@ -86,7 +86,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s * {@inheritdoc} */ public function typeAccessMultiple($entity_ids, $account) { - $access = array(); + $access = []; // If all subtypes are allowed, we have nothing to say here. if (empty($this->types)) { @@ -95,7 +95,7 @@ public function typeAccessMultiple($entity_ids, $account) { // Ensure that only flaggable node types are granted access. This avoids a // node_load() on every type, usually done by applies_to_entity_id(). - $result = db_select('node', 'n')->fields('n', array('nid')) + $result = db_select('node', 'n')->fields('n', ['nid']) ->condition('nid', array_keys($entity_ids), 'IN') ->condition('type', $this->types, 'NOT IN') ->execute(); diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index f81d3ad..0eb4464 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -28,10 +28,10 @@ class UserFlagType extends FlagTypeBase { */ public function defaultConfiguration() { $options = parent::defaultConfiguration(); - $options += array( + $options += [ 'show_on_profile' => TRUE, 'access_uid' => '', - ); + ]; return $options; } @@ -43,26 +43,26 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta /* Options form extras for user flags */ - $form['access']['types'] = array( + $form['access']['types'] = [ // A user flag doesn't support node types. // TODO: Maybe support roles instead of node types. '#type' => 'value', '#value' => array(0 => 0), - ); - $form['access']['access_uid'] = array( + ]; + $form['access']['access_uid'] = [ '#type' => 'checkbox', '#title' => t('Users may flag themselves'), '#description' => t('Disabling this option may be useful when setting up a "friend" flag, when a user flagging themselves does not make sense.'), '#default_value' => $this->getAccessUidSetting() ? 0 : 1, - ); - $form['display']['show_on_profile'] = array( + ]; + $form['display']['show_on_profile'] = [ '#type' => 'checkbox', '#title' => t('Display link on user profile page'), '#description' => t('Show the link formatted as a user profile element.'), '#default_value' => $this->showOnProfile(), // Put this above 'show on entity'. '#weight' => -1, - ); + ]; return $form; } @@ -80,7 +80,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s * {@inheritdoc} */ public function typeAccessMultiple($entity_ids, $account) { - $access = array(); + $access = []; // Exclude anonymous. if (array_key_exists(0, $entity_ids)) { diff --git a/src/Plugin/views/argument/FlagViewsFlaggableArgument.php b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php index 8e7a4c1..84773e1 100644 --- a/src/Plugin/views/argument/FlagViewsFlaggableArgument.php +++ b/src/Plugin/views/argument/FlagViewsFlaggableArgument.php @@ -9,6 +9,8 @@ use Drupal\views\Plugin\views\argument\Numeric; use Drupal\Component\Utility\String; +use Drupal\Core\Database\Connection; +use Drupal\flag\FlagInterface; /** * Provides an argument handler to get the title of flaggble content. @@ -48,13 +50,15 @@ public function getFlag() { if (isset($this->view->relationship[$this->options['relationship']])) { return $this->view->relationship[$this->options['relationship']]->getFlag(); } + + return NULL; } /** * {@inheritdoc} */ public function titleQuery() { - $titles = array(); + $titles = []; $flag = $this->getFlag(); $entity_type = $flag->getFlaggableEntityType(); @@ -68,7 +72,7 @@ public function titleQuery() { ->execute(); foreach ($result as $title) { - $titles[] = String::check_plain($title->$entity_keys['label']); + $titles[] = String::checkPlain($title->$entity_keys['label']); } return $titles; diff --git a/src/Plugin/views/field/FlagViewsFlaggedField.php b/src/Plugin/views/field/FlagViewsFlaggedField.php index 64a3bbf..db222b5 100644 --- a/src/Plugin/views/field/FlagViewsFlaggedField.php +++ b/src/Plugin/views/field/FlagViewsFlaggedField.php @@ -24,6 +24,7 @@ */ class FlagViewsFlaggedField extends Boolean { + // @todo: Define the FlagViewsFlaggedField::formats variable? /** * {@inheritdoc} */ @@ -31,7 +32,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o parent::init($view, $display, $options); // Add our boolean labels. - $this->formats['flag'] = array(t('Flagged'), t('Not flagged')); + $this->formats['flag'] = [t('Flagged'), t('Not flagged')]; // TODO: We could probably lift the '(Un)Flagged message' strings from the // flag object, but a) we need to lift that from the relationship we're on // and b) they will not necessarily make sense in a static context. @@ -42,7 +43,7 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o */ protected function defineOptions() { $options = parent::defineOptions(); - $options['relationship'] = array('default' => 'flag_content_rel'); + $options['relationship'] = ['default' => 'flag_content_rel']; return $options; } diff --git a/src/Plugin/views/field/FlagViewsLinkField.php b/src/Plugin/views/field/FlagViewsLinkField.php index e34a1df..04894ec 100644 --- a/src/Plugin/views/field/FlagViewsLinkField.php +++ b/src/Plugin/views/field/FlagViewsLinkField.php @@ -36,6 +36,8 @@ public function getFlag() { if (isset($this->view->relationship[$this->options['relationship']])) { return $this->view->relationship[$this->options['relationship']]->getFlag(); } + + return NULL; } /** @@ -44,10 +46,10 @@ public function getFlag() { protected function defineOptions() { $options = parent::defineOptions(); - $options['text'] = array( + $options['text'] = [ 'default' => '', 'translatable' => TRUE, - ); + ]; // Set the default relationship handler. The first instance of the // FlagViewsRelationship should always have the id "flag_content_rel", so @@ -61,11 +63,11 @@ protected function defineOptions() { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $form['text'] = array( + $form['text'] = [ '#type' => 'textfield', '#title' => t('Text to display'), '#default_value' => $this->options['text'], - ); + ]; $form['relationship']['#default_value'] = $this->options['relationship']; diff --git a/src/Plugin/views/filter/FlagViewsFilter.php b/src/Plugin/views/filter/FlagViewsFilter.php index 1e96026..786cb10 100644 --- a/src/Plugin/views/filter/FlagViewsFilter.php +++ b/src/Plugin/views/filter/FlagViewsFilter.php @@ -35,12 +35,12 @@ public function defineOptions() { public function buildOptionsForm(&$form, FormStateInterface $form_state) { $form['value']['#type'] = 'radios'; $form['value']['#title'] = t('Status'); - $form['value']['#options'] = array( + $form['value']['#options'] = [ 1 => t('Flagged'), 0 => t('Not flagged'), // @todo Find out what in the hell filter type ALL is supposed to do. // 'All' => t('All'), - ); + ]; $form['value']['#default_value'] = empty($this->options['value']) ? '0' : $this->options['value']; $form['value']['#description'] = '

' . t('This filter is only needed if the relationship used has the "Include only flagged content" option unchecked. Otherwise, this filter is useless, because all records are already limited to flagged content.') . '

' . t('By choosing Not flagged, it is possible to create a list of content that is specifically not flagged.', array('@unflagged-url' => 'http://drupal.org/node/299335')) . '

'; diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 8cb8056..882fd2d 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -21,9 +21,9 @@ class FlagViewsRelationship extends RelationshipPluginBase { */ public function defineOptions() { $options = parent::defineOptions(); - $options['flag'] = array('default' => NULL); - $options['required'] = array('default' => 1); - $options['user_scope'] = array('default' => 'current'); + $options['flag'] = ['default' => NULL]; + $options['required'] = ['default' => 1]; + $options['user_scope'] = ['default' => 'current']; return $options; } @@ -43,12 +43,12 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { $default_value = current(array_keys($flags)); } - $form['flag'] = array( + $form['flag'] = [ '#type' => 'radios', '#title' => t('Flag'), '#default_value' => $default_value, '#required' => TRUE, - ); + ]; foreach ($flags as $fid => $flag) { if (!empty($flag)) { @@ -56,22 +56,22 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } } - $form['user_scope'] = array( + $form['user_scope'] = [ '#type' => 'radios', '#title' => t('By'), - '#options' => array('current' => t('Current user'), 'any' => t('Any user')), + '#options' => ['current' => t('Current user'), 'any' => t('Any user')], '#default_value' => $this->options['user_scope'], - ); + ]; $form['required']['#title'] = t('Include only flagged content'); - $form['required']['#description'] = t('If checked, only content that has this flag will be included. Leave unchecked to include all content; or, in combination with the Flagged filter, to limit the results to specifically unflagged content.', array('@unflagged-url' => 'http://drupal.org/node/299335')); + $form['required']['#description'] = t('If checked, only content that has this flag will be included. Leave unchecked to include all content; or, in combination with the Flagged filter, to limit the results to specifically unflagged content.', ['@unflagged-url' => 'http://drupal.org/node/299335']); if (!$form['flag']['#options']) { - $form = array( - 'error' => array( - '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', array('%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH))) . '

', - ), - ); + $form = [ + 'error' => [ + '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', ['%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH)]) . '

', + ], + ]; $form_state['no flags exist'] = TRUE; } } @@ -84,29 +84,29 @@ public function query() { return; } - $this->definition['extra'][] = array( + $this->definition['extra'][] = [ 'field' => 'fid', 'value' => $flag->id, 'numeric' => TRUE, - ); + ]; if ($this->options['user_scope'] == 'current' && !$flag->isGlobal()) { - $this->definition['extra'][] = array( + $this->definition['extra'][] = [ 'field' => 'uid', 'value' => '***CURRENT_USER***', 'numeric' => TRUE, - ); + ]; $flag_roles = user_roles(FALSE, "flag $flag->label"); if (isset($flag_roles[DRUPAL_ANONYMOUS_RID])) { // Disable page caching for anonymous users. drupal_page_is_cacheable(FALSE); // Add in the SID from Session API for anonymous users. - $this->definition['extra'][] = array( + $this->definition['extra'][] = [ 'field' => 'sid', 'value' => '***FLAG_CURRENT_USER_SID***', 'numeric' => TRUE, - ); + ]; } } @@ -116,7 +116,7 @@ public function query() { /** * Get the flag of the relationship. * - * @return FlagInterface|null + * @return \Drupal\flag\FlagInterface|null * The flag being selected by in the view. */ public function getFlag() { diff --git a/src/Plugin/views/sort/FlagViewsSortFlagged.php b/src/Plugin/views/sort/FlagViewsSortFlagged.php index ea2297f..186ee77 100644 --- a/src/Plugin/views/sort/FlagViewsSortFlagged.php +++ b/src/Plugin/views/sort/FlagViewsSortFlagged.php @@ -22,10 +22,10 @@ class FlagViewsSortFlagged extends SortPluginBase { * Should be overridden by classes that don't override sort_form. */ protected function sortOptions() { - return array( + return [ 'ASC' => t('Unflagged first'), 'DESC' => t('Flagged first'), - ); + ]; } /** diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 6784ab9..99b0538 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -65,10 +65,10 @@ class FlagSimpleTest extends WebTestBase { */ public function testFlagForm() { // Create and log in our user. - $this->adminUser = $this->drupalCreateUser(array( + $this->adminUser = $this->drupalCreateUser([ 'administer flags', 'administer node display', - )); + ]); $this->drupalLogin($this->adminUser); @@ -81,25 +81,25 @@ public function testFlagForm() { */ public function doTestFlagAdd() { // Create content type. - $this->drupalCreateContentType(array('type' => $this->nodeType)); + $this->drupalCreateContentType(['type' => $this->nodeType]); // Test with minimal value requirement. - $edit = array( + $edit = [ 'label' => $this->label, 'id' => $this->id, - ); + ]; $this->drupalPostForm('admin/structure/flags/add', $edit, t('Continue')); // Check for fieldset titles. $this->assertText(t('Messages')); $this->assertText(t('Flag access')); $this->assertText(t('Display options')); - $edit = array( + $edit = [ 'types[' . $this->nodeType . ']' => $this->nodeType, - ); + ]; $this->drupalPostForm(NULL, $edit, t('Create Flag')); - $this->assertText(t('Flag @this_label has been added.', array('@this_label' => $this->label))); + $this->assertText(t('Flag @this_label has been added.', ['@this_label' => $this->label])); // Continue test process. $this->doTestCreateNodeAndFlagIt(); @@ -109,7 +109,7 @@ public function doTestFlagAdd() { * Node creation and flagging. */ public function doTestCreateNodeAndFlagIt() { - $node = $this->drupalCreateNode(array('type' => $this->nodeType)); + $node = $this->drupalCreateNode(['type' => $this->nodeType]); $node_id = $node->id(); // Grant the flag permissions to the authenticated role, so that both @@ -156,10 +156,10 @@ public function doTestCreateNodeAndFlagIt() { public function doTestHideFlagLinkFromTeaser() { $this->drupalLogin($this->adminUser); - $node = $this->drupalCreateNode(array( + $node = $this->drupalCreateNode([ 'type' => $this->nodeType, 'promote' => TRUE, - )); + ]); $node_id = $node->id(); $node_title = $node->getTitle(); @@ -168,9 +168,9 @@ public function doTestHideFlagLinkFromTeaser() { $this->assertLink('Flag this item'); // Set flag format to hidden for teaser display and post form. - $edit = array( + $edit = [ 'fields[flag_' . $this->id . '][type]' => 'hidden', - ); + ]; $this->drupalPostForm('admin/structure/types/manage/' . $this->nodeType . '/display/teaser', $edit, t('Save')); @@ -189,7 +189,7 @@ public function doTestHideFlagLinkFromTeaser() { * Creates user, sets flags and deletes user. */ public function doTestUserDeletion() { - $node = $this->drupalCreateNode(array('type' => $this->nodeType)); + $node = $this->drupalCreateNode(['type' => $this->nodeType]); $node_id = $node->id(); // Create and login a new user. @@ -228,7 +228,7 @@ public function doTestUserDeletion() { * Flags a node using different user accounts and checks flag counts. */ public function doTestFlagCounts() { - $node = $this->drupalCreateNode(array('type' => $this->nodeType)); + $node = $this->drupalCreateNode(['type' => $this->nodeType]); $node_id = $node->id(); // Create and login user 1. From 54db51c5dc6da81fa88530895267aec67a3c09c4 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 31 Aug 2014 22:01:37 -0500 Subject: [PATCH 548/629] Fixed Flag annotation due to https://www.drupal.org/node/2200867 --- src/Entity/Flag.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 2dc01e8..06ad80b 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -23,7 +23,7 @@ * id = "flag", * label = @Translation("Flag"), * admin_permission = "administer flags", - * controllers = { + * handlers = { * "list_builder" = "Drupal\flag\Controller\FlagListController", * "form" = { * "add" = "Drupal\flag\Form\FlagAddForm", From ef6e1776225f25551b70b24c063c0867385acb97 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 1 Sep 2014 22:07:24 -0500 Subject: [PATCH 549/629] Added flag form validation using flag and link type plugins. --- src/ActionLinkPluginManager.php | 1 + src/Entity/Flag.php | 5 ++--- src/Entity/Flagging.php | 3 +++ src/Event/FlaggingEvent.php | 2 +- src/FlagTypeBase.php | 3 ++- src/FlagTypePluginInterface.php | 5 +++-- src/FlagTypePluginManager.php | 3 ++- src/Form/FlagFormBase.php | 20 +++----------------- src/Plugin/ActionLink/AJAXactionLink.php | 3 ++- src/Plugin/ActionLink/ConfirmForm.php | 22 ++++++++++++++++++++++ src/Plugin/ActionLink/Reload.php | 3 ++- src/Plugin/Flag/CommentFlagType.php | 3 ++- src/Plugin/Flag/NodeFlagType.php | 3 ++- src/Plugin/Flag/UserFlagType.php | 3 ++- 14 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php index b643fae..547fbc7 100644 --- a/src/ActionLinkPluginManager.php +++ b/src/ActionLinkPluginManager.php @@ -14,6 +14,7 @@ /** * Plugin manager for link types. + * * @package Drupal\flag * * @see Drupal\flag\ActionLinkTypeBase diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 06ad80b..ae8fca6 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -17,6 +17,7 @@ /** * Provides the Flag configuration entity. + * * @package Drupal\flag\Entity * * @ConfigEntityType( @@ -41,7 +42,6 @@ * "delete-form" = "flag.delete" * } * ) - * */ class Flag extends ConfigEntityBase implements FlagInterface { @@ -161,6 +161,7 @@ class Flag extends ConfigEntityBase implements FlagInterface { /** * An array to store and load the FlagType plugin configuration. + * * @var array */ protected $flagTypeConfig = []; @@ -276,7 +277,6 @@ public function getFlagTypePlugin() { public function setFlagTypePlugin($plugin_id) { $this->flag_type = $plugin_id; // $this->flagTypeBag->addInstanceId($pluginID); - // Workaround for https://www.drupal.org/node/2288805 $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), $this->flag_type, $this->flagTypeConfig); @@ -307,7 +307,6 @@ public function setlinkTypePlugin($plugin_id) { $this->link_type = $plugin_id; // $this->linkTypeBag->addInstanceId($pluginID); - // Workaround for https://www.drupal.org/node/2288805 $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), $this->link_type, $this->linkTypeConfig); diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index aaa8f3c..0362f56 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -34,6 +34,7 @@ class Flagging extends ContentEntityBase implements FlaggingInterface { /** * Gets the flag ID for the parent flag. + * * @return string * The flag ID. */ @@ -53,6 +54,7 @@ public function getFlag() { /** * Gets the entity type of the flaggable. + * * @return string * A string containing the flaggable type ID. */ @@ -62,6 +64,7 @@ public function getFlaggableType() { /** * Gets the entity ID of the flaggable. + * * @return string * A string containing the flaggable ID. */ diff --git a/src/Event/FlaggingEvent.php b/src/Event/FlaggingEvent.php index 2692416..5826d35 100644 --- a/src/Event/FlaggingEvent.php +++ b/src/Event/FlaggingEvent.php @@ -37,7 +37,7 @@ class FlaggingEvent extends FlagEventBase { * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to be acted upon. * @param string $action - * The action to perform. One of 'flag' or 'unflag' + * The action to perform. One of 'flag' or 'unflag'. */ public function __construct(FlagInterface $flag, EntityInterface $entity, $action) { parent::__construct($flag); diff --git a/src/FlagTypeBase.php b/src/FlagTypeBase.php index 51d539b..24f1652 100644 --- a/src/FlagTypeBase.php +++ b/src/FlagTypeBase.php @@ -10,6 +10,7 @@ use Drupal\Component\Plugin\PluginBase; use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Session\AccountInterface; /** * Provides a base class for flag type plugins. @@ -111,7 +112,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form /** * {@inheritdoc} */ - public function typeAccessMultiple($entity_ids, $account) { + public function typeAccessMultiple(array $entity_ids, AccountInterface $account) { return []; } } diff --git a/src/FlagTypePluginInterface.php b/src/FlagTypePluginInterface.php index 2cb2e87..0958348 100644 --- a/src/FlagTypePluginInterface.php +++ b/src/FlagTypePluginInterface.php @@ -8,6 +8,7 @@ use Drupal\Core\Plugin\PluginFormInterface; use Drupal\Component\Plugin\ConfigurablePluginInterface; +use Drupal\Core\Session\AccountInterface; /** * Provides an interface for all flag type plugins. @@ -23,7 +24,7 @@ interface FlagTypePluginInterface extends PluginFormInterface, ConfigurablePlugi * * @param array $entity_ids * An array of entity IDs. - * @param \Drupal\Core\Session\AccountInterface $account + * @param AccountInterface $account * An account to test for access. * * @return array @@ -32,5 +33,5 @@ interface FlagTypePluginInterface extends PluginFormInterface, ConfigurablePlugi * denied, or NULL (or not set) if there is no restriction to be made. It * should NOT be TRUE. */ - public function typeAccessMultiple($entity_ids, $account); + public function typeAccessMultiple(array $entity_ids, AccountInterface $account); } diff --git a/src/FlagTypePluginManager.php b/src/FlagTypePluginManager.php index f3c0684..16f9b0a 100644 --- a/src/FlagTypePluginManager.php +++ b/src/FlagTypePluginManager.php @@ -11,7 +11,8 @@ use Drupal\Core\Plugin\DefaultPluginManager; /** - * Class FlagTypePluginManager + * The plugin manager for flag type plugins. + * * @package Drupal\flag */ class FlagTypePluginManager extends DefaultPluginManager { diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 6663416..f996c05 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -249,24 +249,10 @@ public function submitSelectPlugin(array $form, FormStateInterface $form_state) public function validate(array $form, FormStateInterface $form_state) { parent::validate($form, $form_state); - $form_state['values']['label'] = trim($form_state['values']['label']); - $form_values = $form_state['values']; - // @todo Move this to the validation method for the confirm form plugin - /* - if ($form_values['link_type'] == 'confirm') { - if (empty($form_values['flag_confirmation'])) { - $this->setFormError('flag_confirmation', $form_state, $this->t('A flag confirmation message is required when using the confirmation link type.')); - } - if (empty($form_values['unflag_confirmation'])) { - $this->setFormError('unflag_confirmation', $form_state, $this->t('An unflag confirmation message is required when using the confirmation link type.')); - } - }*/ - /* - if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { - form_set_error('label', t('The flag name may only contain lowercase letters, underscores, and numbers.')); - } - */ + $flag = $this->entity; + $flag->getFlagTypePlugin()->validateConfigurationForm($form, $form_state); + $flag->getLinkTypePlugin()->validateConfigurationForm($form, $form_state); } /** diff --git a/src/Plugin/ActionLink/AJAXactionLink.php b/src/Plugin/ActionLink/AJAXactionLink.php index 6fea78f..814358c 100644 --- a/src/Plugin/ActionLink/AJAXactionLink.php +++ b/src/Plugin/ActionLink/AJAXactionLink.php @@ -19,7 +19,8 @@ * @ActionLinkType( * id = "AJAX Link", * label = @Translation("AJAX link"), - * description = "An AJAX JavaScript request will be made without reloading the page." + * description = "An AJAX JavaScript request will be made without reloading + * the page." * ) */ class AJAXactionLink extends ActionLinkTypeBase { diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index d123e15..960e6b8 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -82,6 +82,26 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta return $form; } + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + $form_values = $form_state['values']; + + if ($form_values['link_type'] == 'confirm') { + if (empty($form_values['flag_confirmation'])) { + $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the confirmation link type.'); + } + if (empty($form_values['unflag_confirmation'])) { + $form_state->setErrorByName('unflag_confirmation', 'An unflag confirmation message is required when using the confirmation link type.'); + } + } + + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { + $form_state->setErrorByName('label', 'The flag name may only contain lowercase letters, underscores, and numbers.'); + } + } + /** * {@inheritdoc} */ @@ -93,6 +113,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * Returns the flag confirm form question when flagging. + * * @return string * A string containing the flag question to display. */ @@ -102,6 +123,7 @@ public function getFlagQuestion() { /** * Returns the flag confirm form question when unflagging. + * * @return string * A string containing the unflag question to display. */ diff --git a/src/Plugin/ActionLink/Reload.php b/src/Plugin/ActionLink/Reload.php index 651125a..d3ec551 100644 --- a/src/Plugin/ActionLink/Reload.php +++ b/src/Plugin/ActionLink/Reload.php @@ -14,7 +14,8 @@ * @ActionLinkType( * id = "reload", * label = @Translation("Normal link"), - * description = "A normal non-JavaScript request will be made and the current page will be reloaded." + * description = "A normal non-JavaScript request will be made and the + * current page will be reloaded." * ) */ class Reload extends ActionLinkTypeBase { diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index 5111362..388afb0 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -7,6 +7,7 @@ namespace Drupal\flag\Plugin\Flag; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Session\AccountInterface; /** * Provides a flag type for comments. @@ -70,7 +71,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * {@inheritdoc} */ - public function typeAccessMultiple($entity_ids, $account) { + public function typeAccessMultiple(array $entity_ids, AccountInterface $account) { $access = []; // If all subtypes are allowed, we have nothing to say here. diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index 6708562..7ffaea7 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -6,6 +6,7 @@ namespace Drupal\flag\Plugin\Flag; +use Drupal\Core\Session\AccountInterface; use Drupal\flag\Plugin\Flag\EntityFlagType; use Drupal\Core\Form\FormStateInterface; @@ -85,7 +86,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * {@inheritdoc} */ - public function typeAccessMultiple($entity_ids, $account) { + public function typeAccessMultiple(array $entity_ids, AccountInterface $account) { $access = []; // If all subtypes are allowed, we have nothing to say here. diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 0eb4464..1e26bf6 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -6,6 +6,7 @@ namespace Drupal\flag\Plugin\Flag; +use Drupal\Core\Session\AccountInterface; use Drupal\flag\FlagTypeBase; use Drupal\Core\Form\FormStateInterface; @@ -79,7 +80,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * {@inheritdoc} */ - public function typeAccessMultiple($entity_ids, $account) { + public function typeAccessMultiple(array $entity_ids, AccountInterface $account) { $access = []; // Exclude anonymous. From b11dc4ce14b61f39989b9d836cf336cb324d8057 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 2 Sep 2014 21:40:34 -0500 Subject: [PATCH 550/629] Fixed broken EntityViewDisplay use statement. --- flag.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flag.module b/flag.module index c5dbaa2..9d37054 100644 --- a/flag.module +++ b/flag.module @@ -10,7 +10,7 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); -use Drupal\entity\Entity\EntityViewDisplay; +use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\flag\Entity\Flag; use Drupal\node\NodeInterface; use Drupal\Core\Entity\EntityInterface; From e262045cc52fc12a4e0be0abd46cc4fc3ee1ffbb Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Wed, 3 Sep 2014 21:31:50 +0200 Subject: [PATCH 551/629] Remove unecessary $form_state['controller'] hack --- flag.module | 2 +- src/Form/FlagFormBase.php | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/flag.module b/flag.module index 9d37054..2e05cb0 100644 --- a/flag.module +++ b/flag.module @@ -326,7 +326,7 @@ function flag_entity_extra_field_info() { */ function flag_form_node_type_form_alter(&$form, FormStateInterface $form_state, $form_id) { global $user; - $node_type = $form_state['controller']->getEntity(); + $node_type = $form_state->getFormObject()->getEntity(); $flags = \Drupal::service('flag')->getFlags('node', $node_type->id(), $user); foreach ($flags as $flag) { // @todo: Revisit when form functionality is implemented. diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index f996c05..673f2f1 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -191,7 +191,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t 'class' => ['flag-link-options'], ], '#limit_validation_errors' => [['link_type']], - '#submit' => [[$this, 'submitSelectPlugin']], + '#submit' => ['::submitSelectPlugin'], '#required' => TRUE, '#executes_submit_callback' => TRUE, '#ajax' => [ @@ -204,7 +204,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $form['display']['link_type_submit'] = [ '#type' => 'submit', '#value' => $this->t('Update'), - '#submit' => [[$this, 'submitSelectPlugin']], + '#submit' => ['::submitSelectPlugin'], '#weight' => 20, '#attributes' => ['class' => ['js-hide']], ]; @@ -237,10 +237,7 @@ public function updateSelectedPluginType($form, FormStateInterface $form_state) public function submitSelectPlugin(array $form, FormStateInterface $form_state) { $this->entity = $this->buildEntity($form, $form_state); - $form_state['rebuild'] = TRUE; - // This is necessary because there are two different instances of the form - // object. Core should handle this. - $form_state['build_info']['callback_object'] = $form_state['controller']; + $form_state->setRebuild(TRUE); } /** From 407c8c7c56a33c13912987202d4768bad68443d0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 3 Sep 2014 20:25:18 -0500 Subject: [PATCH 552/629] Updated more array()s to [] in flag.module. --- flag.module | 125 ++++++++++++++++++++++++---------------------------- 1 file changed, 57 insertions(+), 68 deletions(-) diff --git a/flag.module b/flag.module index 9d37054..9c4912e 100644 --- a/flag.module +++ b/flag.module @@ -236,12 +236,12 @@ function flag_help($route_name, RouteMatchInterface $route_match) { * Implements hook_permission(). */ function flag_permission() { - $permissions = array( - 'administer flags' => array( + $permissions = [ + 'administer flags' => [ 'title' => t('Administer flags'), 'description' => t('Create and edit site-wide flags.'), - ), - ); + ], + ]; $flags = \Drupal::service('flag')->getFlags(); // Provide flag and unflag permissions for each flag. @@ -269,22 +269,11 @@ function flag_form_user_admin_permissions_alter(&$form, FormStateInterface $form } } -/** - * Implements hook_flag_link(). - */ -function flag_flag_link($flag, $action, $entity_id) { - $token = flag_get_token($entity_id); - return array( - 'href' => 'flag/' . ($flag->link_type == 'confirm' ? 'confirm/' : '') . "$action/$flag->name/$entity_id", - 'query' => drupal_get_destination() + ($flag->link_type == 'confirm' ? array() : array('token' => $token)), - ); -} - /** * Implements hook_entity_extra_field_info(). */ function flag_entity_extra_field_info() { - $extra = array(); + $extra = []; $flag_service = \Drupal::service('flag'); $flags = $flag_service->getFlags(); foreach ($flags as $flag) { @@ -296,24 +285,24 @@ function flag_entity_extra_field_info() { foreach ($flag->types as $bundle_name) { if ($flagTypePlugin->showOnForm()) { - $extra[$flag->entity_type][$bundle_name]['form']['flag'] = array( + $extra[$flag->entity_type][$bundle_name]['form']['flag'] = [ 'label' => t('Flags'), 'description' => t('Checkboxes for toggling flags'), 'weight' => 10, - ); + ]; } if ($flagTypePlugin->showAsField()) { - $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $flag->id()] = array( + $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $flag->id()] = [ // It would be nicer to use % as the placeholder, but the label is // run through check_plain() by field_ui_display_overview_form() // (arguably incorrectly; see http://drupal.org/node/1991292). - 'label' => t('Flag: @title', array( + 'label' => t('Flag: @title', [ '@title' => $flag->label, - )), + ]), 'description' => t('Individual flag link'), 'weight' => 10, - ); + ]; } } } @@ -334,30 +323,30 @@ function flag_form_node_type_form_alter(&$form, FormStateInterface $form_state, // To be able to process node tokens in flag labels, we create a fake // node and store it in the flag's cache for replace_tokens() to find, // with a fake ID. - $flag->remember_entity('fake', (object) array( + $flag->remember_entity('fake', (object) [ 'nid' => NULL, 'type' => $form['#node_type']->type, 'title' => '', - )); + ]); $var = 'flag_' . $flag->name . '_default'; - $form['workflow']['flag'][$var] = array( + $form['workflow']['flag'][$var] = [ '#type' => 'checkbox', '#title' => $flag->get_label('flag_short', 'fake'), '#default_value' => variable_get($var . '_' . $form['#node_type']->type, 0), '#return_value' => 1, - ); + ]; } } if (isset($form['workflow']['flag'])) { - $form['workflow']['flag'] += array( + $form['workflow']['flag'] += [ '#type' => 'item', '#title' => t('Default flags'), - '#description' => t('Above are the flags you elected to show on the node editing form. You may specify their initial state here.', array('@flag-url' => url(FLAG_ADMIN_PATH))), + '#description' => t('Above are the flags you elected to show on the node editing form. You may specify their initial state here.', ['@flag-url' => url(FLAG_ADMIN_PATH)]), // Make the spacing a bit more compact: '#prefix' => '
', '#suffix' => '
', - ); + ]; } } @@ -426,15 +415,15 @@ function flag_field_attach_form($entity_type, $entity, &$form, FormStateInterfac continue; } - $form['flag'][$flag->name] = array( + $form['flag'][$flag->name] = [ '#type' => 'checkbox', '#title' => $flag->get_label('flag_short', $id), '#description' => $flag->get_label('flag_long', $id), '#default_value' => $flag_status, '#return_value' => 1, // Used by our drupalSetSummary() on vertical tabs. - '#attributes' => array('title' => $flag->get_title()), - ); + '#attributes' => ['title' => $flag->get_title()], + ]; // If the user does not have access to the flag, set as a value. if (!$access) { @@ -448,29 +437,29 @@ function flag_field_attach_form($entity_type, $entity, &$form, FormStateInterfac } if ($flags_in_form) { - $form['flag'] += array( + $form['flag'] += [ '#weight' => 1, '#tree' => TRUE, - ); + ]; } if ($flags_visible) { - $form['flag'] += array( + $form['flag'] += [ '#type' => 'fieldset', '#title' => t('Flags'), '#collapsible' => TRUE, - ); + ]; if ($entity_type == 'node') { // Turn the fieldset into a vertical tab. - $form['flag'] += array( + $form['flag'] += [ '#group' => 'additional_settings', - '#attributes' => array('class' => array('flag-fieldset')), - '#attached' => array( - 'js' => array( + '#attributes' => ['class' => ['flag-fieldset']], + '#attached' => [ + 'js' => [ 'vertical-tabs' => drupal_get_path('module', 'flag') . '/theme/flag-admin.js', - ), - ), - ); + ], + ], + ]; } } } @@ -674,11 +663,11 @@ function flag_node_translation_change($node) { $entity_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid']; foreach (flag_get_flags('node') as $flag) { if ($flag->i18n) { - db_update('flagging')->fields(array('entity_id' => $entity_id)) + db_update('flagging')->fields(['entity_id' => $entity_id]) ->condition('fid', $flag->fid) ->condition('entity_id', $node->translation_change['old_tnid']) ->execute(); - db_update('flag_counts')->fields(array('entity_id' => $entity_id)) + db_update('flag_counts')->fields(['entity_id' => $entity_id]) ->condition('fid', $flag->fid) ->condition('entity_id', $node->translation_change['old_tnid']) ->execute(); @@ -719,9 +708,9 @@ function flag_user_login($account) { // Migrate anonymous flags to this user's account. if (\Drupal::moduleHandler()->moduleExists('session_api') && ($sid = flag_get_sid(0))) { // Get a list of flagging IDs that will be moved over. - $duplicate_flaggings = array(); + $duplicate_flaggings = []; $flaggings = db_select('flagging', 'fc') - ->fields('fc', array('flagging_id', 'fid', 'entity_id')) + ->fields('fc', ['flagging_id', 'fid', 'entity_id']) ->condition('uid', 0) ->condition('sid', $sid) ->execute() @@ -734,10 +723,10 @@ function flag_user_login($account) { // subsequent db_delete() call. try { db_update('flagging') - ->fields(array( + ->fields([ 'uid' => $account->uid, 'sid' => 0, - )) + ]) ->condition('flagging_id', $flagging_id) ->execute(); } @@ -782,8 +771,8 @@ function flag_user_account_removal(UserInterface $account) { $query = db_select('flagging', 'fc'); $query->leftJoin('flag_counts', 'c', 'fc.entity_id = c.entity_id AND fc.entity_type = c.entity_type'); $result = $query - ->fields('fc', array('fid', 'entity_id')) - ->fields('c', array('count')) + ->fields('fc', ['fid', 'entity_id']) + ->fields('c', ['count']) ->condition('fc.uid', $account->id()) ->execute(); @@ -792,9 +781,9 @@ function flag_user_account_removal(UserInterface $account) { if ($flag_data->count > 0) { $flag_data->count--; db_update('flag_counts') - ->fields(array( + ->fields([ 'count' => $flag_data->count, - )) + ]) ->condition('fid', $flag_data->fid) ->condition('entity_id', $flag_data->entity_id) ->execute(); @@ -882,10 +871,10 @@ function flag_session_api_cleanup($arg = 'run') { function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { // This query can't use db_delete() because that doesn't support a // subquery: see http://drupal.org/node/1267508. - db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flag} WHERE entity_type = :entity_type)", array( + db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flag} WHERE entity_type = :entity_type)", [ ':bundle' => $bundle, ':entity_type' => $entity_type, - )); + ]); } /** @@ -1113,12 +1102,12 @@ function template_preprocess_flag(&$variables) { $variables['status'] = ($action == 'flag' ? 'unflagged' : 'flagged'); $variables['flag_name_css'] = $flag_css_name; - $variables['flag_wrapper_classes_array'] = array(); + $variables['flag_wrapper_classes_array'] = []; $variables['flag_wrapper_classes_array'][] = 'flag-wrapper'; $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name; $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name . '-' . $entity_id; - $variables['flag_classes_array'] = array(); + $variables['flag_classes_array'] = []; $variables['flag_classes_array'][] = 'flag'; if (isset($link['href'])) { $variables['flag_classes_array'][] = $variables['action'] . '-action'; @@ -1131,7 +1120,7 @@ function template_preprocess_flag(&$variables) { $link['attributes']['class'] = is_string($link['attributes']['class']) ? array_filter(explode(' ', $link['attributes']['class'])) : $link['attributes']['class']; $variables['flag_classes_array'] = array_merge($variables['flag_classes_array'], $link['attributes']['class']); } - $variables['message_classes_array'] = array(); + $variables['message_classes_array'] = []; if ($variables['after_flagging']) { $variables['message_classes_array'][] = 'flag-message'; if ($errors) { @@ -1172,7 +1161,7 @@ function template_process_flag(&$variables) { */ function _flag_get_flag_names() { $flags = flag_get_flags(); - $flag_names = array(); + $flag_names = []; foreach ($flags as $flag) { $flag_names[$flag->fid] = $flag->name; } @@ -1183,7 +1172,7 @@ function _flag_get_flag_names() { * Return an array of flag link types suitable for a select list or radios. */ function _flag_link_type_options() { - $options = array(); + $options = []; $types = flag_get_link_types(); foreach ($types as $type_name => $type) { $options[$type_name] = $type['title']; @@ -1195,7 +1184,7 @@ function _flag_link_type_options() { * Return an array of flag link type descriptions. */ function _flag_link_type_descriptions() { - $options = array(); + $options = []; $types = flag_get_link_types(); foreach ($types as $type_name => $type) { $options[$type_name] = $type['description']; @@ -1223,9 +1212,9 @@ function flag_get_entity_flag_counts($flag, $entity_type) { // We check to see if the flag count is already in the cache, // if it's not, run the query. if (!isset($counts[$flag->name][$entity_type])) { - $counts[$flag->name][$entity_type] = array(); + $counts[$flag->name][$entity_type] = []; $result = db_select('flagging', 'f') - ->fields('f', array('fid')) + ->fields('f', ['fid']) ->condition('fid', $flag->fid) ->condition('entity_type', $entity_type) ->countQuery() @@ -1254,9 +1243,9 @@ function flag_get_user_flag_counts($flag, $user) { // We check to see if the flag count is already in the cache, // if it's not, run the query. if (!isset($counts[$flag->name][$user->uid])) { - $counts[$flag->name][$user->uid] = array(); + $counts[$flag->name][$user->uid] = []; $result = db_select('flagging', 'f') - ->fields('f', array('fid')) + ->fields('f', ['fid']) ->condition('fid', $flag->fid) ->condition('uid', $user->uid) ->countQuery() @@ -1283,12 +1272,12 @@ function flag_get_counts($entity_type, $entity_id) { $counts = &drupal_static(__FUNCTION__); if (!isset($counts[$entity_type][$entity_id])) { - $counts[$entity_type][$entity_id] = array(); + $counts[$entity_type][$entity_id] = []; $query = db_select('flag', 'f'); $query->leftJoin('flag_counts', 'fc', 'f.fid = fc.fid'); $result = $query - ->fields('f', array('name')) - ->fields('fc', array('count')) + ->fields('f', ['name']) + ->fields('fc', ['count']) ->condition('fc.entity_type', $entity_type) ->condition('fc.entity_id', $entity_id) ->execute(); From 2859a2eaddebf0bee9ccaeb3f4243c6aab218167 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 3 Sep 2014 20:30:41 -0500 Subject: [PATCH 553/629] Removed flag_get_flag(). --- flag.api.php | 2 +- flag.module | 32 --------------------------- src/Controller/FlagListController.php | 2 +- 3 files changed, 2 insertions(+), 34 deletions(-) diff --git a/flag.api.php b/flag.api.php index 645e206..5017c5f 100644 --- a/flag.api.php +++ b/flag.api.php @@ -31,7 +31,7 @@ function hook_flag_type_info_alter(array &$definitions) { * @param \Drupal\flag\FlagInterface $flag * The flag to alter. * - * @see flag_get_flags() + * @see \Drupal\flag\FlagService::getFlags() */ function hook_flag_alter(FlagInterface &$flag) { diff --git a/flag.module b/flag.module index 9c4912e..3642cc1 100644 --- a/flag.module +++ b/flag.module @@ -1316,38 +1316,6 @@ function flag_get_flag_counts($flag_name, $reset = FALSE) { return $counts[$flag_name]; } -/** - * Load a single flag either by name or by flag ID. - * - * @param $name - * (optional) The flag name. - * @param $fid - * (optional) The the flag id. - * - * @return - * The flag object, or FALSE if no matching flag was found. - */ -function flag_get_flag($name = NULL, $fid = NULL) { - $flags = flag_get_flags(); - if (isset($name)) { - if (isset($flags[$name])) { - return $flags[$name]; - } - } - elseif (isset($fid)) { - foreach ($flags as $flag) { - if ($flag->fid == $fid) { - return $flag; - } - } - } - return FALSE; -} - -function flag_load_by_id($id) { - return entity_load('flag', $id); -} - /** * List all flags available. * diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index df2d3cb..872cae4 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -89,7 +89,7 @@ public function render() { else { $output .= '

'; $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', ['@views-url' => url('admin/structure/views')]); - if (flag_get_flag('bookmarks')) { + if (\Drupal::service('flag')->getFlagById('bookmarks')) { $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', ['@views-url' => url('admin/structure/views', ['query' => ['tag' => 'flag']])]); } $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', ['@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954']); From 372c7e83ecd70a760dcca0295095fc5c85d50f0f Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 3 Sep 2014 20:50:51 -0500 Subject: [PATCH 554/629] Removed flag_node_insert(), flag_node_update(), and flag_save_flag(). --- flag.module | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/flag.module b/flag.module index 3642cc1..7345124 100644 --- a/flag.module +++ b/flag.module @@ -585,46 +585,6 @@ function flag_entity_build_defaults_alter(array &$build, EntityInterface $entity return $build; } -/** - * Implements hook_node_insert(). - */ -function flag_node_insert($node) { - flag_node_save($node); -} - -/** - * Implements hook_node_update(). - */ -function flag_node_update($node) { - flag_node_save($node); -} - -/** - * Shared saving routine between flag_node_insert() and flag_node_update(). - */ -function flag_node_save($node) { - // Response to the flag checkboxes added to the form in flag_form_alter(). - $remembered = FALSE; - if (isset($node->flag)) { - foreach ($node->flag as $name => $state) { - $flag = flag_get_flag($name); - // Flagging may trigger actions. We want actions to get the current - // node, not a stale database-loaded one: - if (!$remembered) { - $flag->remember_entity($node->nid, $node); - // Actions may modify a node, and we don't want to overwrite this - // modification: - $remembered = TRUE; - } - - $action = $state ? 'flag' : 'unflag'; - // Pass TRUE for $skip_permission_check so that flags that have been - // passed through as hidden form values are saved. - $flag->flag($action, $node->nid, NULL, TRUE); - } - } -} - /** * Implements hook_entity_delete(). */ From bfca8a3c3325ff2493d8d7832911939fd8b9d3a4 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 3 Sep 2014 20:51:28 -0500 Subject: [PATCH 555/629] Fixed broken machine name validation in flag forms, replaced with fancy OOP version. --- src/Form/FlagAddPageForm.php | 16 +++++++++++++++- src/Form/FlagFormBase.php | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index cefc2c9..6eaecf6 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -54,7 +54,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), '#weight' => -2, '#machine_name' => [ - 'exists' => 'flag_load_by_id', + 'exists' => [$this, 'exists'], 'source' => ['flag_basic_info', 'label'], ], ]; @@ -122,4 +122,18 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $tempstore = \Drupal::service('user.tempstore')->get('flag'); $tempstore->set('FlagAddPage', $form_state->getValues()); } + + /** + * Determines if the flag already exists. + * + * @param string $id + * The flag ID + * + * @return bool + * TRUE if the flag exists, FALSE otherwise. + */ + public function exists($id) { + // @todo: Make this injected like ActionFormBase::exists(). + return entity_load('flag', $id); + } } diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index f996c05..7cd4b58 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -49,7 +49,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#description' => t('The machine-name for this flag. It may be up to 32 characters long and may only contain lowercase letters, underscores, and numbers. It will be used in URLs and in all API calls.'), '#weight' => -2, '#machine_name' => [ - 'exists' => 'flag_load_by_id', + 'exists' => [$this, 'exists'], ], '#disabled' => !$flag->isNew(), '#submit' => [[$this, 'submitSelectPlugin']], @@ -316,4 +316,18 @@ public function delete(array $form, FormStateInterface $form_state) { $form_state->setRedirect('flag_list'); } + /** + * Determines if the flag already exists. + * + * @param string $id + * The flag ID + * + * @return bool + * TRUE if the flag exists, FALSE otherwise. + */ + public function exists($id) { + // @todo: Make this injected like ActionFormBase::exists(). + return entity_load('flag', $id); + } + } From dfcac131c9dc4f4cc039591215a73f89232ce39a Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 3 Sep 2014 22:34:47 -0500 Subject: [PATCH 556/629] Removed dead hooks from flag.module, augmented flagging retrieval in FlagService. --- flag.module | 398 -------------------------------------------- src/FlagService.php | 60 +++++-- 2 files changed, 49 insertions(+), 409 deletions(-) diff --git a/flag.module b/flag.module index 7345124..9baa387 100644 --- a/flag.module +++ b/flag.module @@ -78,52 +78,6 @@ function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { $query->condition('f.name', $value, $operator); }*/ -/** - * Implements hook_admin_menu_map(). - */ -function flag_admin_menu_map() { - if (!user_access('administer flags')) { - return; - } - - $map = []; - $map[FLAG_ADMIN_PATH . '/manage/%flag'] = [ - 'parent' => FLAG_ADMIN_PATH, - 'arguments' => [ - [ - '%flag' => array_keys(flag_get_flags()), - ], - ], - ]; - - if (\Drupal::moduleHandler()->moduleExists('field_ui')) { - foreach (entity_get_info() as $obj_type => $info) { - if ($obj_type == 'flagging') { - foreach ($info['bundles'] as $bundle_name => $bundle_info) { - if (isset($bundle_info['admin'])) { - $fields = []; - - foreach (field_info_instances($obj_type, $bundle_name) as $field) { - $fields[] = $field['field_name']; - } - - $arguments = [ - '%flag' => [$bundle_name], - '%field_ui_menu' => $fields, - ]; - - $path = $bundle_info['admin']['path']; - $map["$path/fields/%field_ui_menu"]['parent'] = "$path/fields"; - $map["$path/fields/%field_ui_menu"]['arguments'][] = $arguments; - } - } - } - } - } - - return $map; -} - /** * Menu loader for '%flag' arguments. * @@ -598,44 +552,6 @@ function flag_entity_delete(EntityInterface $entity) { // _flag_entity_delete($entity->getFlaggableEntityType(), $entity->id()); } -/** - * Implements hook_node_delete(). - */ -function flag_node_delete($node) { - foreach (flag_get_flags('node') as $flag) { - // @todo: Update comments below and perhaps also flag_node_translation_change? - // If the flag is being tracked by translation set and the node is part - // of a translation set, don't delete the flagging record. - // Instead, data will be updated in hook_node_translation_change(), below. - _flag_entity_delete('node', $node->id()); - } -} - -/** - * Implements hook_node_translation_change(). - * - * (Hook provided by translation_helpers module.) - */ -function flag_node_translation_change($node) { - if (isset($node->translation_change)) { - // If there is only one node remaining, track by nid rather than tnid. - // Otherwise, use the new tnid. - $entity_id = $node->translation_change['new_tnid'] == 0 ? $node->translation_change['remaining_nid'] : $node->translation_change['new_tnid']; - foreach (flag_get_flags('node') as $flag) { - if ($flag->i18n) { - db_update('flagging')->fields(['entity_id' => $entity_id]) - ->condition('fid', $flag->fid) - ->condition('entity_id', $node->translation_change['old_tnid']) - ->execute(); - db_update('flag_counts')->fields(['entity_id' => $entity_id]) - ->condition('fid', $flag->fid) - ->condition('entity_id', $node->translation_change['old_tnid']) - ->execute(); - } - } - } -} - /** * Deletes flagging records for the entity. * @@ -795,48 +711,6 @@ function flag_user_view($account, $view_mode) { } }*/ -/** - * Implements hook_session_api_cleanup(). - * - * Clear out anonymous user flaggings during Session API cleanup. - */ -function flag_session_api_cleanup($arg = 'run') { - // Session API 1.1 version: - if ($arg == 'run') { - $query = db_select('flagging', 'fc'); - $query->leftJoin('session_api', 's', 'fc.sid = s.sid'); - $result = $query - ->fields('fc', array('sid')) - ->condition('fc.sid', 0, '<>') - ->isNull('s.sid') - ->execute(); - foreach ($result as $row) { - db_delete('flagging') - ->condition('sid', $row->sid) - ->execute(); - } - } - // Session API 1.2+ version. - elseif (is_array($arg)) { - $outdated_sids = $arg; - db_delete('flagging')->condition('sid', $outdated_sids, 'IN')->execute(); - } -} - -/** - * Implements hook_field_attach_delete_bundle(). - * - * Delete any flags' applicability to the deleted bundle. - */ -function flag_field_attach_delete_bundle($entity_type, $bundle, $instances) { - // This query can't use db_delete() because that doesn't support a - // subquery: see http://drupal.org/node/1267508. - db_query("DELETE FROM {flag_types} WHERE type = :bundle AND fid IN (SELECT fid FROM {flag} WHERE entity_type = :entity_type)", [ - ':bundle' => $bundle, - ':entity_type' => $entity_type, - ]); -} - /** * Implements hook_flag_access(). */ @@ -1116,42 +990,6 @@ function template_process_flag(&$variables) { $variables['message_classes'] = implode(' ', $variables['message_classes_array']); } -/** - * Return an array of flag names keyed by fid. - */ -function _flag_get_flag_names() { - $flags = flag_get_flags(); - $flag_names = []; - foreach ($flags as $flag) { - $flag_names[$flag->fid] = $flag->name; - } - return $flag_names; -} - -/** - * Return an array of flag link types suitable for a select list or radios. - */ -function _flag_link_type_options() { - $options = []; - $types = flag_get_link_types(); - foreach ($types as $type_name => $type) { - $options[$type_name] = $type['title']; - } - return $options; -} - -/** - * Return an array of flag link type descriptions. - */ -function _flag_link_type_descriptions() { - $options = []; - $types = flag_get_link_types(); - foreach ($types as $type_name => $type) { - $options[$type_name] = $type['description']; - } - return $options; -} - // --------------------------------------------------------------------------- // Non-Views public API @@ -1372,129 +1210,6 @@ function flag_get_flag_flagging_data($flag_name) { return $result->fetchAllAssoc('flagging_id'); } -/** - * Find what a user has flagged, either a single entity or on the entire site. - * - * @param $entity_type - * The type of entity that will be retrieved. Usually 'node'. - * @param $entity_id - * (optional) The entity ID to check for flagging. If none given, all - * entities flagged by this user will be returned. - * @param $uid - * (optional) The user ID whose flags we're checking. If none given, the - * current user will be used. - * @param $sid - * (optional) The user SID (provided by Session API) whose flags we're - * checking. If none given, the current user will be used. The SID is 0 for - * logged in users. - * - * @return - * If returning a single item's flags (that is, when $entity_id isn't NULL), - * an array of the structure - * [flag_name] => (flagging_id => [flagging_id], uid => [uid], entity_id => [entity_id], timestamp => [timestamp], ...) - * - * If returning all items' flags, an array of arrays for each flag: - * [flag_name] => [entity_id] => Object from above. - * - */ -function flag_get_user_flags($entity_type, $entity_id = NULL, $uid = NULL, $sid = NULL) { - $flagged_content = &drupal_static(__FUNCTION__); - - $uid = !isset($uid) ? $GLOBALS['user']->uid : $uid; - $sid = !isset($sid) ? flag_get_sid($uid) : $sid; - - if (isset($entity_id)) { - if (!isset($flagged_content[$uid][$sid][$entity_type][$entity_id])) { - $flag_names = _flag_get_flag_names(); - $flagged_content[$uid][$sid][$entity_type][$entity_id] = array(); - $result = db_select('flagging', 'fc') - ->fields('fc') - ->condition('entity_type', $entity_type) - ->condition('entity_id', $entity_id) - ->condition(db_or() - ->condition('uid', $uid) - ->condition('uid', 0) - ) - ->condition('sid', $sid) - ->execute(); - - foreach ($result as $flagging_data) { - $flagged_content[$uid][$sid][$entity_type][$entity_id][$flag_names[$flagging_data->fid]] = $flagging_data; - } - } - return $flagged_content[$uid][$sid][$entity_type][$entity_id]; - } - - else { - if (!isset($flagged_content[$uid][$sid][$entity_type]['all'])) { - $flag_names = _flag_get_flag_names(); - $flagged_content[$uid][$sid][$entity_type]['all'] = array(); - $result = db_select('flagging', 'fc') - ->fields('fc') - ->condition('entity_type', $entity_type) - ->condition(db_or() - ->condition('uid', $uid) - ->condition('uid', 0) - ) - ->condition('sid', $sid) - ->execute(); - foreach ($result as $flagging_data) { - $flagged_content[$uid][$sid][$entity_type]['all'][$flag_names[$flagging_data->fid]][$flagging_data->entity_id] = $flagging_data; - } - } - return $flagged_content[$uid][$sid][$entity_type]['all']; - } - -} - -/** - * Return a list of users who have flagged an entity. - * - * @param $entity_type - * The type of entity that will be retrieved. Usually 'node'. - * @param $entity_id - * The entity ID to check for flagging. - * @param $flag_name - * (optional) The name of a flag if wanting a list specific to a single flag. - * - * @return - * If no flag name is given, an array of flagging data, keyed by the user - * ID that flagged the entity. Each flagging array is structured as - * an array of flag information for each flag, keyed by the flag name. If - * a flag name is specified, only the information for that flag is returned. - * If no flags were found an empty array is returned. - */ -function flag_get_entity_flags($entity_type, $entity_id, $flag_name = NULL) { - $entity_flags = &drupal_static(__FUNCTION__, array()); - - if (!isset($entity_flags[$entity_type][$entity_id])) { - $flag_names = _flag_get_flag_names(); - $result = db_select('flagging', 'fc') - ->fields('fc') - ->condition('entity_type', $entity_type) - ->condition('entity_id', $entity_id) - ->orderBy('timestamp', 'DESC') - ->execute(); - $entity_flags[$entity_type][$entity_id] = array(); - foreach ($result as $flagging_data) { - // Build a list of flaggings for all flags by user. - $entity_flags[$entity_type][$entity_id]['users'][$flagging_data->uid][$flag_names[$flagging_data->fid]] = $flagging_data; - // Build a list of flaggings for each individual flag. - $entity_flags[$entity_type][$entity_id]['flags'][$flag_names[$flagging_data->fid]][$flagging_data->uid] = $flagging_data; - } - } - if (empty($entity_flags[$entity_type][$entity_id])) { - return array(); - } - if (isset($flag_name)) { - if (isset($entity_flags[$entity_type][$entity_id]['flags'][$flag_name])) { - return $entity_flags[$entity_type][$entity_id]['flags'][$flag_name]; - } - return array(); - } - return $entity_flags[$entity_type][$entity_id]['users']; -} - /** * A utility function for outputting a flag link. * @@ -1736,82 +1451,6 @@ function flag_get_sid($uid = NULL, $create = FALSE) { return flag_set_sid($uid, $create); } -// --------------------------------------------------------------------------- -// Drupal Core operations - -/** - * Implements hook_node_operations(). - * - * Add additional options on the admin/build/node page. - */ -function flag_node_operations() { - global $user; - - $flags = flag_get_flags('node', NULL, $user); - $operations = array(); - - foreach ($flags as $flag) { - $operations['flag_' . $flag->name] = array( - 'label' => $flag->get_label('flag_short'), - 'callback' => 'flag_nodes', - 'callback arguments' => array('flag', $flag->name), - 'behavior' => array(), - ); - $operations['unflag_' . $flag->name] = array( - 'label' => $flag->get_label('unflag_short'), - 'callback' => 'flag_nodes', - 'callback arguments' => array('unflag', $flag->name), - 'behavior' => array(), - ); - } - return $operations; -} - -/** - * Callback function for hook_node_operations(). - */ -function flag_nodes($nodes, $action, $flag_name) { - $performed = FALSE; - foreach ($nodes as $nid) { - $performed |= flag($action, $flag_name, $nid); - } - if ($performed) { - drupal_set_message(t('The update has been performed.')); - } -} - -/** - * Implements hook_user_operations(). - */ -function flag_user_operations() { - global $user; - - $flags = flag_get_flags('user', NULL, $user); - $operations = array(); - - foreach ($flags as $flag) { - $operations['flag_' . $flag->name] = array( - 'label' => $flag->get_label('flag_short'), - 'callback' => 'flag_users', - 'callback arguments' => array('flag', $flag->name), - ); - $operations['unflag_' . $flag->name] = array( - 'label' => $flag->get_label('unflag_short'), - 'callback' => 'flag_users', - 'callback arguments' => array('unflag', $flag->name), - ); - } - return $operations; -} -/** - * Callback function for hook_user_operations(). - */ -function flag_users($users, $action, $flag_name) { - foreach ($users as $uid) { - flag($action, $flag_name, $uid); - } -} - // --------------------------------------------------------------------------- // Contrib integration hooks @@ -1842,43 +1481,6 @@ function flag_features_api() { // --------------------------------------------------------------------------- // Entity Metadata callbacks -/** - * Getter callback that returns whether the given entity is flagged. - */ -function flag_properties_get_flagging_boolean($entity, array $options, $name, $entity_type, $property_info) { - list($entity_id,) = entity_extract_ids($entity_type, $entity); - - $flagging_data = flag_get_user_flags($entity_type, $entity_id); - return isset($flagging_data[$property_info['flag_name']]); -} - -/** - * Getter callback that returns entities the given user flagged. - */ -function flag_properties_get_flagged_entities($entity, array $options, $name, $entity_type, $property_info) { - // Need the entity type the flag applies to. - $flag_entity_type = $property_info['flag_entity_type']; - - $flagging_data = flag_get_user_flags($flag_entity_type, NULL, $entity->uid); - - $flag_name = $property_info['flag_name']; - if (isset($flagging_data[$flag_name])) { - return array_keys($flagging_data[$flag_name]); - } - return array(); -} - -/** - * Getter callback that returns users who flagged the given entity. - */ -function flag_properties_get_flagging_users($entity, array $options, $name, $entity_type, $property_info) { - list($entity_id,) = entity_extract_ids($entity_type, $entity); - - $flagging_data = flag_get_entity_flags($entity_type, $entity_id, $property_info['flag_name']); - - return array_keys($flagging_data); -} - /** * Getter callback that returns the SID of the user that is being retrieved. * diff --git a/src/FlagService.php b/src/FlagService.php index f2c228d..1295da9 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -153,9 +153,11 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ * Get all flaggings for the given entity, flag, and optionally, user. * * @param EntityInterface $entity - * The flaggable entity. + * Optional. The flaggable entity. If NULL, flaggins for any entity will be + * returned. * @param FlagInterface $flag - * The flag entity. + * Optional. The flag entity. If NULL, flaggings for any flag will be + * returned. * @param AccountInterface $account * Optional. The account of the flagging user. If NULL, flaggings for any * user will be returned. @@ -163,17 +165,23 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ * @return array * An array of flaggings. */ - public function getFlaggings(EntityInterface $entity, FlagInterface $flag, AccountInterface $account = NULL) { - if ($account == NULL) { - $account = $this->currentUser; + public function getFlaggings(EntityInterface $entity = NULL, FlagInterface $flag = NULL, AccountInterface $account = NULL) { + $query = $this->entityQueryMgr->get('flagging'); + + if (!empty($account)) { + $query = $query->condition('uid', $account->id()); } - $result = $this->entityQueryMgr->get('flagging') - ->condition('uid', $account->id()) - ->condition('fid', $flag->id()) - ->condition('entity_type', $entity->getEntityTypeId()) - ->condition('entity_id', $entity->id()) - ->execute(); + if (!empty($flag)) { + $query = $query->condition('fid', $flag->id()); + } + + if (!empty($entity)) { + $query = $query->condition('entity_type', $entity->getEntityTypeId()) + ->condition('entity_id', $entity->id()); + } + + $result = $query->execute(); $flaggings = []; foreach ($result as $flagging_id) { @@ -211,6 +219,36 @@ public function getFlaggableById(FlagInterface $flag, $entity_id) { return entity_load($flag->getFlaggableEntityType(), $entity_id); } + /** + * Get a list of users that have flagged an entity. + * + * @param EntityInterface $entity + * The entity object. + * @param FlagInterface $flag + * Optional. The flag entity to which to restrict results. + * + * @return array + * An array of users who have flagged the entity. + */ + public function getFlaggingUsers(EntityInterface $entity, FlagInterface $flag = NULL) { + $query = $this->entityQueryMgr->get('users') + ->condition('entity_type', $entity->getEntityTypeId()) + ->condition('entity_id', $entity->id()); + + if (!empty($flag)) { + $query = $query->condition('fid', $flag->id()); + } + + $result = $query->execute(); + + $flaggings = []; + foreach ($result as $flagging_id) { + $flaggings[$flagging_id] = entity_load('flagging', $flagging_id); + } + + return $flaggings; + } + /** * Flags the given entity given the flag and entity objects. * From a794101acb39af5414af6679786c718f516b4e2f Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 7 Sep 2014 22:44:51 -0500 Subject: [PATCH 557/629] Refactored Flag entity to use getters and setters provided by FlagInterface. --- flag.module | 460 +------------------------------------ flag.tokens.inc | 4 +- src/ActionLinkTypeBase.php | 8 +- src/Entity/Flag.php | 155 ++++++++++--- src/FlagInterface.php | 160 +++++++++++++ src/Form/FlagFormBase.php | 20 +- 6 files changed, 312 insertions(+), 495 deletions(-) diff --git a/flag.module b/flag.module index 9baa387..1d57ffc 100644 --- a/flag.module +++ b/flag.module @@ -78,39 +78,6 @@ function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { $query->condition('f.name', $value, $operator); }*/ -/** - * Menu loader for '%flag' arguments. - * - * @param $flag_name - * The machine name of the flag. - * @param $include_disabled - * (optional) Whether to return a disabled flag too. Normally only enabled - * flags are returned. Some menu items operate on disabled flags and in this - * case you need to turn on this switch by doing: - * @code - * 'load arguments' => array(TRUE) - * @endcode - * in your hook_menu(). - * - * @return - * Either the flag object, or FALSE if none was found. - */ -function flag_load($flag_name, $include_disabled = FALSE) { - if (($flag = flag_get_flag($flag_name))) { - return $flag; - } - else { - // No enabled flag was found. Search among the disabled ones. - if ($include_disabled) { - $default_flags = flag_get_default_flags(TRUE); - if (isset($default_flags[$flag_name])) { - return $default_flags[$flag_name]; - } - } - } - // A menu loader has to return FALSE (not NULL) when no object is found. - return FALSE; -} /** * Implements hook_help(). */ @@ -207,7 +174,7 @@ function flag_permission() { } /** - * Implements hook_form_FORM_ID_alter(): user_admin_permissions. + * Implements hook_form_FORM_ID_alter(): user_admin_permissions(). * * Disable permission on the permissions form that don't make sense for * anonymous users when Session API module is not enabled. @@ -232,13 +199,13 @@ function flag_entity_extra_field_info() { $flags = $flag_service->getFlags(); foreach ($flags as $flag) { // Skip flags that aren't on entities. - $flagTypePlugin = $flag->getFlagTypePlugin(); - if (!($flagTypePlugin instanceof \Drupal\flag\Plugin\Flag\EntityFlagType)) { + $flag_type_plugin = $flag->getFlagTypePlugin(); + if (!($flag_type_plugin instanceof \Drupal\flag\Plugin\Flag\EntityFlagType)) { continue; } foreach ($flag->types as $bundle_name) { - if ($flagTypePlugin->showOnForm()) { + if ($flag_type_plugin->showOnForm()) { $extra[$flag->entity_type][$bundle_name]['form']['flag'] = [ 'label' => t('Flags'), 'description' => t('Checkboxes for toggling flags'), @@ -246,7 +213,7 @@ function flag_entity_extra_field_info() { ]; } - if ($flagTypePlugin->showAsField()) { + if ($flag_type_plugin->showAsField()) { $extra[$flag->entity_type][$bundle_name]['display']['flag_' . $flag->id()] = [ // It would be nicer to use % as the placeholder, but the label is // run through check_plain() by field_ui_display_overview_form() @@ -266,7 +233,7 @@ function flag_entity_extra_field_info() { /** * Implements hook_form_FORM_ID_alter(): node_type_form. - */ + *//* function flag_form_node_type_form_alter(&$form, FormStateInterface $form_state, $form_id) { global $user; $node_type = $form_state['controller']->getEntity(); @@ -303,172 +270,11 @@ function flag_form_node_type_form_alter(&$form, FormStateInterface $form_state, ]; } } - +*/ function flag_node_links_alter(array &$links, NodeInterface $entity, array &$context) { //@todo: Define this for handling the showOnLinks() flag mode. } -/** - * Implements hook_field_attach_form(). - * - * Handles the 'show_on_form' flag option. - * - * Warning: will not work on entity types that are not fieldable, as this relies - * on a field module hook. - * - * @see flag_field_attach_submit(). - */ -function flag_field_attach_form($entity_type, $entity, &$form, FormStateInterface $form_state, $langcode) { - $id = $entity->id; - - // Some modules are being stupid here. Commerce! - if (empty($entity->id)) { - $id = NULL; - } - - // Get all possible flags for this entity type. - $flags = \Drupal::service('flag')->getFlags($entity_type); - - // Filter out flags which need to be included on the node form. - $flags_in_form = 0; - $flags_visible = 0; - foreach ($flags as $flag) { - if (!$flag->show_on_form) { - continue; - } - - // Get the flag status. - if (isset($id)) { - $flag_status = $flag->is_flagged($id); - } - else { - // We don't have per-bundle defaults on general entities yet: default - // status is just unflagged. - $flag_status = FALSE; - // Apply the per-bundle defaults for nodes. - if ($entity_type == 'node') { - $flag_status = variable_get('flag_' . $flag->name . '_default_' . $form['type']['#value'], 0); - } - - // For a new, unsaved entity, make a dummy entity ID so that the flag - // handler can remember the entity. This allows access to the flag to be - // correctly handled in node and comment preview. - $id = 'new'; - $flag->remember_entity($id, $entity); - } - - // If the flag is not global and the user doesn't have access, skip it. - // Global flags have their value set even if the user doesn't have access - // to it, similar to the way "published" and "promote" keep the default - // values even if the user doesn't have "administer nodes" permission. - // Furthermore, a global flag is set to its default value on new nodes - // even if the user creating the node doesn't have access to the flag. - global $user; - $access = $flag->access($id, $flag_status ? 'unflag' : 'flag'); - if (!$access && !$flag->global) { - continue; - } - - $form['flag'][$flag->name] = [ - '#type' => 'checkbox', - '#title' => $flag->get_label('flag_short', $id), - '#description' => $flag->get_label('flag_long', $id), - '#default_value' => $flag_status, - '#return_value' => 1, - // Used by our drupalSetSummary() on vertical tabs. - '#attributes' => ['title' => $flag->get_title()], - ]; - - // If the user does not have access to the flag, set as a value. - if (!$access) { - $form['flag'][$flag->name]['#type'] = 'value'; - $form['flag'][$flag->name]['#value'] = $flag_status; - } - else { - $flags_visible++; - } - $flags_in_form++; - } - - if ($flags_in_form) { - $form['flag'] += [ - '#weight' => 1, - '#tree' => TRUE, - ]; - } - if ($flags_visible) { - $form['flag'] += [ - '#type' => 'fieldset', - '#title' => t('Flags'), - '#collapsible' => TRUE, - ]; - - if ($entity_type == 'node') { - // Turn the fieldset into a vertical tab. - $form['flag'] += [ - '#group' => 'additional_settings', - '#attributes' => ['class' => ['flag-fieldset']], - '#attached' => [ - 'js' => [ - 'vertical-tabs' => drupal_get_path('module', 'flag') . '/theme/flag-admin.js', - ], - ], - ]; - } - } -} - -/** - * Implements hook_field_attach_submit(). - * - * @see flag_field_attach_form(). - */ -function flag_field_attach_submit($entity_type, $entity, $form, FormStateInterface $form_state) { - // This is invoked for each flag_field_attach_form(), but possibly more than - // once for a particular form in the case that a form is showing multiple - // entities (field collection, inline entity form). Hence we can't simply - // assume our submitted form values are in $form_state['values']['flag']. - if (isset($form['flag'])) { - $parents = $form['flag']['#parents']; - $flag_values = drupal_array_get_nested_value($form_state['values'], $parents); - - // Put the form values in the entity so flag_field_attach_save() can find - // them. We can't call flag() here as new entities have no id yet. - $entity->flag = $flag_values; - } -} - -/** - * Implements hook_field_attach_insert(). - */ -function flag_field_attach_insert($entity_type, $entity) { - if (isset($entity->flag)) { - flag_field_attach_save($entity_type, $entity); - } -} - -/** - * Implements hook_field_attach_update(). - */ -function flag_field_attach_update($entity_type, $entity) { - if (isset($entity->flag)) { - flag_field_attach_save($entity_type, $entity); - } -} - -/** - * Shared saving routine between flag_field_attach_insert/update(). - * - * @see flag_field_attach_form(). - */ -function flag_field_attach_save($entity_type, $entity) { - list($id) = entity_extract_ids($entity_type, $entity); - // Get the flag values we stashed in the entity in flag_field_attach_submit(). - foreach ($entity->flag as $flag_name => $state) { - flag($state ? 'flag' : 'unflag', $flag_name, $id); - } -} - /** * Implements hook_entity_view(). * @@ -549,32 +355,7 @@ function flag_entity_delete(EntityInterface $entity) { return; } -// _flag_entity_delete($entity->getFlaggableEntityType(), $entity->id()); -} - -/** - * Deletes flagging records for the entity. - * - * @param $entity_type - * The type of the entity being deleted; e.g. 'node' or 'comment'. - * @param $entity_id - * The ID of the entity being deleted. - * @param $fid - * The flag id - */ -function _flag_entity_delete($entity_type, $entity_id, $fid = NULL) { - $query_content = db_delete('flagging') - ->condition('entity_type', $entity_type) - ->condition('entity_id', $entity_id); - $query_counts = db_delete('flag_counts') - ->condition('entity_type', $entity_type) - ->condition('entity_id', $entity_id); - if (isset($fid)) { - $query_content->condition('fid', $fid); - $query_counts->condition('fid', $fid); - } - $query_content->execute(); - $query_counts->execute(); + // @todo Actually delete the flaggings and clear associated flag counts. } /** @@ -1114,27 +895,6 @@ function flag_get_flag_counts($flag_name, $reset = FALSE) { return $counts[$flag_name]; } -/** - * List all flags available. - * - * If node type or account are entered, a list of all possible flags will be - * returned. - * - * @param $entity_type - * (optional) The type of entity for which to load the flags. Usually 'node'. - * @param $content_subtype - * (optional) The node type for which to load the flags. - * @param $account - * (optional) The user accont to filter available flags. If not set, all - * flags for will this node will be returned. - * - * @return - * An array of the structure [fid] = flag_object. - */ -function flag_get_flags($entity_type = NULL, $content_subtype = NULL, $account = NULL) { - return \Drupal::service('flag')->getFlags($entity_type, $content_subtype, $account); -} - /** * Comparison function for uasort(). */ @@ -1145,145 +905,6 @@ function _flag_compare_weight($flag1, $flag2) { return $flag1->weight < $flag2->weight ? -1 : 1; } -/** - * Retrieve a list of flags defined by modules. - * - * @param $include_disabled - * (optional) Unless specified, only enabled flags will be returned. - * - * @return - * An array of flag prototypes, not usable for flagging. Use flag_get_flags() - * if needing to perform a flagging with any enabled flag. - */ -function flag_get_default_flags($include_disabled = FALSE) { - $default_flags = array(); - $flag_status = variable_get('flag_default_flag_status', array()); - - foreach (module_implements('flag_default_flags') as $module) { - $function = $module . '_flag_default_flags'; - foreach ($function() as $flag_name => $flag_info) { - // Backward compatibility: old exported default flags have their names - // in $flag_info instead, so we use the += operator to not overwrite it. - $flag_info += array( - 'name' => $flag_name, - 'module' => $module, - ); - $flag = flag_flag::factory_by_array($flag_info); - - // Disable flags that are not at the current API version. - if (!$flag->is_compatible()) { - $flag->status = FALSE; - } - - // Add flags that have been enabled. - if ((!isset($flag_status[$flag->name]) && (!isset($flag->status) || $flag->status)) || !empty($flag_status[$flag->name])) { - $flag->status = TRUE; - $default_flags[$flag->name] = $flag; - } - // Add flags that have been disabled. - elseif ($include_disabled) { - $flag->status = FALSE; - $default_flags[$flag->name] = $flag; - } - } - } - - return $default_flags; -} - -/** - * Get all flagged entities in a flag. - * - * @param $flag_name - * The flag name for which to retrieve flagged entites. - * - * @return - * An array of flagging data, keyed by the flagging ID. - */ -function flag_get_flag_flagging_data($flag_name) { - $return = array(); - $flag = flag_get_flag($flag_name); - $result = db_select('flagging', 'fc') - ->fields('fc') - ->condition('fid', $flag->fid) - ->execute(); - return $result->fetchAllAssoc('flagging_id'); -} - -/** - * A utility function for outputting a flag link. - * - * You should call this function from your template when you want to put the - * link on the page yourself. For example, you could call this function from - * your theme preprocessor for node.tpl.php: - * @code - * $variables['my_flag_link'] = flag_create_link('bookmarks', $node->nid); - * @endcode - * - * @param $flag_name - * The "machine readable" name of the flag; e.g. 'bookmarks'. - * @param $entity_id - * The entity ID to check for flagging, for example a node ID. - * - * @return - * The HTML for the themed flag link. - */ -function flag_create_link($flag_name, $entity_id) { - $flag = flag_get_flag($flag_name); - if (!$flag) { - // Flag does not exist. - return; - } - if (!$flag->access($entity_id) && (!$flag->is_flagged($entity_id) || !$flag->access($entity_id, 'flag'))) { - // User has no permission to use this flag. - return; - } - return $flag->theme($flag->is_flagged($entity_id) ? 'unflag' : 'flag', $entity_id); -} - -/** - * Trim a flag to a certain size. - * - * @param $fid - * The flag object. - * @param $account - * The user object on behalf the trimming will occur. - * @param $cutoff_size - * The number of flaggings allowed. Any flaggings beyond that will be trimmed. - * @param $trim_newest - * An optional boolean indicating whether to trim the newest flags. - * @param $permissions_check - * (optional) A boolean indicating whether to skip permissions. - * This will trim the flag if $permissions_check is TRUE even if the user - * doesn't have the permission to flag/unflag. - */ -function flag_trim_flag($flag, $account, $cutoff_size, $trim_newest, $permissions_check = FALSE) { - $query = db_select('flagging', 'fc') - ->fields('fc') - ->condition('fid', $flag->fid) - ->condition(db_or()->condition('uid', $account->uid)->condition('uid', 0)) - // Account for session ID (in the case of anonymous users). - ->condition('sid', flag_get_sid($account->uid)); - // If $trim_newest is TRUE, then, we should order by 'ASC' as we should trim - // the newest flags. - if ($trim_newest) { - $query->orderBy('timestamp', 'ASC'); - } - else { - $query->orderBy('timestamp', 'DESC') ; - } - - // Execute the query - $result = $query->execute(); - - $i = 1; - foreach ($result as $row) { - if ($i++ > $cutoff_size) { - flag('unflag', $flag->name, $row->entity_id, $account, $permissions_check); - } - } -} - /** * Remove all flagged entities from a flag. * @@ -1320,71 +941,6 @@ function flag_reset_flag($flag, $entity_id = NULL) { return $query->execute(); } -/** - * Return an array of link types provided by modules. - * - * @return - * An array of link types as defined by hook_flag_link_type_info(). These are - * keyed by the type name, and each value is an array of properties. In - * addition to those defined in hook_flag_link_type_info(), the following - * properties are set: - * - 'module': The providing module. - * - 'name': The machine name of the type. - * - * @see hook_flag_link_type_info() - * @see hook_flag_link_type_info_alter() - */ -function flag_get_link_types() { - $link_types = &drupal_static(__FUNCTION__); - - if (!isset($link_types)) { - if ($cache = \Drupal::cache()->get('flag_link_type_info')) { - $link_types = $cache->data; - } - // In some rare edge cases \Drupal::cache()->get() can return an empty result. If it - // does, we make sure to fetch the link types again. - if (empty($link_types)) { - $link_types = array(); - foreach (module_implements('flag_link_type_info') as $module) { - $module_types = module_invoke($module, 'flag_link_type_info'); - foreach ($module_types as $type_name => $info) { - $link_types[$type_name] = $info + array( - 'module' => $module, - 'name' => $type_name, - 'title' => '', - 'description' => '', - 'options' => array(), - 'uses standard js' => TRUE, - 'uses standard css' => TRUE, - 'provides form' => FALSE, - ); - } - } - drupal_alter('flag_link_type_info', $link_types); - - \Drupal::cache()->set('flag_link_type_info', $link_types); - } - } - - return $link_types; -} - -/** - * Get a private token used to protect links from spoofing - CSRF. - */ -function flag_get_token($entity_id) { - // Anonymous users get a less secure token, since it must be the same for all - // anonymous users on the entire site to work with page caching. - return ($GLOBALS['user']->uid) ? drupal_get_token($entity_id) : md5(drupal_get_private_key() . $entity_id); -} - -/** - * Check to see if a token value matches the specified node. - */ -function flag_check_token($token, $entity_id) { - return flag_get_token($entity_id) == $token; -} - /** * Set the Session ID for a user. Utilizes the Session API module. * diff --git a/flag.tokens.inc b/flag.tokens.inc index 7fcf735..52bc66f 100644 --- a/flag.tokens.inc +++ b/flag.tokens.inc @@ -99,6 +99,7 @@ function flag_token_info() { * Implements hook_tokens(). */ function flag_tokens($type, $tokens, array $data = array(), array $options = array()) { + /* $replacements = array(); $sanitize = !empty($options['sanitize']); $langcode = isset($options['language']) ? $options['language']->language : NULL; @@ -162,7 +163,7 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr } if (isset($data[$type]) && in_array($type, \Drupal::service('flag')->fetchDefinition())) { - $flags = flag_get_flags($type); + $flags = \Drupal::service('flag')->getFlags($type); $object = $data[$type]; foreach ($flags as $flag) { foreach ($tokens as $name => $original) { @@ -178,6 +179,7 @@ function flag_tokens($type, $tokens, array $data = array(), array $options = arr } } return $replacements; + */ } /** diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 6d6eb8c..59bdc9b 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -80,12 +80,12 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity $render['#attributes']['id'] = 'flag-' . $flag->id() . '-id-' . $entity->id(); if ($action === 'unflag') { - $render['#title'] = $flag->unflag_short; - $render['#alt'] = $flag->unflag_long; + $render['#title'] = $flag->getUnflagShortText(); + $render['#alt'] = $flag->getUnflagLongText(); } else { - $render['#title'] = $flag->flag_short; - $render['#alt'] = $flag->flag_long; + $render['#title'] = $flag->getFlagShortText(); + $render['#alt'] = $flag->getFlagLongText(); } return $render; diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index ae8fca6..4127216 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -44,6 +44,7 @@ * ) */ class Flag extends ConfigEntityBase implements FlagInterface { + // @todo: Define flag reset method. /** * The flag ID. @@ -101,49 +102,49 @@ class Flag extends ConfigEntityBase implements FlagInterface { * * @var string */ - public $flag_short = ''; + protected $flag_short = ''; /** * The description of the "flag this" link. * * @var string */ - public $flag_long = ''; + protected $flag_long = ''; /** * Message displayed after flagging an entity. * * @var string */ - public $flag_message = ''; + protected $flag_message = ''; /** * The text for the "unflag this" link for this flag. * * @var string */ - public $unflag_short = ''; + protected $unflag_short = ''; /** * The description of the "unflag this" link. * * @var string */ - public $unflag_long = ''; + protected $unflag_long = ''; /** * Message displayed after flagging an entity. * * @var string */ - public $unflag_message = ''; + protected $unflag_message = ''; /** * Message displayed if users aren't allowed to unflag. * * @var string */ - public $unflag_denied_text = ''; + protected $unflag_denied_text = ''; /** * The ID of the FlagType plugin. @@ -248,6 +249,13 @@ public function isFlagged(EntityInterface $entity, AccountInterface $account = N return FALSE; } + /** + * {@inheritdoc} + */ + public function getFlaggableEntityType() { + return $this->entity_type; + } + /** * {@inheritdoc} */ @@ -259,20 +267,14 @@ public function getPluginBags() { } /** - * Get the flag type plugin for this flag. - * - * @return \Drupal\flag\FlagTypePluginInterface - * The flag type plugin for this flag. + * {@inheritdoc} */ public function getFlagTypePlugin() { return $this->flagTypeBag->get($this->flag_type); } /** - * Set the flag type plugin. - * - * @param string $plugin_id - * A string containing the flag type plugin ID. + * {@inheritdoc} */ public function setFlagTypePlugin($plugin_id) { $this->flag_type = $plugin_id; @@ -288,20 +290,14 @@ public function setFlagTypePlugin($plugin_id) { } /** - * Get the link type plugin for this flag. - * - * @return \Drupal\flag\ActionLinkTypePluginInterface - * The link type plugin for the flag. + * {@inheritdoc} */ public function getLinkTypePlugin() { return $this->linkTypeBag->get($this->link_type); } /** - * Set the link type plugin. - * - * @param string $plugin_id - * A string containing the link type plugin ID. + * {@inheritdoc} */ public function setlinkTypePlugin($plugin_id) { $this->link_type = $plugin_id; @@ -364,15 +360,116 @@ public function setGlobal($is_global = TRUE) { } /** - * Returns the flaggable entity type ID. - * - * @return string - * The flaggable entity ID. + * {@inheritdoc} */ - public function getFlaggableEntityType() { - return $this->entity_type; + public function setFlagShortText($text) { + $this->flag_short; + } + + /** + * {@inheritdoc} + */ + public function getFlagShortText() { + return $this->flag_short; } + /** + * {@inheritdoc} + */ + public function getFlagLongText() { + return $this->flag_long; + } + + /** + * {@inheritdoc} + */ + public function setFlagLongText($flag_long) { + $this->flag_long = $flag_long; + } + + /** + * {@inheritdoc} + */ + public function getFlagMessage() { + return $this->flag_message; + } + + /** + * {@inheritdoc} + */ + public function setFlagMessage($flag_message) { + $this->flag_message = $flag_message; + } + + /** + * {@inheritdoc} + */ + public function getUnflagLongText() { + return $this->unflag_long; + } + + /** + * {@inheritdoc} + */ + public function setUnflagLongText($unflag_long) { + $this->unflag_long = $unflag_long; + } + + /** + * {@inheritdoc} + */ + public function getUnflagMessage() { + return $this->unflag_message; + } + + /** + * {@inheritdoc} + */ + public function setUnflagMessage($unflag_message) { + $this->unflag_message = $unflag_message; + } + + /** + * {@inheritdoc} + */ + public function getUnflagShortText() { + return $this->unflag_short; + } + + /** + * {@inheritdoc} + */ + public function setUnflagShortText($unflag_short) { + $this->unflag_short = $unflag_short; + } + + /** + * {@inheritdoc} + */ + public function getUnflagDeniedText() { + return $this->unflag_denied_text; + } + + /** + * {@inheritdoc} + */ + public function setUnflagDeniedText($unflag_denied_text) { + $this->unflag_denied_text = $unflag_denied_text; + } + + /** + * {@inheritdoc} + */ + public function getWeight() { + return $this->weight; + } + + /** + * {@inheritdoc} + */ + public function setWeight($weight) { + $this->weight = $weight; + } /** * {@inheritdoc} */ diff --git a/src/FlagInterface.php b/src/FlagInterface.php index 48c2ffe..6673569 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -43,6 +43,38 @@ public function disable(); */ public function isFlagged(EntityInterface $entity, AccountInterface $account = NULL); + /** + * Returns the flaggable entity type ID. + * + * @return string + * The flaggable entity ID. + */ + public function getFlaggableEntityType(); + + /** + * Set the flag type plugin. + * + * @param string $plugin_id + * A string containing the flag type plugin ID. + */ + public function setFlagTypePlugin($plugin_id); + + /** + * Get the link type plugin for this flag. + * + * @return \Drupal\flag\ActionLinkTypePluginInterface + * The link type plugin for the flag. + */ + public function getLinkTypePlugin(); + + /** + * Set the link type plugin. + * + * @param string $plugin_id + * A string containing the link type plugin ID. + */ + public function setlinkTypePlugin($plugin_id); + /** * Returns an associative array of permissions used by flag_permission(). * @@ -80,6 +112,134 @@ public function isGlobal(); */ public function setGlobal($is_global); + /** + * The flag short text. + * + * @param string $text + * The flag short text to set. + */ + public function setFlagShortText($text); + + /** + * Gets the flag short text. + * + * @return string + * A string containing the flag short text. + */ + public function getFlagShortText(); + + /** + * Gets the flag long text. + * + * @return string + * A string containing the flag long text. + */ + public function getFlagLongText(); + + /** + * Sets the flag long text. + * + * @param string $flag_long + * The flag long text to use. + */ + public function setFlagLongText($flag_long); + + /** + * Gets the flag message. + * + * @return string + * A string continaing the flag message. + */ + public function getFlagMessage(); + + /** + * Sets the flag message. + * + * @param string $flag_message + * The flag message text to use. + */ + public function setFlagMessage($flag_message); + + /** + * Gets the unflag short text. + * + * @return string + * A string containing the unflag short text. + */ + public function getUnflagShortText(); + + /** + * Sets the unflag short text. + * + * @param string $flag_short + * The unflag short text to use. + */ + public function setUnflagShortText($flag_short); + + /** + * Gets the flag long text. + * + * @return string + * A string containing the unflag long text. + */ + public function getUnflagLongText(); + + /** + * Sets the unflag long text. + * + * @param string $unflag_long + * The unflag lnog text to use. + */ + public function setUnflagLongText($unflag_long); + + /** + * Gets the unflag message. + * + * @return string + * The unflag message text to use. + */ + public function getUnflagMessage(); + + /** + * Sets the unflag message. + * + * @param string $unflag_message + * The unflag message text to use. + */ + public function setUnflagMessage($unflag_message); + + /** + * Get the flag's weight. + * + * @return int + * The flag's weight. + */ + public function getWeight(); + + /** + * Set the flag's weight. + * + * @param int $weight + * An int containing the flag weight to use. + */ + public function setWeight($weight); + + /** + * Get the flag's unflag denied message text. + * + * @return string + * A string containing the unflag denied message text. + */ + public function getUnflagDeniedText(); + + /** + * Set's the flag's unflag denied message text. + * + * @param string $unflag_denied_text + * The unflag denied message text to use. + */ + public function setUnflagDeniedText($unflag_denied_text); + /** * {@inheritdoc} */ diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 7cd4b58..e754c80 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -7,8 +7,8 @@ namespace Drupal\flag\Form; use Drupal\Core\Entity\EntityForm; -use Drupal\flag\Handlers\AbstractFlag; use Drupal\Core\Form\FormStateInterface; +use Drupal\flag\FlagInterface; /** * Provides the base flag add/edit form. @@ -75,10 +75,11 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#title' => t('Messages'), ]; + $flag_short = $flag->getFlagShortText(); $form['messages']['flag_short'] = [ '#type' => 'textfield', '#title' => t('Flag link text'), - '#default_value' => !empty($flag->flag_short) ? $flag->flag_short : t('Flag this item'), + '#default_value' => !empty($flag_short) ? $flag_short : t('Flag this item'), '#description' => t('The text for the "flag this" link for this flag.'), '#required' => TRUE, ]; @@ -86,21 +87,22 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $form['messages']['flag_long'] = [ '#type' => 'textfield', '#title' => t('Flag link description'), - '#default_value' => $flag->flag_long, + '#default_value' => $flag->getFlagLongText(), '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'), ]; $form['messages']['flag_message'] = [ '#type' => 'textfield', '#title' => t('Flagged message'), - '#default_value' => $flag->flag_message, + '#default_value' => $flag->getFlagMessage(), '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), ]; + $unflag_short = $flag->getUnflagShortText(); $form['messages']['unflag_short'] = [ '#type' => 'textfield', '#title' => t('Unflag link text'), - '#default_value' => !empty($flag->unflag_short) ? $flag->unflag_short : t('Unflag this item'), + '#default_value' => !empty($unflag_short) ? $unflag_short : t('Unflag this item'), '#description' => t('The text for the "unflag this" link for this flag.'), '#required' => TRUE, ]; @@ -108,14 +110,14 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $form['messages']['unflag_long'] = [ '#type' => 'textfield', '#title' => t('Unflag link description'), - '#default_value' => $flag->unflag_long, + '#default_value' => $flag->getUnflagLongText(), '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'), ]; $form['messages']['unflag_message'] = [ '#type' => 'textfield', '#title' => t('Unflagged message'), - '#default_value' => $flag->unflag_message, + '#default_value' => $flag->getUnflagMessage(), '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'), ]; @@ -132,7 +134,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $flag_type_def = $flag_type_plugin->getPluginDefinition(); $bundles = entity_get_bundles($flag_type_def['entity_type']); - $entity_bundles = array(); + $entity_bundles = []; foreach ($bundles as $bundle_id => $bundle_row) { $entity_bundles[$bundle_id] = $bundle_row['label']; } @@ -151,7 +153,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $form['access']['unflag_denied_text'] = [ '#type' => 'textfield', '#title' => t('Unflag not allowed text'), - '#default_value' => $flag->unflag_denied_text, + '#default_value' => $flag->getUnflagDeniedText(), '#description' => t('If a user is allowed to flag but not unflag, this text will be displayed after flagging. Often this is the past-tense of the link text, such as "flagged".'), '#weight' => -1, ]; From 7d6b532add40aa86778a1c2e3d1f9aa197eb6db2 Mon Sep 17 00:00:00 2001 From: vagrant Date: Mon, 8 Sep 2014 19:46:59 +0000 Subject: [PATCH 558/629] Added .DS_Store to .gitignore because of &^%#%$ Macs. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7f5b539..f092eec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea *.patch +.DS_Store From 921b3847cf6e968c1a3c5fccb941b47ef59449d5 Mon Sep 17 00:00:00 2001 From: vagrant Date: Mon, 8 Sep 2014 21:28:32 +0000 Subject: [PATCH 559/629] Fixed broken user flags. --- src/FlagService.php | 2 +- src/Plugin/Flag/EntityFlagType.php | 6 +----- src/Plugin/Flag/UserFlagType.php | 4 ++-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index 1295da9..78a93f8 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -127,7 +127,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ $query->condition('entity_type', $entity_type); } - if ($bundle != NULL) { + if ($bundle != NULL && $entity_type != $bundle) { $query->condition("types.$bundle", $bundle); } diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 0339c90..006abea 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -160,11 +160,7 @@ public function showInLinks($name) { * TRUE if the flag should appear as a psudofield, FALSE otherwise. */ public function showAsField() { - if (!empty($this->configuration['show_as_field'])) { - return $this->configuration['show_as_field']; - } - - return TRUE; + return $this->configuration['show_as_field']; } /** diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index 1e26bf6..eb95ccf 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -7,7 +7,7 @@ namespace Drupal\flag\Plugin\Flag; use Drupal\Core\Session\AccountInterface; -use Drupal\flag\FlagTypeBase; +use Drupal\flag\Plugin\Flag\EntityFlagType; use Drupal\Core\Form\FormStateInterface; /** @@ -22,7 +22,7 @@ * provider = "user" * ) */ -class UserFlagType extends FlagTypeBase { +class UserFlagType extends EntityFlagType { /** * {@inheritdoc} From 7b13e3153a44b9d1831eda410758717868763580 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 9 Sep 2014 20:17:26 -0500 Subject: [PATCH 560/629] Initial broken Flagging field entry link type. --- flag.routing.yml | 9 ++ src/Controller/FieldEntryFormController.php | 59 +++++++++ src/Entity/Flagging.php | 7 + src/Form/FlaggingForm.php | 44 +++++++ src/Plugin/ActionLink/FieldEntry.php | 134 ++++++++++++++++++++ 5 files changed, 253 insertions(+) create mode 100644 src/Controller/FieldEntryFormController.php create mode 100644 src/Form/FlaggingForm.php create mode 100644 src/Plugin/ActionLink/FieldEntry.php diff --git a/flag.routing.yml b/flag.routing.yml index 8afef14..2fc3f72 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -86,4 +86,13 @@ flag.confirm_unflag: requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkUnflag' +flag.field_entry: + path: '/flag/details/flag/{flag_id}/{entity_id}' + defaults: + _form: '\Drupal\flag\Form\FlaggingForm' + _title: 'Enter Flag Details' + requirements: + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + + diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php new file mode 100644 index 0000000..9d22543 --- /dev/null +++ b/src/Controller/FieldEntryFormController.php @@ -0,0 +1,59 @@ +getForm($flag, 'default'); + } +} diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 0362f56..2df8812 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -23,6 +23,13 @@ * fieldable = TRUE, * bundle_entity_type = "flag", * field_ui_base_route = "flag.edit", + * controllers = { + * "form" = { + * "add" = "Drupal\flag\Form\FlaggingForm", + * "edit" = "Drupal\flag\Form\FlaggingForm", + * "delete" = "Drupal\flag\Form\FlaggingConfirmForm", + * } + * }, * entity_keys = { * "id" = "id", * "bundle" = "type", diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php new file mode 100644 index 0000000..a18daf8 --- /dev/null +++ b/src/Form/FlaggingForm.php @@ -0,0 +1,44 @@ +setRedirect('content_entity_example.contact_list'); + + return $entity; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + $entity = $this->entity; + $entity->save(); + } +} diff --git a/src/Plugin/ActionLink/FieldEntry.php b/src/Plugin/ActionLink/FieldEntry.php new file mode 100644 index 0000000..57c4091 --- /dev/null +++ b/src/Plugin/ActionLink/FieldEntry.php @@ -0,0 +1,134 @@ + 'fieldset', + '#title' => t('Options for the "Confirmation form" link type'), + // Any "link type" provider module must put its settings fields inside + // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is + // the machine-name of the link type. This is necessary for the + // radiobutton's JavaScript dependency feature to work. + '#id' => 'link-options-field_entry', + ]; + + $form['display']['settings']['link_options_field']['flag_confirmation'] = [ + '#type' => 'textfield', + '#title' => t('Flag confirmation message'), + '#default_value' => $this->configuration['flag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ]; + + $form['display']['settings']['link_options_field']['unflag_confirmation'] = [ + '#type' => 'textfield', + '#title' => t('Unflag confirmation message'), + '#default_value' => $this->configuration['unflag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ]; +*/ + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + /* $form_values = $form_state['values']; + + if ($form_values['link_type'] == 'confirm') { + if (empty($form_values['flag_confirmation'])) { + $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the confirmation link type.'); + } + if (empty($form_values['unflag_confirmation'])) { + $form_state->setErrorByName('unflag_confirmation', 'An unflag confirmation message is required when using the confirmation link type.'); + } + } + + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { + $form_state->setErrorByName('label', 'The flag name may only contain lowercase letters, underscores, and numbers.'); + } + */ + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + parent::submitConfigurationForm($form, $form_state); + /* + $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; + $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; + */ + } + + /** + * Returns the flag confirm form question when flagging. + * + * @return string + * A string containing the flag question to display. + */ + public function getFlagQuestion() { + return $this->configuration['flag_confirmation']; + } + + /** + * Returns the flag confirm form question when unflagging. + * + * @return string + * A string containing the unflag question to display. + */ + public function getUnflagQuestion() { + return $this->configuration['unflag_confirmation']; + } +} From a78e6a7912417123d89d4cad7fe33e98c116e154 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 9 Sep 2014 22:22:32 -0500 Subject: [PATCH 561/629] Fixed broken AJAX link type form. --- src/Form/FlagFormBase.php | 38 +++++++++++++++++++------------------- theme/flag-admin.js | 21 --------------------- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index e754c80..5d0a688 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -52,14 +52,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t 'exists' => [$this, 'exists'], ], '#disabled' => !$flag->isNew(), - '#submit' => [[$this, 'submitSelectPlugin']], '#required' => TRUE, - '#executes_submit_callback' => TRUE, - '#ajax' => [ - 'callback' => [$this, 'updateSelectedPluginType'], - 'wrapper' => 'monitoring-sensor-plugin', - 'method' => 'replace', - ], ]; $form['is_global'] = [ @@ -186,9 +179,6 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t // Give this a high weight so additions by the flag classes for entity- // specific options go above. '#weight' => 18, - '#attached' => [ - 'js' => [drupal_get_path('module', 'flag') . '/theme/flag-admin.js'], - ], '#attributes' => [ 'class' => ['flag-link-options'], ], @@ -197,7 +187,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#required' => TRUE, '#executes_submit_callback' => TRUE, '#ajax' => [ - 'callback' => [$this, 'updateSelectedPluginType'], + 'callback' => '::updateSelectedPluginType', 'wrapper' => 'link-type-settings-wrapper', 'event' => 'change', 'method' => 'replace', @@ -215,9 +205,6 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t $action_link_plugin_defs = \Drupal::service('plugin.manager.flag.linktype')->getDefinitions(); foreach ($action_link_plugin_defs as $key => $info) { $form['display']['link_type'][$key]['#description'] = $info['description']; - $form['display']['link_type'][$key]['#submit'] = [[$this, 'submitSelectPlugin']]; - $form['display']['link_type'][$key]['#executes_submit_callback'] = TRUE; - $form['display']['link_type'][$key]['#limit_validation_errors'] = [['link_type']]; } $action_link_plugin = $flag->getLinkTypePlugin(); @@ -230,6 +217,24 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t * Handles switching the configuration type selector. */ public function updateSelectedPluginType($form, FormStateInterface $form_state) { + // Rebuild the entity using the form's new state. + $this->entity = $this->buildEntity($form, $form_state); + $flag = $this->entity; + + // Reset the wrapper for the link type settings. + $form['display']['settings'] = [ + '#type' => 'container', + '#prefix' => '

', + '#weight' => 21, + ]; + + // Update the link type settings wrapper for the new selection. + $action_link_plugin = $flag->getLinkTypePlugin(); + $form = $action_link_plugin->buildConfigurationForm($form, $form_state); + + $form_state['rebuild'] = TRUE; + return $form['display']['settings']; } @@ -237,12 +242,7 @@ public function updateSelectedPluginType($form, FormStateInterface $form_state) * Handles submit call when sensor type is selected. */ public function submitSelectPlugin(array $form, FormStateInterface $form_state) { - $this->entity = $this->buildEntity($form, $form_state); - $form_state['rebuild'] = TRUE; - // This is necessary because there are two different instances of the form - // object. Core should handle this. - $form_state['build_info']['callback_object'] = $form_state['controller']; } /** diff --git a/theme/flag-admin.js b/theme/flag-admin.js index dcbc926..e52f2c4 100644 --- a/theme/flag-admin.js +++ b/theme/flag-admin.js @@ -45,25 +45,4 @@ Drupal.behaviors.flagRoles.attach = function(context) { } }; -/** - * Vertical tabs integration. - */ -Drupal.behaviors.flagSummary = {}; - -Drupal.behaviors.flagSummary.attach = function (context) { - $('fieldset.flag-fieldset', context).drupalSetSummary(function(context) { - var flags = []; - $('input:checkbox:checked', context).each(function() { - flags.push(this.title); - }); - - if (flags.length) { - return flags.join(', '); - } - else { - return Drupal.t('No flags'); - } - }); -}; - })(jQuery); From 5d8e166e69de9b8eeffff45dd8527e3d6162ab28 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 9 Sep 2014 20:17:26 -0500 Subject: [PATCH 562/629] Initial broken Flagging field entry link type. --- flag.routing.yml | 9 ++ src/Controller/FieldEntryFormController.php | 59 +++++++++ src/Entity/Flagging.php | 7 + src/Form/FlaggingForm.php | 44 +++++++ src/Plugin/ActionLink/FieldEntry.php | 134 ++++++++++++++++++++ 5 files changed, 253 insertions(+) create mode 100644 src/Controller/FieldEntryFormController.php create mode 100644 src/Form/FlaggingForm.php create mode 100644 src/Plugin/ActionLink/FieldEntry.php diff --git a/flag.routing.yml b/flag.routing.yml index 8afef14..2fc3f72 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -86,4 +86,13 @@ flag.confirm_unflag: requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkUnflag' +flag.field_entry: + path: '/flag/details/flag/{flag_id}/{entity_id}' + defaults: + _form: '\Drupal\flag\Form\FlaggingForm' + _title: 'Enter Flag Details' + requirements: + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + + diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php new file mode 100644 index 0000000..9d22543 --- /dev/null +++ b/src/Controller/FieldEntryFormController.php @@ -0,0 +1,59 @@ +getForm($flag, 'default'); + } +} diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 0362f56..2df8812 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -23,6 +23,13 @@ * fieldable = TRUE, * bundle_entity_type = "flag", * field_ui_base_route = "flag.edit", + * controllers = { + * "form" = { + * "add" = "Drupal\flag\Form\FlaggingForm", + * "edit" = "Drupal\flag\Form\FlaggingForm", + * "delete" = "Drupal\flag\Form\FlaggingConfirmForm", + * } + * }, * entity_keys = { * "id" = "id", * "bundle" = "type", diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php new file mode 100644 index 0000000..a18daf8 --- /dev/null +++ b/src/Form/FlaggingForm.php @@ -0,0 +1,44 @@ +setRedirect('content_entity_example.contact_list'); + + return $entity; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + $entity = $this->entity; + $entity->save(); + } +} diff --git a/src/Plugin/ActionLink/FieldEntry.php b/src/Plugin/ActionLink/FieldEntry.php new file mode 100644 index 0000000..57c4091 --- /dev/null +++ b/src/Plugin/ActionLink/FieldEntry.php @@ -0,0 +1,134 @@ + 'fieldset', + '#title' => t('Options for the "Confirmation form" link type'), + // Any "link type" provider module must put its settings fields inside + // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is + // the machine-name of the link type. This is necessary for the + // radiobutton's JavaScript dependency feature to work. + '#id' => 'link-options-field_entry', + ]; + + $form['display']['settings']['link_options_field']['flag_confirmation'] = [ + '#type' => 'textfield', + '#title' => t('Flag confirmation message'), + '#default_value' => $this->configuration['flag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ]; + + $form['display']['settings']['link_options_field']['unflag_confirmation'] = [ + '#type' => 'textfield', + '#title' => t('Unflag confirmation message'), + '#default_value' => $this->configuration['unflag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ]; +*/ + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + /* $form_values = $form_state['values']; + + if ($form_values['link_type'] == 'confirm') { + if (empty($form_values['flag_confirmation'])) { + $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the confirmation link type.'); + } + if (empty($form_values['unflag_confirmation'])) { + $form_state->setErrorByName('unflag_confirmation', 'An unflag confirmation message is required when using the confirmation link type.'); + } + } + + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { + $form_state->setErrorByName('label', 'The flag name may only contain lowercase letters, underscores, and numbers.'); + } + */ + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + parent::submitConfigurationForm($form, $form_state); + /* + $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; + $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; + */ + } + + /** + * Returns the flag confirm form question when flagging. + * + * @return string + * A string containing the flag question to display. + */ + public function getFlagQuestion() { + return $this->configuration['flag_confirmation']; + } + + /** + * Returns the flag confirm form question when unflagging. + * + * @return string + * A string containing the unflag question to display. + */ + public function getUnflagQuestion() { + return $this->configuration['unflag_confirmation']; + } +} From c5d8cd3ea2c1619cd7aeb886a059c55f0e5fdf9c Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 9 Sep 2014 23:47:03 -0500 Subject: [PATCH 563/629] Fixed incorrect handlers annotation. --- src/Entity/Flagging.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 2df8812..2bd5a5e 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -23,7 +23,7 @@ * fieldable = TRUE, * bundle_entity_type = "flag", * field_ui_base_route = "flag.edit", - * controllers = { + * handlers = { * "form" = { * "add" = "Drupal\flag\Form\FlaggingForm", * "edit" = "Drupal\flag\Form\FlaggingForm", From e24cadf316e2460ca15a8db0191b66dee65ededb Mon Sep 17 00:00:00 2001 From: Tim Plunkett Date: Fri, 12 Sep 2014 00:01:08 -0700 Subject: [PATCH 564/629] Remove usage of FormState as an array. --- flag.module | 2 +- src/Form/FlagAddPageForm.php | 4 ++-- src/Form/FlagFormBase.php | 4 ++-- src/Plugin/ActionLink/ConfirmForm.php | 6 +++--- src/Plugin/Flag/CommentFlagType.php | 2 +- src/Plugin/Flag/EntityFlagType.php | 8 ++++---- src/Plugin/Flag/NodeFlagType.php | 4 ++-- src/Plugin/Flag/UserFlagType.php | 4 ++-- src/Plugin/views/relationship/FlagViewsRelationship.php | 1 - 9 files changed, 17 insertions(+), 18 deletions(-) diff --git a/flag.module b/flag.module index 1d57ffc..9759d1c 100644 --- a/flag.module +++ b/flag.module @@ -236,7 +236,7 @@ function flag_entity_extra_field_info() { *//* function flag_form_node_type_form_alter(&$form, FormStateInterface $form_state, $form_id) { global $user; - $node_type = $form_state['controller']->getEntity(); + $node_type = $form_state->getFormObject()->getEntity(); $flags = \Drupal::service('flag')->getFlags('node', $node_type->id(), $user); foreach ($flags as $flag) { // @todo: Revisit when form functionality is implemented. diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index 6eaecf6..8f20314 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -102,11 +102,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { */ public function validateForm(array &$form, FormStateInterface $form_state) { /* - $flag = AbstractFlag::factory_by_entity_type($form_state['values']['type']); + $flag = AbstractFlag::factory_by_entity_type($form_state->getValue('type')); if (get_class($flag) == 'BrokenFlag') { form_set_error('type', t("This flag type, %type, isn't valid.", - array('%type' => $form_state['values']['type']))); + array('%type' => $form_state->getValue('type')))); } */ } diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 5d0a688..2b7f0e1 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -233,7 +233,7 @@ public function updateSelectedPluginType($form, FormStateInterface $form_state) $action_link_plugin = $flag->getLinkTypePlugin(); $form = $action_link_plugin->buildConfigurationForm($form, $form_state); - $form_state['rebuild'] = TRUE; + $form_state->setRebuild(); return $form['display']['settings']; } @@ -242,7 +242,7 @@ public function updateSelectedPluginType($form, FormStateInterface $form_state) * Handles submit call when sensor type is selected. */ public function submitSelectPlugin(array $form, FormStateInterface $form_state) { - $form_state['rebuild'] = TRUE; + $form_state->setRebuild(); } /** diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index 960e6b8..97f3417 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -86,7 +86,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * {@inheritdoc} */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { - $form_values = $form_state['values']; + $form_values = $form_state->getValues(); if ($form_values['link_type'] == 'confirm') { if (empty($form_values['flag_confirmation'])) { @@ -107,8 +107,8 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); - $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; - $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; + $this->configuration['flag_confirmation'] = $form_state->getValue('flag_confirmation'); + $this->configuration['unflag_confirmation'] = $form_state->getValue('unflag_confirmation'); } /** diff --git a/src/Plugin/Flag/CommentFlagType.php b/src/Plugin/Flag/CommentFlagType.php index 388afb0..efc171c 100644 --- a/src/Plugin/Flag/CommentFlagType.php +++ b/src/Plugin/Flag/CommentFlagType.php @@ -65,7 +65,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); - $this->configuration['access_author'] = $form_state['values']['access_author']; + $this->configuration['access_author'] = $form_state->getValue('access_author'); } /** diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 006abea..915d0a0 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -130,10 +130,10 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); - $this->configuration['show_in_links'] = $form_state['values']['show_in_links']; - $this->configuration['show_as_field'] = $form_state['values']['show_as_field']; - $this->configuration['show_on_form'] = $form_state['values']['show_on_form']; - $this->configuration['show_contextual_link'] = $form_state['values']['show_contextual_link']; + $this->configuration['show_in_links'] = $form_state->getValue('show_in_links'); + $this->configuration['show_as_field'] = $form_state->getValue('show_as_field'); + $this->configuration['show_on_form'] = $form_state->getValue('show_on_form'); + $this->configuration['show_contextual_link'] = $form_state->getValue('show_contextual_link'); } /** diff --git a/src/Plugin/Flag/NodeFlagType.php b/src/Plugin/Flag/NodeFlagType.php index 7ffaea7..bbc6d25 100644 --- a/src/Plugin/Flag/NodeFlagType.php +++ b/src/Plugin/Flag/NodeFlagType.php @@ -79,8 +79,8 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); - $this->configuration['access_author'] = $form_state['values']['access_author']; - $this->configuration['i18n'] = $form_state['values']['i18n']; + $this->configuration['access_author'] = $form_state->getValue('access_author'); + $this->configuration['i18n'] = $form_state->getValue('i18n'); } /** diff --git a/src/Plugin/Flag/UserFlagType.php b/src/Plugin/Flag/UserFlagType.php index eb95ccf..7a20549 100644 --- a/src/Plugin/Flag/UserFlagType.php +++ b/src/Plugin/Flag/UserFlagType.php @@ -73,8 +73,8 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); - $this->configuration['access_uid'] = $form_state['values']['access']['access_uid']; - $this->configuration['show_on_profile'] = $form_state['values']['display']['show_on_profile']; + $this->configuration['access_uid'] = $form_state->getValue(['access', 'access_uid']); + $this->configuration['show_on_profile'] = $form_state->getValue(['display', 'show_on_profile']); } /** diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 882fd2d..c8c93da 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -72,7 +72,6 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', ['%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH)]) . '

', ], ]; - $form_state['no flags exist'] = TRUE; } } From 398dba0a2633644f25343670bf285c8b43e2b61d Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 13 Sep 2014 21:53:11 -0500 Subject: [PATCH 565/629] Updated routing. --- flag.routing.yml | 2 +- src/Entity/Flagging.php | 17 ++++++++++------- src/Form/FlaggingForm.php | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index 2fc3f72..6162242 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -89,7 +89,7 @@ flag.confirm_unflag: flag.field_entry: path: '/flag/details/flag/{flag_id}/{entity_id}' defaults: - _form: '\Drupal\flag\Form\FlaggingForm' + _entity_form: flagging.add _title: 'Enter Flag Details' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 2bd5a5e..d3cdab0 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -19,26 +19,29 @@ * @ContentEntityType( * id = "flagging", * label = @Translation("Flagging"), - * base_table = "flagging", - * fieldable = TRUE, - * bundle_entity_type = "flag", - * field_ui_base_route = "flag.edit", + * bundle_label = @Translation("Flagging"), * handlers = { * "form" = { * "add" = "Drupal\flag\Form\FlaggingForm", * "edit" = "Drupal\flag\Form\FlaggingForm", - * "delete" = "Drupal\flag\Form\FlaggingConfirmForm", + * "delete" = "Drupal\flag\Form\FlaggingConfirmForm" * } * }, + * base_table = "flagging", + * data_table = "flagging_data", + * fieldable = TRUE, * entity_keys = { * "id" = "id", * "bundle" = "type", * "uuid" = "uuid" - * } + * }, + * bundle_entity_type = "flag", + * field_ui_base_route = "flag.edit" * ) */ class Flagging extends ContentEntityBase implements FlaggingInterface { - + // @todo should there be a data_table annotation? + // @todo should the bundle entity_key annotation be "flag" not "type"? /** * Gets the flag ID for the parent flag. * diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index a18daf8..f70fa9c 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -27,7 +27,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function submit(array $form, FormStateInterface $form_state) { + public function submitForm(array &$form, FormStateInterface $form_state) { $entity = parent::submit($form, $form_state); // $form_state->setRedirect('content_entity_example.contact_list'); From e23a127d0e7d10a59ed974ac44045c05c0e17b60 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 9 Sep 2014 20:17:26 -0500 Subject: [PATCH 566/629] Initial broken Flagging field entry link type. --- flag.routing.yml | 9 ++ src/Controller/FieldEntryFormController.php | 59 +++++++++ src/Entity/Flagging.php | 7 + src/Form/FlaggingForm.php | 44 +++++++ src/Plugin/ActionLink/FieldEntry.php | 134 ++++++++++++++++++++ 5 files changed, 253 insertions(+) create mode 100644 src/Controller/FieldEntryFormController.php create mode 100644 src/Form/FlaggingForm.php create mode 100644 src/Plugin/ActionLink/FieldEntry.php diff --git a/flag.routing.yml b/flag.routing.yml index 8afef14..2fc3f72 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -86,4 +86,13 @@ flag.confirm_unflag: requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkUnflag' +flag.field_entry: + path: '/flag/details/flag/{flag_id}/{entity_id}' + defaults: + _form: '\Drupal\flag\Form\FlaggingForm' + _title: 'Enter Flag Details' + requirements: + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + + diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php new file mode 100644 index 0000000..9d22543 --- /dev/null +++ b/src/Controller/FieldEntryFormController.php @@ -0,0 +1,59 @@ +getForm($flag, 'default'); + } +} diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 0362f56..2df8812 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -23,6 +23,13 @@ * fieldable = TRUE, * bundle_entity_type = "flag", * field_ui_base_route = "flag.edit", + * controllers = { + * "form" = { + * "add" = "Drupal\flag\Form\FlaggingForm", + * "edit" = "Drupal\flag\Form\FlaggingForm", + * "delete" = "Drupal\flag\Form\FlaggingConfirmForm", + * } + * }, * entity_keys = { * "id" = "id", * "bundle" = "type", diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php new file mode 100644 index 0000000..a18daf8 --- /dev/null +++ b/src/Form/FlaggingForm.php @@ -0,0 +1,44 @@ +setRedirect('content_entity_example.contact_list'); + + return $entity; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + $entity = $this->entity; + $entity->save(); + } +} diff --git a/src/Plugin/ActionLink/FieldEntry.php b/src/Plugin/ActionLink/FieldEntry.php new file mode 100644 index 0000000..57c4091 --- /dev/null +++ b/src/Plugin/ActionLink/FieldEntry.php @@ -0,0 +1,134 @@ + 'fieldset', + '#title' => t('Options for the "Confirmation form" link type'), + // Any "link type" provider module must put its settings fields inside + // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is + // the machine-name of the link type. This is necessary for the + // radiobutton's JavaScript dependency feature to work. + '#id' => 'link-options-field_entry', + ]; + + $form['display']['settings']['link_options_field']['flag_confirmation'] = [ + '#type' => 'textfield', + '#title' => t('Flag confirmation message'), + '#default_value' => $this->configuration['flag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ]; + + $form['display']['settings']['link_options_field']['unflag_confirmation'] = [ + '#type' => 'textfield', + '#title' => t('Unflag confirmation message'), + '#default_value' => $this->configuration['unflag_confirmation'], + '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ]; +*/ + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + /* $form_values = $form_state['values']; + + if ($form_values['link_type'] == 'confirm') { + if (empty($form_values['flag_confirmation'])) { + $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the confirmation link type.'); + } + if (empty($form_values['unflag_confirmation'])) { + $form_state->setErrorByName('unflag_confirmation', 'An unflag confirmation message is required when using the confirmation link type.'); + } + } + + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { + $form_state->setErrorByName('label', 'The flag name may only contain lowercase letters, underscores, and numbers.'); + } + */ + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + parent::submitConfigurationForm($form, $form_state); + /* + $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; + $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; + */ + } + + /** + * Returns the flag confirm form question when flagging. + * + * @return string + * A string containing the flag question to display. + */ + public function getFlagQuestion() { + return $this->configuration['flag_confirmation']; + } + + /** + * Returns the flag confirm form question when unflagging. + * + * @return string + * A string containing the unflag question to display. + */ + public function getUnflagQuestion() { + return $this->configuration['unflag_confirmation']; + } +} From 5bcac22787b8b7dbb902c0042540589a654685f5 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 9 Sep 2014 23:47:03 -0500 Subject: [PATCH 567/629] Fixed incorrect handlers annotation. --- src/Entity/Flagging.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 2df8812..2bd5a5e 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -23,7 +23,7 @@ * fieldable = TRUE, * bundle_entity_type = "flag", * field_ui_base_route = "flag.edit", - * controllers = { + * handlers = { * "form" = { * "add" = "Drupal\flag\Form\FlaggingForm", * "edit" = "Drupal\flag\Form\FlaggingForm", From 06fd1c12b04bfae3d6882a0176a4bb12e0420879 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 13 Sep 2014 21:53:11 -0500 Subject: [PATCH 568/629] Updated routing. --- flag.routing.yml | 2 +- src/Entity/Flagging.php | 17 ++++++++++------- src/Form/FlaggingForm.php | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index 2fc3f72..6162242 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -89,7 +89,7 @@ flag.confirm_unflag: flag.field_entry: path: '/flag/details/flag/{flag_id}/{entity_id}' defaults: - _form: '\Drupal\flag\Form\FlaggingForm' + _entity_form: flagging.add _title: 'Enter Flag Details' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index 2bd5a5e..d3cdab0 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -19,26 +19,29 @@ * @ContentEntityType( * id = "flagging", * label = @Translation("Flagging"), - * base_table = "flagging", - * fieldable = TRUE, - * bundle_entity_type = "flag", - * field_ui_base_route = "flag.edit", + * bundle_label = @Translation("Flagging"), * handlers = { * "form" = { * "add" = "Drupal\flag\Form\FlaggingForm", * "edit" = "Drupal\flag\Form\FlaggingForm", - * "delete" = "Drupal\flag\Form\FlaggingConfirmForm", + * "delete" = "Drupal\flag\Form\FlaggingConfirmForm" * } * }, + * base_table = "flagging", + * data_table = "flagging_data", + * fieldable = TRUE, * entity_keys = { * "id" = "id", * "bundle" = "type", * "uuid" = "uuid" - * } + * }, + * bundle_entity_type = "flag", + * field_ui_base_route = "flag.edit" * ) */ class Flagging extends ContentEntityBase implements FlaggingInterface { - + // @todo should there be a data_table annotation? + // @todo should the bundle entity_key annotation be "flag" not "type"? /** * Gets the flag ID for the parent flag. * diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index a18daf8..f70fa9c 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -27,7 +27,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - public function submit(array $form, FormStateInterface $form_state) { + public function submitForm(array &$form, FormStateInterface $form_state) { $entity = parent::submit($form, $form_state); // $form_state->setRedirect('content_entity_example.contact_list'); From 568a2088dbfe2d5b84810da1057ac8bae624ffe0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 14 Sep 2014 21:41:33 -0500 Subject: [PATCH 569/629] Working flagging field creation form. --- flag.routing.yml | 2 +- src/Controller/FieldEntryFormController.php | 15 +++++++++++++++ src/Entity/Flagging.php | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/flag.routing.yml b/flag.routing.yml index 6162242..b7f0290 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -89,7 +89,7 @@ flag.confirm_unflag: flag.field_entry: path: '/flag/details/flag/{flag_id}/{entity_id}' defaults: - _entity_form: flagging.add + _content: '\Drupal\flag\Controller\FieldEntryFormController::flag' _title: 'Enter Flag Details' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php index 9d22543..b7b44bf 100644 --- a/src/Controller/FieldEntryFormController.php +++ b/src/Controller/FieldEntryFormController.php @@ -7,6 +7,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\flag\FlagInterface; +use Drupal\flag\Entity\Flag; /** * Provides a controller for the Field Entry link type. @@ -29,6 +30,20 @@ class FieldEntryFormController extends ControllerBase { * @see \Drupal\flag\Plugin\ActionLink\AJAXactionLink */ public function flag($flag_id, $entity_id) { + $account = $this->currentUser(); + $flag = Flag::load($flag_id); + + $flagging = $this->entityManager()->getStorage('flagging')->create([ + 'fid' => $flag->id(), + 'entity_type' => $flag->getFlaggableEntityType(), + 'entity_id' => $entity_id, + 'type' => $flag->id(), + 'uid' => $account->id(), + ]); + + $form = $this->entityFormBuilder()->getForm($flagging); + + return $form; } /** diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index d3cdab0..e705a20 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -22,6 +22,7 @@ * bundle_label = @Translation("Flagging"), * handlers = { * "form" = { + * "default" = "Drupal\flag\Form\FlaggingForm", * "add" = "Drupal\flag\Form\FlaggingForm", * "edit" = "Drupal\flag\Form\FlaggingForm", * "delete" = "Drupal\flag\Form\FlaggingConfirmForm" From 22ddc0e15fc96dac7893079af83cab29025e6ea3 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 14 Sep 2014 22:01:05 -0500 Subject: [PATCH 570/629] Changed getForm() call to include 'add'. --- src/Controller/FieldEntryFormController.php | 2 +- src/Entity/Flagging.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php index b7b44bf..ebf8c04 100644 --- a/src/Controller/FieldEntryFormController.php +++ b/src/Controller/FieldEntryFormController.php @@ -41,7 +41,7 @@ public function flag($flag_id, $entity_id) { 'uid' => $account->id(), ]); - $form = $this->entityFormBuilder()->getForm($flagging); + $form = $this->entityFormBuilder()->getForm($flagging, 'add'); return $form; } diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index e705a20..d3cdab0 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -22,7 +22,6 @@ * bundle_label = @Translation("Flagging"), * handlers = { * "form" = { - * "default" = "Drupal\flag\Form\FlaggingForm", * "add" = "Drupal\flag\Form\FlaggingForm", * "edit" = "Drupal\flag\Form\FlaggingForm", * "delete" = "Drupal\flag\Form\FlaggingConfirmForm" From 6ec5bdfbdfeb494aeb3c84ac440e7e60433012bb Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 15 Sep 2014 17:02:22 -0500 Subject: [PATCH 571/629] Added edit route for flagging field entry. --- flag.routing.yml | 9 +++++++-- src/Controller/FieldEntryFormController.php | 15 +++++++++++++++ src/Plugin/ActionLink/FieldEntry.php | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index b7f0290..10daca5 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -94,5 +94,10 @@ flag.field_entry: requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' - - +flag.field_entry.edit: + path: '/flag/details/edit/{flag_id}/{entity_id}' + defaults: + _content: '\Drupal\flag\Controller\FieldEntryFormController::edit' + _title: 'Enter Flag Details' + requirements: + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' \ No newline at end of file diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php index ebf8c04..b738ce0 100644 --- a/src/Controller/FieldEntryFormController.php +++ b/src/Controller/FieldEntryFormController.php @@ -46,6 +46,17 @@ public function flag($flag_id, $entity_id) { return $form; } + public function edit($flag_id, $entity_id) { + $account = $this->currentUser(); + $flag = \Drupal::service('flag')->getFlagById($flag_id); + $entity = \Drupal::service('flag')->getFlaggableById($entity_id); + $flagging = \Drupal::service('flag')->getFlaggings($entity, $flag, $account); + + $form = $this->entityFormBuilder()->getForm($flagging, 'edit'); + + return $form; + } + /** * Performs an unflagging when called via a route. * @@ -60,6 +71,10 @@ public function flag($flag_id, $entity_id) { * @see \Drupal\flag\Plugin\ActionLink\AJAXactionLink */ public function unflag($flag_id, $entity_id) { + $account = $this->currentUser(); + $flag = Flag::load($flag_id); + + } /** diff --git a/src/Plugin/ActionLink/FieldEntry.php b/src/Plugin/ActionLink/FieldEntry.php index 57c4091..be0ca05 100644 --- a/src/Plugin/ActionLink/FieldEntry.php +++ b/src/Plugin/ActionLink/FieldEntry.php @@ -25,7 +25,7 @@ class FieldEntry extends ActionLinkTypeBase { */ public function routeName($action = NULL) { if ($action == 'unflag') { - return 'flag.confirm_unflag'; + return 'flag.field_entry.edit'; } return 'flag.field_entry'; From 650945e1ddb1395cfcc488f2c3f624b2e0f8b6a4 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 15 Sep 2014 21:31:48 -0500 Subject: [PATCH 572/629] Fixed broken FlaggingConfirmForm. --- src/Form/FlaggingConfirmForm.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index b524313..8e3807f 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -81,10 +81,10 @@ public function getCancelUrl() { */ public function getDescription() { if ($this->isFlagged()) { - return $this->flag->unflag_long; + return $this->flag->getUnflagLongText(); } - return $this->flag->flag_long; + return $this->flag->getFlagLongText(); } /** From 51d499e9b30201a442d9fb1c76c49b11ed5119e9 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 15 Sep 2014 22:18:58 -0500 Subject: [PATCH 573/629] Making flagging fields editable. --- src/Controller/FieldEntryFormController.php | 6 ++++-- src/Entity/Flagging.php | 2 +- src/Form/FlaggingConfirmForm.php | 4 ++-- src/Form/FlaggingForm.php | 7 +++++++ 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php index b738ce0..16690b6 100644 --- a/src/Controller/FieldEntryFormController.php +++ b/src/Controller/FieldEntryFormController.php @@ -49,8 +49,10 @@ public function flag($flag_id, $entity_id) { public function edit($flag_id, $entity_id) { $account = $this->currentUser(); $flag = \Drupal::service('flag')->getFlagById($flag_id); - $entity = \Drupal::service('flag')->getFlaggableById($entity_id); - $flagging = \Drupal::service('flag')->getFlaggings($entity, $flag, $account); + $entity = \Drupal::service('flag')->getFlaggableById($flag, $entity_id); + $flaggings = \Drupal::service('flag')->getFlaggings($entity, $flag, $account); + + $flagging = array_values($flaggings)[0]; $form = $this->entityFormBuilder()->getForm($flagging, 'edit'); diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index d3cdab0..eecb126 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -36,7 +36,7 @@ * "uuid" = "uuid" * }, * bundle_entity_type = "flag", - * field_ui_base_route = "flag.edit" + * field_ui_base_route = "flag.edit", * ) */ class Flagging extends ContentEntityBase implements FlaggingInterface { diff --git a/src/Form/FlaggingConfirmForm.php b/src/Form/FlaggingConfirmForm.php index b524313..8e3807f 100644 --- a/src/Form/FlaggingConfirmForm.php +++ b/src/Form/FlaggingConfirmForm.php @@ -81,10 +81,10 @@ public function getCancelUrl() { */ public function getDescription() { if ($this->isFlagged()) { - return $this->flag->unflag_long; + return $this->flag->getUnflagLongText(); } - return $this->flag->flag_long; + return $this->flag->getFlagLongText(); } /** diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index f70fa9c..1fc428a 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -24,6 +24,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { return $form; } + /** + * {@inheritdoc} + */ + public function actions(array $form, FormStateInterface $form_state) { + + } + /** * {@inheritdoc} */ From 5022a303e5d039ec57be76ac966bdc954a427696 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 15 Sep 2014 22:49:25 -0500 Subject: [PATCH 574/629] Flagging field entry delete link (broken). --- flag.routing.yml | 8 +++ src/Controller/FieldEntryFormController.php | 64 +++++++++++++++------ src/Entity/Flagging.php | 3 + src/Form/FlaggingForm.php | 18 ++++++ 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index 10daca5..f7c78fe 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -99,5 +99,13 @@ flag.field_entry.edit: defaults: _content: '\Drupal\flag\Controller\FieldEntryFormController::edit' _title: 'Enter Flag Details' + requirements: + _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + +flag.field_entry.delete: + path: '/flag/details/unflag/{flag_id}/{entity_id}' + defaults: + _content: '\Drupal\flag\Controller\FieldEntryFormController::unflag' + _title: 'Unflag content' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' \ No newline at end of file diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php index 16690b6..5e9d672 100644 --- a/src/Controller/FieldEntryFormController.php +++ b/src/Controller/FieldEntryFormController.php @@ -6,7 +6,7 @@ namespace Drupal\flag\Controller; use Drupal\Core\Controller\ControllerBase; -use Drupal\flag\FlagInterface; +use Drupal\flag\FlaggingInterface; use Drupal\flag\Entity\Flag; /** @@ -41,22 +41,24 @@ public function flag($flag_id, $entity_id) { 'uid' => $account->id(), ]); - $form = $this->entityFormBuilder()->getForm($flagging, 'add'); - - return $form; + return $this->getForm($flagging, 'add'); } + /** + * Return the flagging edit form. + * + * @param string $flag_id + * The flag ID. + * @param mixed $entity_id + * The entity ID. + * + * @return array + * The flagging edit form. + */ public function edit($flag_id, $entity_id) { - $account = $this->currentUser(); - $flag = \Drupal::service('flag')->getFlagById($flag_id); - $entity = \Drupal::service('flag')->getFlaggableById($flag, $entity_id); - $flaggings = \Drupal::service('flag')->getFlaggings($entity, $flag, $account); - - $flagging = array_values($flaggings)[0]; + $flagging = $this->getFlagging($flag_id, $entity_id); - $form = $this->entityFormBuilder()->getForm($flagging, 'edit'); - - return $form; + return $this->getForm($flagging, 'edit'); } /** @@ -73,19 +75,43 @@ public function edit($flag_id, $entity_id) { * @see \Drupal\flag\Plugin\ActionLink\AJAXactionLink */ public function unflag($flag_id, $entity_id) { - $account = $this->currentUser(); - $flag = Flag::load($flag_id); + $flagging = $this->getFlagging($flag_id, $entity_id); + return $this->getForm($flagging, 'delete'); + } + /** + * Get a flagging that already exists. + * + * @param string $flag_id + * The flag ID. + * @param mixed $entity_id + * The flaggable ID. + * + * @return FlaggingInterface|null + * The flagging or NULL. + */ + protected function getFlagging($flag_id, $entity_id) { + $account = $this->currentUser(); + $flag = \Drupal::service('flag')->getFlagById($flag_id); + $entity = \Drupal::service('flag')->getFlaggableById($flag, $entity_id); + $flaggings = \Drupal::service('flag')->getFlaggings($entity, $flag, $account); + + return array_values($flaggings)[0]; } /** * Get the flag's field entry form. * - * @param FlagInterface $flag - * The flag from which to get the form. + * @param FlaggingInterface $flagging + * The flagging from which to get the form. + * @param string|null $operation + * The operation identifying the form variant to return. + * + * return array + * The form array. */ - protected function getForm(FlagInterface $flag) { - $form = \Drupal::service('entity.form_builder')->getForm($flag, 'default'); + protected function getForm(FlaggingInterface $flagging, $operation = 'default') { + return $this->entityFormBuilder()->getForm($flagging, $operation); } } diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index eecb126..bcf12d9 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -37,6 +37,9 @@ * }, * bundle_entity_type = "flag", * field_ui_base_route = "flag.edit", + * links = { + * "delete-form" = "flag.field_entry.delete" + * } * ) */ class Flagging extends ContentEntityBase implements FlaggingInterface { diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index 1fc428a..827260a 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -28,7 +28,25 @@ public function buildForm(array $form, FormStateInterface $form_state) { * {@inheritdoc} */ public function actions(array $form, FormStateInterface $form_state) { + $actions = parent::actions($form, $form_state); + $actions['submit']['#value'] = $this->t('Update details'); + $route_info = $this->entity->urlInfo('delete-form'); + $actions['delete'] = [ + '#type' => 'link', + '#title' => $this->t('Delete Flagging'), + //'#access' => $this->entity->access('delete'), + '#attributes' => [ + 'class' => ['button', 'button--danger'], + ], + ]; + $actions['delete'] += $route_info->toRenderArray(); + + $actions['delete']['#route_parameters']['flag_id'] = $this->entity->getFlagId(); + $actions['delete']['#route_parameters']['entity_id'] = $this->entity->getFlaggableId(); + + + return $actions; } /** From 27d379526082f684e1a45961dd414cd12dcb4566 Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Tue, 16 Sep 2014 18:21:26 +0100 Subject: [PATCH 575/629] fixes https://github.com/socketwench/flag-drupal8/issues/64 W- SOD on install --- src/ActionLinkPluginManager.php | 2 +- src/FlagTypePluginManager.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ActionLinkPluginManager.php b/src/ActionLinkPluginManager.php index 547fbc7..f577b36 100644 --- a/src/ActionLinkPluginManager.php +++ b/src/ActionLinkPluginManager.php @@ -25,7 +25,7 @@ class ActionLinkPluginManager extends DefaultPluginManager { * {@inheritdoc} */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/ActionLink', $namespaces, $module_handler, 'Drupal\flag\Annotation\ActionLinkType'); + parent::__construct('Plugin/ActionLink', $namespaces, $module_handler, 'Drupal\flag\ActionLinkTypePluginInterface', 'Drupal\flag\Annotation\ActionLinkType'); $this->alterInfo('flag_link_type_info'); $this->setCacheBackend($cache_backend, 'flag_link_type_plugins'); } diff --git a/src/FlagTypePluginManager.php b/src/FlagTypePluginManager.php index 16f9b0a..a648a13 100644 --- a/src/FlagTypePluginManager.php +++ b/src/FlagTypePluginManager.php @@ -29,7 +29,7 @@ class FlagTypePluginManager extends DefaultPluginManager { * The module handler to invoke the alter hook with. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/Flag', $namespaces, $module_handler, 'Drupal\flag\Annotation\FlagType'); + parent::__construct('Plugin/Flag', $namespaces, $module_handler, 'Drupal\flag\FlagTypePluginInterface', 'Drupal\flag\Annotation\FlagType'); // $this->alterInfo('flag_type_info'); $this->setCacheBackend($cache_backend, 'flag'); From ec95ba3b1122dc4db1777e3dbb0d41d2af3b7bf0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 16 Sep 2014 21:03:04 -0500 Subject: [PATCH 576/629] Partially working delete form route. --- flag.routing.yml | 8 -------- src/Entity/Flagging.php | 2 +- src/Form/FlaggingForm.php | 21 ++++++++------------- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index f7c78fe..ab0bb88 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -101,11 +101,3 @@ flag.field_entry.edit: _title: 'Enter Flag Details' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' - -flag.field_entry.delete: - path: '/flag/details/unflag/{flag_id}/{entity_id}' - defaults: - _content: '\Drupal\flag\Controller\FieldEntryFormController::unflag' - _title: 'Unflag content' - requirements: - _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' \ No newline at end of file diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index bcf12d9..dad22a9 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -38,7 +38,7 @@ * bundle_entity_type = "flag", * field_ui_base_route = "flag.edit", * links = { - * "delete-form" = "flag.field_entry.delete" + * "delete-form" = "flag.confirm_unflag" * } * ) */ diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index 827260a..acb8450 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -31,20 +31,15 @@ public function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); $actions['submit']['#value'] = $this->t('Update details'); - $route_info = $this->entity->urlInfo('delete-form'); - $actions['delete'] = [ - '#type' => 'link', - '#title' => $this->t('Delete Flagging'), - //'#access' => $this->entity->access('delete'), - '#attributes' => [ - 'class' => ['button', 'button--danger'], - ], - ]; - $actions['delete'] += $route_info->toRenderArray(); - - $actions['delete']['#route_parameters']['flag_id'] = $this->entity->getFlagId(); - $actions['delete']['#route_parameters']['entity_id'] = $this->entity->getFlaggableId(); + // Customize the delete link. + if (isset($actions['delete'])) { + // @todo Why does the access call always fail? + unset($actions['delete']['#access']); + $actions['delete']['#title'] = $this->t('Delete Flagging'); + $actions['delete']['#route_parameters']['flag_id'] = $this->entity->getFlagId(); + $actions['delete']['#route_parameters']['entity_id'] = $this->entity->getFlaggableId(); + } return $actions; } From b1c861e9bb6def6c41ce8005a59a497946f1f463 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 16 Sep 2014 22:05:27 -0500 Subject: [PATCH 577/629] Added link type options for FieldEntry. Cleaned up the FlaggingForm class. --- src/Form/FlaggingForm.php | 2 +- src/Plugin/ActionLink/FieldEntry.php | 59 +++++++++++++++++++++------- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index acb8450..516ed96 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -21,6 +21,7 @@ class FlaggingForm extends ContentEntityForm { */ public function buildForm(array $form, FormStateInterface $form_state) { $form = parent::buildForm($form, $form_state); + return $form; } @@ -49,7 +50,6 @@ public function actions(array $form, FormStateInterface $form_state) { */ public function submitForm(array &$form, FormStateInterface $form_state) { $entity = parent::submit($form, $form_state); - // $form_state->setRedirect('content_entity_example.contact_list'); return $entity; } diff --git a/src/Plugin/ActionLink/FieldEntry.php b/src/Plugin/ActionLink/FieldEntry.php index be0ca05..def1934 100644 --- a/src/Plugin/ActionLink/FieldEntry.php +++ b/src/Plugin/ActionLink/FieldEntry.php @@ -1,6 +1,7 @@ 'fieldset', - '#title' => t('Options for the "Confirmation form" link type'), + '#title' => t('Options for the "Field entry" link type'), // Any "link type" provider module must put its settings fields inside // a fieldset whose HTML ID is link-options-LINKTYPE, where LINKTYPE is // the machine-name of the link type. This is necessary for the @@ -63,7 +65,16 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#type' => 'textfield', '#title' => t('Flag confirmation message'), '#default_value' => $this->configuration['flag_confirmation'], - '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), + '#description' => t('Message displayed if the user has clicked the "flag this" link and field entry is required. Usually presented in the form such as, "Please enter the flagging details."'), + // This will get changed to a state by flag_link_type_options_states(). + '#required' => TRUE, + ]; + + $form['display']['settings']['link_options_field']['flagging_edit_title'] = [ + '#type' => 'textfield', + '#title' => t('Enter flagging details message'), + '#default_value' => $this->configuration['edit_flagging'], + '#description' => t('Message displayed if the user has clicked the "Edit flag" link. Usually presented in the form such as, "Please enter the flagging details."'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, ]; @@ -72,11 +83,11 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#type' => 'textfield', '#title' => t('Unflag confirmation message'), '#default_value' => $this->configuration['unflag_confirmation'], - '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), + '#description' => t('Message displayed if the user has clicked the "delete flag" link in the field entry form. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, ]; -*/ + return $form; } @@ -84,21 +95,23 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * {@inheritdoc} */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { - /* $form_values = $form_state['values']; + $form_values = $form_state['values']; - if ($form_values['link_type'] == 'confirm') { + if ($form_values['link_type'] == 'field_entry') { if (empty($form_values['flag_confirmation'])) { - $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the confirmation link type.'); + $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the field entry link type.'); + } + if (empty($form_values['flagging_edit_title'])) { + $form_state->setErrorByName('flagging_edit_title', 'An edit flagging details message is required when using the field entry link type.'); } if (empty($form_values['unflag_confirmation'])) { - $form_state->setErrorByName('unflag_confirmation', 'An unflag confirmation message is required when using the confirmation link type.'); + $form_state->setErrorByName('unflag_confirmation', 'An unflag confirmation message is required when using the field entry link type.'); } } if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { $form_state->setErrorByName('label', 'The flag name may only contain lowercase letters, underscores, and numbers.'); } - */ } /** @@ -106,15 +119,18 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); - /* + $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; + $this->configuration['edit_flagging'] = $form_state['values']['flagging_edit_title']; $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; - */ } /** * Returns the flag confirm form question when flagging. * + * We're copying the confirm form link type interface here so we can take + * advantage of the existing confirm form code without duplicating the class. + * * @return string * A string containing the flag question to display. */ @@ -122,9 +138,22 @@ public function getFlagQuestion() { return $this->configuration['flag_confirmation']; } + /** + * Returns the edit flagging details form title. + * + * @return string + * A string containing the edit flagging details title to display. + */ + public function getEditFlaggingTitle() { + return $this->configuration['edit_flagging']; + } + /** * Returns the flag confirm form question when unflagging. * + * We're copying the confirm form link type interface here so we can take + * advantage of the existing confirm form code without duplicating the class. + * * @return string * A string containing the unflag question to display. */ From 1b17e779e018278df4737f29b078b770d4dd64cd Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 16 Sep 2014 22:20:47 -0500 Subject: [PATCH 578/629] Added title callbacks for the field entry flagging create and edit form. --- flag.routing.yml | 4 +-- src/Controller/FieldEntryFormController.php | 34 +++++++++++++++++++++ src/Form/FlaggingForm.php | 2 +- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index ab0bb88..7c1df01 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -90,7 +90,7 @@ flag.field_entry: path: '/flag/details/flag/{flag_id}/{entity_id}' defaults: _content: '\Drupal\flag\Controller\FieldEntryFormController::flag' - _title: 'Enter Flag Details' + _title_callback: '\Drupal\flag\Controller\FieldEntryFormController::flagTitle' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' @@ -98,6 +98,6 @@ flag.field_entry.edit: path: '/flag/details/edit/{flag_id}/{entity_id}' defaults: _content: '\Drupal\flag\Controller\FieldEntryFormController::edit' - _title: 'Enter Flag Details' + _title_callback: '\Drupal\flag\Controller\FieldEntryFormController::editTitle' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php index 5e9d672..bb13dbb 100644 --- a/src/Controller/FieldEntryFormController.php +++ b/src/Controller/FieldEntryFormController.php @@ -80,6 +80,40 @@ public function unflag($flag_id, $entity_id) { return $this->getForm($flagging, 'delete'); } + /** + * Title callback when creating a new flagging. + * + * @param int $flag_id + * The flag ID. + * @param int $entity_id + * The entity ID to unflag. + * + * @return string + * The flag field entry form title. + */ + public function flagTitle($flag_id, $entity_id) { + $flag = \Drupal::service('flag')->getFlagById($flag_id); + $link_type = $flag->getLinkTypePlugin(); + return $link_type->getFlagQuestion(); + } + + /** + * Title callback when editing an existing flagging. + * + * @param int $flag_id + * The flag ID. + * @param int $entity_id + * The entity ID to unflag. + * + * @return string + * The flag field entry form title. + */ + public function editTitle($flag_id, $entity_id) { + $flag = \Drupal::service('flag')->getFlagById($flag_id); + $link_type = $flag->getLinkTypePlugin(); + return $link_type->getEditFlaggingTitle(); + } + /** * Get a flagging that already exists. * diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index 516ed96..a6e2638 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -30,7 +30,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { */ public function actions(array $form, FormStateInterface $form_state) { $actions = parent::actions($form, $form_state); - $actions['submit']['#value'] = $this->t('Update details'); + $actions['submit']['#value'] = $this->t('Update Flagging'); // Customize the delete link. if (isset($actions['delete'])) { From 8275b02e72e965786efe1e623895e68d2b67bb3f Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Wed, 17 Sep 2014 19:02:01 +0100 Subject: [PATCH 579/629] Fixed invalid url in watchdog messages and converted deprecated watchdog function --- src/Form/FlagFormBase.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 22e4862..32e40a1 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -271,11 +271,11 @@ public function save(array $form, FormStateInterface $form_state) { $url = $flag->url(); if ($status == SAVED_UPDATED) { drupal_set_message(t('Flag %label has been updated.', ['%label' => $flag->label()])); - watchdog('flag', 'Flag %label has been updated.', ['%label' => $flag->label()], WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); + $this->logger('flag')->notice('Flag %label has been updated.', ['%label' => $flag->label(), 'link' => l(t('Edit'), $url)]); } else { drupal_set_message(t('Flag %label has been added.', ['%label' => $flag->label()])); - watchdog('flag', 'Flag %label has been added.', ['%label' => $flag->label()], WATCHDOG_NOTICE, l(t('Edit'), $url . '/edit')); + $this->logger('flag')->notice('Flag %label has been added.', ['%label' => $flag->label(), 'link' => l(t('Edit'), $url)]); } // We clear caches more vigorously if the flag was new. From 2399659f41488a56b038b0755842603cc52f9d6f Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 19 Sep 2014 08:57:07 +0200 Subject: [PATCH 580/629] Updated access checks for new AccessResult API, fixes #67" --- flag.module | 20 ++++++++++---------- src/FlaggingAccessController.php | 22 +++++++--------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/flag.module b/flag.module index 9759d1c..556aa07 100644 --- a/flag.module +++ b/flag.module @@ -9,7 +9,7 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); - +use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\flag\Entity\Flag; use Drupal\node\NodeInterface; @@ -457,7 +457,7 @@ function flag_user_account_removal(UserInterface $account) { ->execute(); // Remove flags that have been done to this user. - _flag_entity_delete('user', $account->id()); + //_flag_entity_delete('user', $account->id()); } /** @@ -507,14 +507,14 @@ function flag_flag_access($flag, $entity_id, $action, $account) { // For non-existent nodes (such as on the node add form), assume that the // current user is creating the content. if (empty($entity_id) || !($node = $flag->fetch_entity($entity_id))) { - return $flag->access_author == 'others' ? FALSE : NULL; + return AccessResult::allowedIf($flag->access_author == 'others')->cacheUntilEntityChanges($flag); } if ($flag->access_author == 'own' && $node->uid != $account->uid) { - return FALSE; + return AccessResult::forbidden()->cacheUntilEntityChanges($flag); } elseif ($flag->access_author == 'others' && $node->uid == $account->uid) { - return FALSE; + return AccessResult::forbidden()->cacheUntilEntityChanges($flag); } } @@ -523,21 +523,21 @@ function flag_flag_access($flag, $entity_id, $action, $account) { // For non-existent comments (such as on the comment add form), assume that // the current user is creating the content. if (empty($entity_id) || !($comment = $flag->fetch_entity($entity_id))) { - return $flag->access_author == 'comment_others' ? FALSE : NULL; + return $flag->access_author == 'comment_others' ? AccessResult::forbidden()->cacheUntilEntityChanges($flag) : NULL; } $node = node_load($comment->nid); if ($flag->access_author == 'node_own' && $node->uid != $account->uid) { - return FALSE; + return AccessResult::forbidden()->cacheUntilEntityChanges($flag); } elseif ($flag->access_author == 'node_others' && $node->uid == $account->uid) { - return FALSE; + return AccessResult::forbidden()->cacheUntilEntityChanges($flag); } elseif ($flag->access_author == 'comment_own' && $comment->uid != $account->uid) { - return FALSE; + return AccessResult::forbidden()->cacheUntilEntityChanges($flag); } elseif ($flag->access_author == 'comment_others' && $comment->uid == $account->uid) { - return FALSE; + return AccessResult::forbidden()->cacheUntilEntityChanges($flag); } } } diff --git a/src/FlaggingAccessController.php b/src/FlaggingAccessController.php index b239a70..1338df0 100644 --- a/src/FlaggingAccessController.php +++ b/src/FlaggingAccessController.php @@ -6,7 +6,7 @@ namespace Drupal\flag; -use Drupal\Core\Access\AccessInterface; +use Drupal\Core\Access\AccessResult; use Drupal\Core\Controller\ControllerBase; use Drupal\flag\Entity\Flag; use Symfony\Component\HttpFoundation\Request; @@ -25,13 +25,9 @@ class FlaggingAccessController extends ControllerBase { * @return string * Returns indication value for flagging access permission. */ - public function checkFlag(Request $request) { - $flag = Flag::load($request->get('flag_id')); - if ($flag->hasActionAccess('flag')) { - return AccessInterface::ALLOW; - } - - return AccessInterface::DENY; + public function checkFlag($flag_id) { + $flag = Flag::load($flag_id); + return AccessResult::allowedIf($flag->hasActionAccess('flag')); } /** @@ -43,13 +39,9 @@ public function checkFlag(Request $request) { * @return string * Returns indication value for unflagging access permission. */ - public function checkUnflag(Request $request) { - $flag = Flag::load($request->get('flag_id')); - if ($flag->hasActionAccess('unflag')) { - return AccessInterface::ALLOW; - } - - return AccessInterface::DENY; + public function checkUnflag($flag_id) { + $flag = Flag::load($flag_id); + return AccessResult::allowedIf($flag->hasActionAccess('unflag')); } } From 0a123ba4d8adfdaa98f360536282e428b727604e Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Sat, 20 Sep 2014 11:45:56 +0100 Subject: [PATCH 581/629] https://github.com/socketwench/flag-drupal8/issues/69 Three unterminated lines. --- theme/flag.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/theme/flag.js b/theme/flag.js index 27cb150..6588c1b 100644 --- a/theme/flag.js +++ b/theme/flag.js @@ -117,11 +117,11 @@ Drupal.flagAnonymousLinks = function(context) { this.href += (this.href.match(/\?/) ? '&' : '?') + 'has_js=1'; $(this).addClass('flag-anonymous-processed'); }); -} +}; String.prototype.flagNameToCSS = function() { return this.replace(/_/g, '-'); -} +}; /** * A behavior specifically for anonymous users. Update links to the proper state. @@ -166,7 +166,7 @@ Drupal.flagAnonymousLinkTemplates = function(context) { } } } -} +}; /** * Utility function used to set Flag cookies. From 3e363702f4231c5887282f6481b49f1e398d123e Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Sat, 20 Sep 2014 12:04:36 +0100 Subject: [PATCH 582/629] use String::checkPlain --- flag.module | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/flag.module b/flag.module index 556aa07..546d3df 100644 --- a/flag.module +++ b/flag.module @@ -9,6 +9,8 @@ define('FLAG_API_VERSION', 3); define('FLAG_ADMIN_PATH', 'admin/structure/flags'); define('FLAG_ADMIN_PATH_START', 3); + +use Drupal\Component\Utility\String; use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\flag\Entity\Flag; @@ -685,7 +687,7 @@ function template_preprocess_flag(&$variables) { $link_type = $flag->get_link_type(); $link = module_invoke($link_type['module'], 'flag_link', $flag, $action, $entity_id); if (isset($link['title']) && empty($link['html'])) { - $link['title'] = check_plain($link['title']); + $link['title'] = String::checkPlain($link['title']); } // Replace the link with the access denied text if unable to flag. @@ -713,7 +715,7 @@ function template_preprocess_flag(&$variables) { $variables['link'] = $link; $variables['link_href'] = isset($link['href']) ? check_url(url($link['href'], $link)) : FALSE; $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $entity_id); - $variables['link_title'] = isset($link['attributes']['title']) ? check_plain($link['attributes']['title']) : check_plain(strip_tags($flag->get_label($action . '_long', $entity_id))); + $variables['link_title'] = isset($link['attributes']['title']) ? String::checkPlain($link['attributes']['title']) : String::checkPlain(strip_tags($flag->get_label($action . '_long', $entity_id))); $variables['status'] = ($action == 'flag' ? 'unflagged' : 'flagged'); $variables['flag_name_css'] = $flag_css_name; From 2851443cb1f09ed20f96fb9df47ddceb91e7feae Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 21 Sep 2014 21:58:26 -0500 Subject: [PATCH 583/629] Updated FieldEntry to use FormState::getValue(). --- src/Controller/FieldEntryFormController.php | 2 +- src/Form/FlaggingForm.php | 9 --------- src/Plugin/ActionLink/FieldEntry.php | 6 ++---- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/Controller/FieldEntryFormController.php b/src/Controller/FieldEntryFormController.php index bb13dbb..e3f4577 100644 --- a/src/Controller/FieldEntryFormController.php +++ b/src/Controller/FieldEntryFormController.php @@ -131,7 +131,7 @@ protected function getFlagging($flag_id, $entity_id) { $entity = \Drupal::service('flag')->getFlaggableById($flag, $entity_id); $flaggings = \Drupal::service('flag')->getFlaggings($entity, $flag, $account); - return array_values($flaggings)[0]; + return reset($flaggings); } /** diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index a6e2638..af8136a 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -45,15 +45,6 @@ public function actions(array $form, FormStateInterface $form_state) { return $actions; } - /** - * {@inheritdoc} - */ - public function submitForm(array &$form, FormStateInterface $form_state) { - $entity = parent::submit($form, $form_state); - - return $entity; - } - /** * {@inheritdoc} */ diff --git a/src/Plugin/ActionLink/FieldEntry.php b/src/Plugin/ActionLink/FieldEntry.php index def1934..cdb82a0 100644 --- a/src/Plugin/ActionLink/FieldEntry.php +++ b/src/Plugin/ActionLink/FieldEntry.php @@ -95,9 +95,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * {@inheritdoc} */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { - $form_values = $form_state['values']; - - if ($form_values['link_type'] == 'field_entry') { + if ($form_state->getValue('link_type') == 'field_entry') { if (empty($form_values['flag_confirmation'])) { $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the field entry link type.'); } @@ -109,7 +107,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form } } - if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_values['id'])) { + if (!preg_match('/^[a-z_][a-z0-9_]*$/', $form_state->getValue('id'))) { $form_state->setErrorByName('label', 'The flag name may only contain lowercase letters, underscores, and numbers.'); } } From 398d3eb7cb09859c7f49aee57322a2cd05cd05e6 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 23 Sep 2014 17:12:41 -0500 Subject: [PATCH 584/629] Fixed permissions due to https://www.drupal.org/node/2311427 --- flag.module | 20 -------------------- flag.permissions.yml | 7 +++++++ src/FlagPermissions.php | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 flag.permissions.yml create mode 100644 src/FlagPermissions.php diff --git a/flag.module b/flag.module index 546d3df..cf41bea 100644 --- a/flag.module +++ b/flag.module @@ -155,26 +155,6 @@ function flag_help($route_name, RouteMatchInterface $route_match) { } } -/** - * Implements hook_permission(). - */ -function flag_permission() { - $permissions = [ - 'administer flags' => [ - 'title' => t('Administer flags'), - 'description' => t('Create and edit site-wide flags.'), - ], - ]; - - $flags = \Drupal::service('flag')->getFlags(); - // Provide flag and unflag permissions for each flag. - foreach ($flags as $flag_name => $flag) { - $permissions += $flag->getPermissions(); - } - - return $permissions; -} - /** * Implements hook_form_FORM_ID_alter(): user_admin_permissions(). * diff --git a/flag.permissions.yml b/flag.permissions.yml new file mode 100644 index 0000000..4f54d65 --- /dev/null +++ b/flag.permissions.yml @@ -0,0 +1,7 @@ +administer flag: + title: 'Administer Flag' + decription: 'Define and manage Flags and Flag settings.' + restrict access: TRUE + +permission_callbacks: + - Drupal\flag\FlagPermissions::permissions \ No newline at end of file diff --git a/src/FlagPermissions.php b/src/FlagPermissions.php new file mode 100644 index 0000000..014b89f --- /dev/null +++ b/src/FlagPermissions.php @@ -0,0 +1,24 @@ +getFlags(); + // Provide flag and unflag permissions for each flag. + foreach ($flags as $flag_name => $flag) { + $permissions += $flag->getPermissions(); + } + + return $permissions; + } +} From 5154cccf00fd1ee342bc6829403f7345b332156b Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 23 Sep 2014 22:47:49 -0500 Subject: [PATCH 585/629] Fixed permission name typo that was breaking tests. --- flag.permissions.yml | 4 ++-- src/Tests/FlagSimpleTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flag.permissions.yml b/flag.permissions.yml index 4f54d65..4f4a6a3 100644 --- a/flag.permissions.yml +++ b/flag.permissions.yml @@ -1,5 +1,5 @@ -administer flag: - title: 'Administer Flag' +administer flags: + title: 'Administer Flags' decription: 'Define and manage Flags and Flag settings.' restrict access: TRUE diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index 99b0538..d2a9604 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -67,7 +67,7 @@ public function testFlagForm() { // Create and log in our user. $this->adminUser = $this->drupalCreateUser([ 'administer flags', - 'administer node display', + 'administer flagging display', ]); $this->drupalLogin($this->adminUser); From cc93e53334c177851d8d52c943f5debb8a4057f6 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 24 Sep 2014 11:00:54 -0500 Subject: [PATCH 586/629] Fixed incorrect role markup in FlagListController. --- src/Controller/FlagListController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 872cae4..93f33d8 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -9,6 +9,7 @@ use Drupal\Core\Config\Entity\ConfigEntityListBuilder; use Drupal\Core\Entity\EntityInterface; use Drupal\flag\FlagInterface; +use Drupal\Component\Utility\String; /** * Provides a entity list page for Flags. @@ -52,7 +53,7 @@ protected function getFlagRoles(FlagInterface $flag) { $out = implode(', ', $all_roles); if (empty($out)) { - return 'None'; + return String::placeHolder($this->t('None')); } return rtrim($out, ', '); From 43e4f6df8e0802ca09be4d5e6bf747970faceae0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 24 Sep 2014 12:49:53 -0500 Subject: [PATCH 587/629] Added documentation to FlagPermissions. --- src/FlagPermissions.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/FlagPermissions.php b/src/FlagPermissions.php index 014b89f..99a04b1 100644 --- a/src/FlagPermissions.php +++ b/src/FlagPermissions.php @@ -1,19 +1,32 @@ getFlags(); + // Provide flag and unflag permissions for each flag. foreach ($flags as $flag_name => $flag) { $permissions += $flag->getPermissions(); From da7580ad87fc631a2f0b2f448c229032934934ba Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 24 Sep 2014 16:45:43 -0500 Subject: [PATCH 588/629] Added validation and changed default values for the EntityFlagType plugin. --- src/Plugin/Flag/EntityFlagType.php | 34 +++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 915d0a0..2373f70 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -51,7 +51,7 @@ public function defaultConfiguration() { // @see hook_entity_view(). 'show_in_links' => [], // Output the flag as individual pseudofields. - 'show_as_field' => FALSE, + 'show_as_field' => TRUE, // Add a checkbox for the flag in the entity form. // @see hook_field_attach_form(). 'show_on_form' => FALSE, @@ -125,6 +125,38 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta return $form; } + /** + * {@inheritdoc} + */ + public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + $form_values = $form_state->getValues(); + + // Check each of the display modes for the show_in_links field. + foreach ($form_values['show_in_links'] as $link_display) { + if (!empty($link_display)) { + return; + } + } + + // Check if the user selected display as a psudofield. + if (!empty($form_values['show_as_field'])) { + return; + } + + // Check if the user selected display on the entity edit form. + if (!empty($form_values['show_on_form'])) { + return; + } + + // Check if the user selected display as a contextual link. + if (!empty($form_values['show_contextual_link'])) { + return; + } + + // If we're still here, no display was selected. Return a form error. + $form_state->setErrorByName('show_as_field', 'No entity link display selected. Please select at least one link display such as \'Display link as field\'.'); + } + /** * {@inheritdoc} */ From 126af38c7b28e6db1bd0c58cf643ea84c30cfd9c Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 24 Sep 2014 16:46:14 -0500 Subject: [PATCH 589/629] Fixed missing node display permission that was causing tests to fail. --- src/Tests/FlagSimpleTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tests/FlagSimpleTest.php b/src/Tests/FlagSimpleTest.php index d2a9604..2d99134 100644 --- a/src/Tests/FlagSimpleTest.php +++ b/src/Tests/FlagSimpleTest.php @@ -68,6 +68,7 @@ public function testFlagForm() { $this->adminUser = $this->drupalCreateUser([ 'administer flags', 'administer flagging display', + 'administer node display', ]); $this->drupalLogin($this->adminUser); From d2b1927582821e4211015662be8fa850e7787170 Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Sun, 28 Sep 2014 17:00:17 +0100 Subject: [PATCH 590/629] node_load is deperecated. --- flag.module | 2 +- src/Entity/Flagging.php | 4 ++-- src/FlagService.php | 12 ++++++------ src/Form/FlagAddPageForm.php | 2 +- src/Form/FlagFormBase.php | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/flag.module b/flag.module index cf41bea..351e54b 100644 --- a/flag.module +++ b/flag.module @@ -508,7 +508,7 @@ function flag_flag_access($flag, $entity_id, $action, $account) { return $flag->access_author == 'comment_others' ? AccessResult::forbidden()->cacheUntilEntityChanges($flag) : NULL; } - $node = node_load($comment->nid); + $node = \Drupal::entityManager()->getStorage('node')->load($comment->nid); if ($flag->access_author == 'node_own' && $node->uid != $account->uid) { return AccessResult::forbidden()->cacheUntilEntityChanges($flag); } diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index dad22a9..2d46eaf 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -62,7 +62,7 @@ public function getFlagId() { * The flag related this this flagging. */ public function getFlag() { - return entity_load('flag', $this->getFlagId()); + return $this->entityManager()->getStorage('flag')->load($this->getFlagId()); } /** @@ -92,7 +92,7 @@ public function getFlaggableId() { * The flaggable entity. */ public function getFlaggable() { - return entity_load($this->getFlaggableType(), $this->getFlaggableId()); + return $this->entityManager()->getStorage($this->getFlaggableType())->load($this->getFlaggableId()); } /** diff --git a/src/FlagService.php b/src/FlagService.php index 78a93f8..77f734d 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -133,7 +133,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ $result = $query->execute(); - $flags = entity_load_multiple('flag', $result); + $flags = $this->entityMgr->getStorage('flag')->load($result); if ($account == NULL) { return $flags; @@ -185,7 +185,7 @@ public function getFlaggings(EntityInterface $entity = NULL, FlagInterface $flag $flaggings = []; foreach ($result as $flagging_id) { - $flaggings[$flagging_id] = entity_load('flagging', $flagging_id); + $flaggings[$flagging_id] = $this->entityMgr->getStorage('flagging')->load($flagging_id); } return $flaggings; @@ -201,7 +201,7 @@ public function getFlaggings(EntityInterface $entity = NULL, FlagInterface $flag * The flag entity. */ public function getFlagById($flag_id) { - return entity_load('flag', $flag_id); + return $this->entityMgr->getStorage('flag')->load($flag_id); } /** @@ -216,7 +216,7 @@ public function getFlagById($flag_id) { * The flaggable entity object. */ public function getFlaggableById(FlagInterface $flag, $entity_id) { - return entity_load($flag->getFlaggableEntityType(), $entity_id); + return $this->entityMgr->getStorage($flag->getFlaggableEntityType())->load($entity_id); } /** @@ -243,7 +243,7 @@ public function getFlaggingUsers(EntityInterface $entity, FlagInterface $flag = $flaggings = []; foreach ($result as $flagging_id) { - $flaggings[$flagging_id] = entity_load('flagging', $flagging_id); + $flaggings[$flagging_id] = $this->entityManager->getStorage('flagging')->load($flagging_id); } return $flaggings; @@ -268,7 +268,7 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $account = $this->currentUser; } - $flagging = entity_create('flagging', [ + $flagging = $this->entityMgr->getStorage('flagging')->create([ 'type' => 'flag', 'uid' => $account->id(), 'fid' => $flag->id(), diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index 8f20314..a2c0c53 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -134,6 +134,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) { */ public function exists($id) { // @todo: Make this injected like ActionFormBase::exists(). - return entity_load('flag', $id); + return \Drupal::entityManager()->getStorage('flag')->load($id); } } diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 32e40a1..5ff0428 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -329,7 +329,7 @@ public function delete(array $form, FormStateInterface $form_state) { */ public function exists($id) { // @todo: Make this injected like ActionFormBase::exists(). - return entity_load('flag', $id); + return \Drupal::entityManager()->getStorage('flag')->load($id); } } From 5f59ba74254ccf835eeba86c84939a3e47a05bc9 Mon Sep 17 00:00:00 2001 From: Martin Frances Date: Sun, 28 Sep 2014 17:27:54 +0100 Subject: [PATCH 591/629] node_load is deprecated - bug fix --- src/FlagService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FlagService.php b/src/FlagService.php index 77f734d..dbbe0cc 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -133,7 +133,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ $result = $query->execute(); - $flags = $this->entityMgr->getStorage('flag')->load($result); + $flags = $this->entityMgr->getStorage('flag')->loadMultiple($result); if ($account == NULL) { return $flags; From 2d12a05930779f15a9e3661b381b0f5692521330 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Sep 2014 16:26:52 -0500 Subject: [PATCH 592/629] Fixed missing default configuration for ActionLinkTypeBase. --- src/ActionLinkTypeBase.php | 3 +-- src/Plugin/ActionLink/ConfirmForm.php | 10 ++++++---- src/Tests/FlagConfirmFormTest.php | 11 +++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 src/Tests/FlagConfirmFormTest.php diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 59bdc9b..520d9fa 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -38,8 +38,7 @@ abstract class ActionLinkTypeBase extends PluginBase implements ActionLinkTypePl */ public function __construct(array $configuration, $plugin_id, array $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->setConfiguration($configuration); + $this->configuration += $this->defaultConfiguration(); } /** diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index 97f3417..0abdf0f 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -39,8 +39,10 @@ public function routeName($action = NULL) { public function defaultConfiguration() { $options = parent::defaultConfiguration(); - $options['flag_confirmation'] = 'Flag this content?'; - $options['unflag_confirmation'] = 'Unflag this content?'; + $options += [ + 'flag_confirmation' => 'Flag this content?', + 'unflag_confirmation' => 'Unflag this content?', + ]; return $options; } @@ -64,7 +66,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['display']['settings']['link_options_confirm']['flag_confirmation'] = [ '#type' => 'textfield', '#title' => t('Flag confirmation message'), - '#default_value' => $this->configuration['flag_confirmation'], + '#default_value' => $this->getFlagQuestion(), '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, @@ -73,7 +75,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['display']['settings']['link_options_confirm']['unflag_confirmation'] = [ '#type' => 'textfield', '#title' => t('Unflag confirmation message'), - '#default_value' => $this->configuration['unflag_confirmation'], + '#default_value' => $this->getUnflagQuestion(), '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, diff --git a/src/Tests/FlagConfirmFormTest.php b/src/Tests/FlagConfirmFormTest.php new file mode 100644 index 0000000..94fb369 --- /dev/null +++ b/src/Tests/FlagConfirmFormTest.php @@ -0,0 +1,11 @@ + Date: Sun, 28 Sep 2014 20:38:47 -0500 Subject: [PATCH 593/629] Added initial confirm form test. --- src/Tests/FlagConfirmFormTest.php | 139 +++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/src/Tests/FlagConfirmFormTest.php b/src/Tests/FlagConfirmFormTest.php index 94fb369..7180d8e 100644 --- a/src/Tests/FlagConfirmFormTest.php +++ b/src/Tests/FlagConfirmFormTest.php @@ -1,11 +1,146 @@ adminUser = $this->drupalCreateUser([ + 'administer flags', + 'administer flagging display', + 'administer node display', + ]); + + $this->drupalLogin($this->adminUser); + $this->doCreateFlag(); + $this->doCreateNode(); + } + + /** + * Create a node type and a flag. + */ + public function doCreateFlag() { + // Create content type. + $this->drupalCreateContentType(['type' => $this->nodeType]); + + // Test with minimal value requirement. + $edit = [ + 'label' => $this->label, + 'id' => $this->id, + 'flag_entity_type' => 'flagtype_node', + 'flag_link_type' => 'confirm', + ]; + $this->drupalPostForm('admin/structure/flags/add', $edit, t('Continue')); + + // Check confirm form field entry. + $this->assertText(t('Flag confirmation message')); + $this->assertText(t('Unflag confirmation message')); + + // Update the flag. + $edit = [ + 'types[' . $this->nodeType . ']' => $this->nodeType, + 'flag_confirmation' => $this->flagConfirmMessage, + 'unflag_confirmation' => $this->unflagConfirmMessage, + ]; + $this->drupalPostForm(NULL, $edit, t('Create Flag')); + + // Check to see if the flag was created. + $this->assertText(t('Flag @this_label has been added.', ['@this_label' => $this->label])); + } + + /** + * Create a node and flag it. + */ + public function doCreateNode() { + $node = $this->drupalCreateNode(['type' => $this->nodeType]); + $node_id = $node->id(); + + // Grant the flag permissions to the authenticated role, so that both + // users have the same roles and share the render cache. + $role = Role::load(DRUPAL_AUTHENTICATED_RID); + $role->grantPermission('flag ' . $this->id); + $role->grantPermission('unflag ' . $this->id); + $role->save(); + + // Create and login a new user. + $user_1 = $this->drupalCreateUser(); + $this->drupalLogin($user_1); + + // Click the flag link. + $this->drupalGet('node/' . $node_id); + $this->clickLink('Flag this item'); + + // Check if we have the confirm form message displayed. + $this->assertText($this->flagConfirmMessage); + + // Submit the confirm form. + $this->drupalPostForm('flag/confirm/flag/' . $this->id . '/' . $node_id, [], t('Flag')); + $this->assertResponse(200); + + // Check that the node is flagged. + $this->drupalGet('node/' . $node_id); + $this->assertLink('Unflag this item'); + } -} \ No newline at end of file +} From a17db7245df44ffee07a5698f4ac1d8c12334dc8 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Sep 2014 16:26:52 -0500 Subject: [PATCH 594/629] Fixed missing default configuration for ActionLinkTypeBase. --- src/ActionLinkTypeBase.php | 3 +-- src/Plugin/ActionLink/ConfirmForm.php | 10 ++++++---- src/Tests/FlagConfirmFormTest.php | 11 +++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 src/Tests/FlagConfirmFormTest.php diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 59bdc9b..520d9fa 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -38,8 +38,7 @@ abstract class ActionLinkTypeBase extends PluginBase implements ActionLinkTypePl */ public function __construct(array $configuration, $plugin_id, array $plugin_definition) { parent::__construct($configuration, $plugin_id, $plugin_definition); - - $this->setConfiguration($configuration); + $this->configuration += $this->defaultConfiguration(); } /** diff --git a/src/Plugin/ActionLink/ConfirmForm.php b/src/Plugin/ActionLink/ConfirmForm.php index 97f3417..0abdf0f 100644 --- a/src/Plugin/ActionLink/ConfirmForm.php +++ b/src/Plugin/ActionLink/ConfirmForm.php @@ -39,8 +39,10 @@ public function routeName($action = NULL) { public function defaultConfiguration() { $options = parent::defaultConfiguration(); - $options['flag_confirmation'] = 'Flag this content?'; - $options['unflag_confirmation'] = 'Unflag this content?'; + $options += [ + 'flag_confirmation' => 'Flag this content?', + 'unflag_confirmation' => 'Unflag this content?', + ]; return $options; } @@ -64,7 +66,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['display']['settings']['link_options_confirm']['flag_confirmation'] = [ '#type' => 'textfield', '#title' => t('Flag confirmation message'), - '#default_value' => $this->configuration['flag_confirmation'], + '#default_value' => $this->getFlagQuestion(), '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, @@ -73,7 +75,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['display']['settings']['link_options_confirm']['unflag_confirmation'] = [ '#type' => 'textfield', '#title' => t('Unflag confirmation message'), - '#default_value' => $this->configuration['unflag_confirmation'], + '#default_value' => $this->getUnflagQuestion(), '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'), // This will get changed to a state by flag_link_type_options_states(). '#required' => TRUE, diff --git a/src/Tests/FlagConfirmFormTest.php b/src/Tests/FlagConfirmFormTest.php new file mode 100644 index 0000000..94fb369 --- /dev/null +++ b/src/Tests/FlagConfirmFormTest.php @@ -0,0 +1,11 @@ + Date: Sun, 28 Sep 2014 20:38:47 -0500 Subject: [PATCH 595/629] Added initial confirm form test. --- src/Tests/FlagConfirmFormTest.php | 139 +++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/src/Tests/FlagConfirmFormTest.php b/src/Tests/FlagConfirmFormTest.php index 94fb369..7180d8e 100644 --- a/src/Tests/FlagConfirmFormTest.php +++ b/src/Tests/FlagConfirmFormTest.php @@ -1,11 +1,146 @@ adminUser = $this->drupalCreateUser([ + 'administer flags', + 'administer flagging display', + 'administer node display', + ]); + + $this->drupalLogin($this->adminUser); + $this->doCreateFlag(); + $this->doCreateNode(); + } + + /** + * Create a node type and a flag. + */ + public function doCreateFlag() { + // Create content type. + $this->drupalCreateContentType(['type' => $this->nodeType]); + + // Test with minimal value requirement. + $edit = [ + 'label' => $this->label, + 'id' => $this->id, + 'flag_entity_type' => 'flagtype_node', + 'flag_link_type' => 'confirm', + ]; + $this->drupalPostForm('admin/structure/flags/add', $edit, t('Continue')); + + // Check confirm form field entry. + $this->assertText(t('Flag confirmation message')); + $this->assertText(t('Unflag confirmation message')); + + // Update the flag. + $edit = [ + 'types[' . $this->nodeType . ']' => $this->nodeType, + 'flag_confirmation' => $this->flagConfirmMessage, + 'unflag_confirmation' => $this->unflagConfirmMessage, + ]; + $this->drupalPostForm(NULL, $edit, t('Create Flag')); + + // Check to see if the flag was created. + $this->assertText(t('Flag @this_label has been added.', ['@this_label' => $this->label])); + } + + /** + * Create a node and flag it. + */ + public function doCreateNode() { + $node = $this->drupalCreateNode(['type' => $this->nodeType]); + $node_id = $node->id(); + + // Grant the flag permissions to the authenticated role, so that both + // users have the same roles and share the render cache. + $role = Role::load(DRUPAL_AUTHENTICATED_RID); + $role->grantPermission('flag ' . $this->id); + $role->grantPermission('unflag ' . $this->id); + $role->save(); + + // Create and login a new user. + $user_1 = $this->drupalCreateUser(); + $this->drupalLogin($user_1); + + // Click the flag link. + $this->drupalGet('node/' . $node_id); + $this->clickLink('Flag this item'); + + // Check if we have the confirm form message displayed. + $this->assertText($this->flagConfirmMessage); + + // Submit the confirm form. + $this->drupalPostForm('flag/confirm/flag/' . $this->id . '/' . $node_id, [], t('Flag')); + $this->assertResponse(200); + + // Check that the node is flagged. + $this->drupalGet('node/' . $node_id); + $this->assertLink('Unflag this item'); + } -} \ No newline at end of file +} From ad9f683dbc98650aeab082f5bd23c50273efd2f6 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Tue, 30 Sep 2014 14:19:34 +0200 Subject: [PATCH 596/629] Page cache, fieldable --- src/Entity/Flagging.php | 1 - src/Plugin/views/relationship/FlagViewsRelationship.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Entity/Flagging.php b/src/Entity/Flagging.php index dad22a9..0964b38 100644 --- a/src/Entity/Flagging.php +++ b/src/Entity/Flagging.php @@ -29,7 +29,6 @@ * }, * base_table = "flagging", * data_table = "flagging_data", - * fieldable = TRUE, * entity_keys = { * "id" = "id", * "bundle" = "type", diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index c8c93da..1506d1a 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -98,7 +98,7 @@ public function query() { $flag_roles = user_roles(FALSE, "flag $flag->label"); if (isset($flag_roles[DRUPAL_ANONYMOUS_RID])) { // Disable page caching for anonymous users. - drupal_page_is_cacheable(FALSE); + \Drupal::service('page_cache_kill_switch')->trigger(); // Add in the SID from Session API for anonymous users. $this->definition['extra'][] = [ From 8e83d14705f016a88b7cd750bd0f18c641315575 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 7 Oct 2014 09:41:00 -0500 Subject: [PATCH 597/629] Fixed FlagListController WSOD due to https://www.drupal.org/node/2346779 --- src/Controller/FlagListController.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 93f33d8..706f369 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\flag\FlagInterface; use Drupal\Component\Utility\String; +use Drupal\Core\Url; /** * Provides a entity list page for Flags. @@ -85,31 +86,28 @@ public function render() { // @todo Move this too hook_help()? if (!\Drupal::moduleHandler()->moduleExists('views')) { - $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', ['@views-url' => url('http://drupal.org/project/views')]) . '

'; + $output .= '

' . t('The Views module is not installed, or not enabled. It is recommended that you install the Views module to be able to easily produce lists of flagged content.', ['@views-url' => Url::fromUri('http://drupal.org/project/views')]) . '

'; } else { $output .= '

'; - $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', ['@views-url' => url('admin/structure/views')]); + $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', ['@views-url' => Url::fromRoute('views_ui.list')]); if (\Drupal::service('flag')->getFlagById('bookmarks')) { - $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', ['@views-url' => url('admin/structure/views', ['query' => ['tag' => 'flag']])]); + $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', ['@views-url' => Url::fromRoute('views_ui.list', ['query' => ['tag' => 'flag']])]); } $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', ['@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954']); $output .= '

'; } - if (!\Drupal::moduleHandler()->moduleExists('flag_actions')) { - $output .= '

' . t('Flagging an item may trigger actions. However, you don\'t have the Flag actions module enabled, so you won\'t be able to enjoy this feature.', ['@actions-url' => url(FLAG_ADMIN_PATH . '/actions'), '@modules-url' => url('admin/modules')]) . '

'; - } - else { - $output .= '

' . t('Flagging an item may trigger actions.', ['@actions-url' => url(FLAG_ADMIN_PATH . '/actions')]) . '

'; - } - if (!\Drupal::moduleHandler()->moduleExists('rules')) { - $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', ['@rules-url' => url('http://drupal.org/node/407070')]) . '

'; + $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', ['@rules-url' => Url::fromUri('http://drupal.org/node/407070')]) . '

'; } + + /* + * Commented out because the rules route name has yet to be established. else { - $output .= '

' . t('Flagging an item may trigger rules.', ['@rules-url' => url('admin/config/workflow/rules')]) . '

'; + $output .= '

' . t('Flagging an item may trigger rules.', ['@rules-url' => Url::fromUri('base://admin/config/workflow/rules')]) . '

'; } + */ $output .= '

' . t('To learn about the various ways to use flags, please check out the Flag module handbook.', ['@handbook-url' => 'http://drupal.org/handbook/modules/flag']) . '

'; From 999140ee05edf0fff5e2b17418de6866c60bbdc0 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 7 Oct 2014 10:09:17 -0500 Subject: [PATCH 598/629] Further l() and url() fixes due to https://www.drupal.org/node/2346779 --- src/Form/FlagAddPageForm.php | 4 ++-- src/Form/FlagFormBase.php | 9 +++++---- src/Plugin/views/relationship/FlagViewsRelationship.php | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index a2c0c53..3c3679d 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -7,8 +7,8 @@ namespace Drupal\flag\Form; use Drupal\Core\Form\FormBase; -use Drupal\flag\Handlers\AbstractFlag; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; /** * Provides the flag add page. @@ -43,7 +43,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['flag_basic_info']['label'] = [ '#type' => 'textfield', '#title' => t('Label'), - '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), + '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => Url::fromRoute('views_ui.list'))), '#maxlength' => 255, '#required' => TRUE, '#weight' => -3, diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index 5ff0428..a725fa0 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityForm; use Drupal\Core\Form\FormStateInterface; use Drupal\flag\FlagInterface; +use Drupal\Core\Url; /** * Provides the base flag add/edit form. @@ -36,7 +37,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#type' => 'textfield', '#title' => t('Label'), '#default_value' => $flag->label, - '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => url('admin/structure/views'))), + '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => Url::fromRoute('views_ui.list'))), '#maxlength' => 255, '#required' => TRUE, '#weight' => -3, @@ -268,14 +269,14 @@ public function save(array $form, FormStateInterface $form_state) { $flag->enable(); $status = $flag->save(); - $url = $flag->url(); + $url = $flag->urlInfo(); if ($status == SAVED_UPDATED) { drupal_set_message(t('Flag %label has been updated.', ['%label' => $flag->label()])); - $this->logger('flag')->notice('Flag %label has been updated.', ['%label' => $flag->label(), 'link' => l(t('Edit'), $url)]); + $this->logger('flag')->notice('Flag %label has been updated.', ['%label' => $flag->label(), 'link' => \Drupal::l(t('Edit'), $url)]); } else { drupal_set_message(t('Flag %label has been added.', ['%label' => $flag->label()])); - $this->logger('flag')->notice('Flag %label has been added.', ['%label' => $flag->label(), 'link' => l(t('Edit'), $url)]); + $this->logger('flag')->notice('Flag %label has been added.', ['%label' => $flag->label(), 'link' => \Drupal::l(t('Edit'), $url)]); } // We clear caches more vigorously if the flag was new. diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 1506d1a..4672bae 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -8,6 +8,7 @@ use Drupal\views\Plugin\views\relationship\RelationshipPluginBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; /** * Provides a views relationship to select flag content by a flag. @@ -69,7 +70,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if (!$form['flag']['#options']) { $form = [ 'error' => [ - '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', ['%type' => $entity_type, '@create-url' => url(FLAG_ADMIN_PATH)]) . '

', + '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', ['%type' => $entity_type, '@create-url' => Url::fromRoute('flag.list')]) . '

', ], ]; } From dd4897e13b096e737905f5e1b625b3b2e334f881 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Fri, 10 Oct 2014 13:59:36 +0200 Subject: [PATCH 599/629] Prevent errors on content preview. --- flag.module | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flag.module b/flag.module index 351e54b..4fb0e64 100644 --- a/flag.module +++ b/flag.module @@ -267,6 +267,11 @@ function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisp $flag_service = \Drupal::service('flag'); $flags = $flag_service->getFlags($entity->getEntityTypeID(), $entity->bundle()); + // Don't act on previews. + if ($entity->isNew()) { + return; + } + foreach ($flags as $flag) { $link_type_plugin = $flag->getLinkTypePlugin(); $flag_type_plugin = $flag->getFlagTypePlugin(); From 11949d1d9bc0ee88175fb9cc6baeedd4d2105a5a Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 13 Oct 2014 20:22:36 -0500 Subject: [PATCH 600/629] Moved preview termination conditional to earlier in flag_entity_view(). --- flag.module | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/flag.module b/flag.module index 4fb0e64..a46c430 100644 --- a/flag.module +++ b/flag.module @@ -263,15 +263,17 @@ function flag_node_links_alter(array &$links, NodeInterface $entity, array &$con * Handles the 'show_in_links' and 'show_as_field' flag options. */ function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode) { - // Get all possible flags for this entity type. - $flag_service = \Drupal::service('flag'); - $flags = $flag_service->getFlags($entity->getEntityTypeID(), $entity->bundle()); - // Don't act on previews. if ($entity->isNew()) { return; } + // @todo: Add caching here PLZ. + + // Get all possible flags for this entity type. + $flag_service = \Drupal::service('flag'); + $flags = $flag_service->getFlags($entity->getEntityTypeID(), $entity->bundle()); + foreach ($flags as $flag) { $link_type_plugin = $flag->getLinkTypePlugin(); $flag_type_plugin = $flag->getFlagTypePlugin(); From fd64ea382321de7efdbe4ff6195ab1629a559f7a Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 14 Oct 2014 00:18:04 -0500 Subject: [PATCH 601/629] Added field entry link type test. --- src/Form/FlaggingForm.php | 15 +- src/Plugin/ActionLink/FieldEntry.php | 8 +- src/Tests/FlagConfirmFormTest.php | 4 +- src/Tests/FlagFieldEntryTest.php | 206 +++++++++++++++++++++++++++ 4 files changed, 226 insertions(+), 7 deletions(-) create mode 100644 src/Tests/FlagFieldEntryTest.php diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index af8136a..8af5237 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; /** * Provides the flagging form for field entry. @@ -38,8 +39,18 @@ public function actions(array $form, FormStateInterface $form_state) { unset($actions['delete']['#access']); $actions['delete']['#title'] = $this->t('Delete Flagging'); - $actions['delete']['#route_parameters']['flag_id'] = $this->entity->getFlagId(); - $actions['delete']['#route_parameters']['entity_id'] = $this->entity->getFlaggableId(); + + // Build the delete url from route. We need to build this manually + // otherwise Drupal will try to build the flagging entity's delete-form + // link. Since that route doesn't use the flagging ID, Drupal can't build + // the link for us. + $route_params = [ + 'flag_id' => $this->entity->getFlagId(), + 'entity_id' => $this->entity->getFlaggableId(), + ]; + $url = Url::fromRoute('flag.confirm_unflag', $route_params); + + $actions['delete']['#url'] = $url; } return $actions; diff --git a/src/Plugin/ActionLink/FieldEntry.php b/src/Plugin/ActionLink/FieldEntry.php index cdb82a0..f2761ab 100644 --- a/src/Plugin/ActionLink/FieldEntry.php +++ b/src/Plugin/ActionLink/FieldEntry.php @@ -95,6 +95,8 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta * {@inheritdoc} */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { + $form_values = $form_state->getValues(); + if ($form_state->getValue('link_type') == 'field_entry') { if (empty($form_values['flag_confirmation'])) { $form_state->setErrorByName('flag_confirmation', 'A flag confirmation message is required when using the field entry link type.'); @@ -118,9 +120,9 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); - $this->configuration['flag_confirmation'] = $form_state['values']['flag_confirmation']; - $this->configuration['edit_flagging'] = $form_state['values']['flagging_edit_title']; - $this->configuration['unflag_confirmation'] = $form_state['values']['unflag_confirmation']; + $this->configuration['flag_confirmation'] = $form_state->getValue('flag_confirmation'); + $this->configuration['edit_flagging'] = $form_state->getValue('flagging_edit_title'); + $this->configuration['unflag_confirmation'] = $form_state->getValue('unflag_confirmation'); } /** diff --git a/src/Tests/FlagConfirmFormTest.php b/src/Tests/FlagConfirmFormTest.php index 7180d8e..edb6a24 100644 --- a/src/Tests/FlagConfirmFormTest.php +++ b/src/Tests/FlagConfirmFormTest.php @@ -129,7 +129,7 @@ public function doCreateNode() { // Click the flag link. $this->drupalGet('node/' . $node_id); - $this->clickLink('Flag this item'); + $this->clickLink(t('Flag this item')); // Check if we have the confirm form message displayed. $this->assertText($this->flagConfirmMessage); @@ -140,7 +140,7 @@ public function doCreateNode() { // Check that the node is flagged. $this->drupalGet('node/' . $node_id); - $this->assertLink('Unflag this item'); + $this->assertLink(t('Unflag this item')); } } diff --git a/src/Tests/FlagFieldEntryTest.php b/src/Tests/FlagFieldEntryTest.php new file mode 100644 index 0000000..7bd5fe0 --- /dev/null +++ b/src/Tests/FlagFieldEntryTest.php @@ -0,0 +1,206 @@ +adminUser = $this->drupalCreateUser([ + 'administer flags', + 'administer flagging display', + 'administer flagging fields', + 'administer node display', + ]); + + $this->drupalLogin($this->adminUser); + $this->doCreateFlag(); + $this->doAddFields(); + $this->doCreateFlagNode(); + $this->doEditFlagField(); + } + + /** + * Create a node type and flag. + */ + public function doCreateFlag() { + // Create content type. + $this->drupalCreateContentType(['type' => $this->nodeType]); + + // Test with minimal value requirement. + $edit = [ + 'label' => $this->label, + 'id' => $this->id, + 'flag_entity_type' => 'flagtype_node', + 'flag_link_type' => 'field_entry', + ]; + $this->drupalPostForm('admin/structure/flags/add', $edit, t('Continue')); + + // Check confirm form field entry. + $this->assertText(t('Flag confirmation message')); + $this->assertText(t('Enter flagging details message')); + $this->assertText(t('Unflag confirmation message')); + + // Update the flag. + $edit = [ + 'types[' . $this->nodeType . ']' => $this->nodeType, + 'flag_confirmation' => $this->flagConfirmMessage, + 'flagging_edit_title' => $this->flagDetailsMessage, + 'unflag_confirmation' => $this->unflagConfirmMessage, + ]; + $this->drupalPostForm(NULL, $edit, t('Create Flag')); + + // Check to see if the flag was created. + $this->assertText(t('Flag @this_label has been added.', ['@this_label' => $this->label])); + } + + /** + * Add fields to flag. + */ + public function doAddFields() { + $edit = [ + 'fields[_add_new_field][label]' => $this->flagFieldLabel, + 'fields[_add_new_field][field_name]' => $this->flagFieldId, + 'fields[_add_new_field][type]' => 'text', + ]; + $this->drupalPostForm('admin/structure/flags/manage/' . $this->id . '/fields', $edit, t('Save')); + + $edit = [ + 'field_storage[cardinality]' => '-1', + 'field_storage[cardinality_number]' => '1', + ]; + $this->drupalPostForm(NULL, $edit, t('Save field settings')); + + $this->assertText(t('Updated field') . ' ' . $this->flagFieldLabel . ' ' . t('field settings.')); + } + + /** + * Create a node and flag it. + */ + public function doCreateFlagNode() { + $node = $this->drupalCreateNode(['type' => $this->nodeType]); + $this->nodeId = $node->id(); + + // Grant the flag permissions to the authenticated role, so that both + // users have the same roles and share the render cache. + $role = Role::load(DRUPAL_AUTHENTICATED_RID); + $role->grantPermission('flag ' . $this->id); + $role->grantPermission('unflag ' . $this->id); + $role->save(); + + // Create and login a new user. + $user_1 = $this->drupalCreateUser(); + $this->drupalLogin($user_1); + + // Click the flag link. + $this->drupalGet('node/' . $this->nodeId); + $this->clickLink(t('Flag this item')); + + // Check if we have the confirm form message displayed. + $this->assertText($this->flagConfirmMessage); + + // Enter the field value and submit it. + $this->flagFieldValue = $this->randomString(); + $edit = [ + 'field_' . $this->flagFieldId . '[0][value]' => $this->flagFieldValue, + ]; + $this->drupalPostForm(NULL, $edit, t('Update Flagging')); + + // Check that the node is flagged. + $this->assertLink(t('Unflag this item')); + } + + /** + * Edit the field value of the existing flagging. + */ + public function doEditFlagField() { + // Get the details form. + $this->drupalGet('flag/details/edit/' . $this->id . '/' . $this->nodeId); + + // See if the details message is displayed. + $this->assertText($this->flagDetailsMessage); + + // See if the field value was preserved. + $this->assertFieldByName('field_' . $this->flagFieldId . '[0][value]', $this->flagFieldValue); + + // Update the field value. + $this->flagFieldValue = $this->randomString(); + $edit = [ + 'field_' . $this->flagFieldId . '[0][value]' => $this->flagFieldValue, + ]; + $this->drupalPostForm(NULL, $edit, t('Update Flagging')); + + // Get the details form. + $this->drupalGet('flag/details/edit/' . $this->id . '/' . $this->nodeId); + + // See if the field value was preserved. + $this->assertFieldByName('field_' . $this->flagFieldId . '[0][value]', $this->flagFieldValue); + } + +} From 8b02c0aa05ca058e335e6b7d3f3793cf6804b777 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Wed, 15 Oct 2014 12:34:21 +1000 Subject: [PATCH 602/629] Fixes for test fails --- flag.info.yml | 2 ++ src/Controller/FlagListController.php | 6 +++--- src/Form/FlagAddPageForm.php | 2 +- src/Form/FlagFormBase.php | 2 +- src/Plugin/views/relationship/FlagViewsRelationship.php | 2 +- src/Tests/FlagFieldEntryTest.php | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/flag.info.yml b/flag.info.yml index 7ee6475..d62a74d 100644 --- a/flag.info.yml +++ b/flag.info.yml @@ -4,3 +4,5 @@ core: 8.x type: module package: Flags configure: admin/structure/flags +dependencies: + - views_ui diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 706f369..238450c 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -90,16 +90,16 @@ public function render() { } else { $output .= '

'; - $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', ['@views-url' => Url::fromRoute('views_ui.list')]); + $output .= t('Lists of flagged content can be displayed using views. You can configure these in the Views administration section.', ['@views-url' => Url::fromRoute('views_ui.list')->toString()]); if (\Drupal::service('flag')->getFlagById('bookmarks')) { - $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', ['@views-url' => Url::fromRoute('views_ui.list', ['query' => ['tag' => 'flag']])]); + $output .= ' ' . t('Flag module automatically provides a few default views for the bookmarks flag. You can use these as templates by cloning these views and then customizing as desired.', ['@views-url' => Url::fromRoute('views_ui.list', ['query' => ['tag' => 'flag']])->toString()]); } $output .= ' ' . t('The Flag module handbook contains extensive documentation on creating customized views using flags.', ['@flag-handbook-url' => 'http://drupal.org/handbook/modules/flag', '@customize-url' => 'http://drupal.org/node/296954']); $output .= '

'; } if (!\Drupal::moduleHandler()->moduleExists('rules')) { - $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', ['@rules-url' => Url::fromUri('http://drupal.org/node/407070')]) . '

'; + $output .= '

' . t('Flagging an item may trigger rules. However, you don\'t have the Rules module enabled, so you won\'t be able to enjoy this feature. The Rules module is a more extensive solution than Flag actions.', ['@rules-url' => Url::fromUri('http://drupal.org/node/407070')->toString()]) . '

'; } /* diff --git a/src/Form/FlagAddPageForm.php b/src/Form/FlagAddPageForm.php index 3c3679d..d158b2d 100644 --- a/src/Form/FlagAddPageForm.php +++ b/src/Form/FlagAddPageForm.php @@ -43,7 +43,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['flag_basic_info']['label'] = [ '#type' => 'textfield', '#title' => t('Label'), - '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => Url::fromRoute('views_ui.list'))), + '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => Url::fromRoute('views_ui.list')->toString())), '#maxlength' => 255, '#required' => TRUE, '#weight' => -3, diff --git a/src/Form/FlagFormBase.php b/src/Form/FlagFormBase.php index a725fa0..38ca2fa 100644 --- a/src/Form/FlagFormBase.php +++ b/src/Form/FlagFormBase.php @@ -37,7 +37,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t '#type' => 'textfield', '#title' => t('Label'), '#default_value' => $flag->label, - '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => Url::fromRoute('views_ui.list'))), + '#description' => t('A short, descriptive title for this flag. It will be used in administrative interfaces to refer to this flag, and in page titles and menu items of some views this module provides (theses are customizable, though). Some examples could be Bookmarks, Favorites, or Offensive.', array('@insite-views-url' => Url::fromRoute('views_ui.list')->toString())), '#maxlength' => 255, '#required' => TRUE, '#weight' => -3, diff --git a/src/Plugin/views/relationship/FlagViewsRelationship.php b/src/Plugin/views/relationship/FlagViewsRelationship.php index 4672bae..62f1f0e 100644 --- a/src/Plugin/views/relationship/FlagViewsRelationship.php +++ b/src/Plugin/views/relationship/FlagViewsRelationship.php @@ -70,7 +70,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { if (!$form['flag']['#options']) { $form = [ 'error' => [ - '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', ['%type' => $entity_type, '@create-url' => Url::fromRoute('flag.list')]) . '

', + '#markup' => '

' . t('No %type flags exist. You must first create a %type flag before being able to use this relationship type.', ['%type' => $entity_type, '@create-url' => Url::fromRoute('flag.list')->toString()]) . '

', ], ]; } diff --git a/src/Tests/FlagFieldEntryTest.php b/src/Tests/FlagFieldEntryTest.php index 7bd5fe0..49537aa 100644 --- a/src/Tests/FlagFieldEntryTest.php +++ b/src/Tests/FlagFieldEntryTest.php @@ -66,7 +66,7 @@ class FlagFieldEntryTest extends WebTestBase { * * @var array */ - public static $modules = array('views', 'flag', 'node', 'field_ui'); + public static $modules = array('views', 'flag', 'node', 'field_ui', 'text'); /** * Create a new flag with the Field Entry type, and add fields. From eb430ab15715726392f6551c189bb0fc40ea9cd7 Mon Sep 17 00:00:00 2001 From: Florian Weber Date: Wed, 15 Oct 2014 18:19:03 +0200 Subject: [PATCH 603/629] Fix definition of EntityFlagType "derivative" got renamed to "deriver". Related change record: https://www.drupal.org/node/2257811 --- src/Plugin/Flag/EntityFlagType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/Flag/EntityFlagType.php b/src/Plugin/Flag/EntityFlagType.php index 2373f70..28f67ff 100644 --- a/src/Plugin/Flag/EntityFlagType.php +++ b/src/Plugin/Flag/EntityFlagType.php @@ -19,7 +19,7 @@ * @FlagType( * id = "flagtype_entity", * title = @Translation("Flag Type Entity"), - * derivative = "Drupal\flag\Plugin\Derivative\EntityFlagType" + * deriver = "Drupal\flag\Plugin\Derivative\EntityFlagType" * ) */ class EntityFlagType extends FlagTypeBase { From bdca61e11dd959df071cc136df4ee351054f6696 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 18 Oct 2014 00:01:51 -0500 Subject: [PATCH 604/629] Removed dead hooks from flag.module. --- flag.module | 497 ++-------------------------------------------------- 1 file changed, 15 insertions(+), 482 deletions(-) diff --git a/flag.module b/flag.module index a46c430..2603769 100644 --- a/flag.module +++ b/flag.module @@ -21,65 +21,6 @@ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\user\UserInterface; use Drupal\Core\Form\FormStateInterface; -// @todo: Implement flagging_view(). Not extremely useful. I already have it. - -// @todo: When renaming a flag: Call field_attach_rename_bundle(). - -// @todo: When creating a flag: Call field_attach_create_bundle(). - -// @todo: When deleting a flag: Call field_attach_delete_bundle(). - -// @tood: Discuss: Should flag deleting call flag_reset_flag()? No. - -// @todo: flag_reset_flag(): -// - it should delete the flaggings. -// - (it has other issues; see http://drupal.org/node/894992.) -// - (is problematic: it might not be possible to delete all data in a single page request.) - -// @todo: Discuss: Note that almost all functions/identifiers dealing with -// flaggings *aren't* prefixed by "flag_". For example: -// - The menu argument is %flagging, not %flag_flagging. -// - The entity type is "flagging", not "flag_flagging". -// On the one hand this succinct version is readable and nice. On the other hand, it isn't -// very "correct". - -/** - * Implements hook_entity_query_alter(). - * - * Replaces bundle condition in EntityFieldQuery on flagging entities - * with query condition on [name] field in [flag] table. - * - * @see flag_query_flagging_flag_names_alter() - *//* -function flag_entity_query_alter(EntityFieldQuery $query) { - $conditions = &$query->entityConditions; - - // Alter only flagging queries with bundle conditions. - if (isset($conditions['entity_type']) && $conditions['entity_type']['value'] == 'flagging' && isset($conditions['bundle'])) { - $query->addTag('flagging_flag_names'); // Add tag to alter query. - // Make value and operator of the bundle condition accessible - // in hook_query_TAG_alter. - $query->addMetaData('flag_name_value', $conditions['bundle']['value']); - $query->addMetaData('flag_name_operator', $conditions['bundle']['operator']); - unset($conditions['bundle']); - } -}*/ - -/** - * Implements hook_query_TAG_alter() for flagging_flag_names tag. - * - * @see flag_entity_query_alter() - *//* -function flag_query_flagging_flag_names_alter(QueryAlterableInterface $query) { - // Get value and operator for bundle condition from meta data. - $value = $query->getMetaData('flag_name_value'); - $operator = $query->getMetaData('flag_name_operator'); - // Join [flag] and [flagging] tables by [fid] and - // apply bundle condition on [flag].[name] field. - $query->join('flag', 'f', 'flagging.fid = f.fid'); - $query->condition('f.name', $value, $operator); -}*/ - /** * Implements hook_help(). */ @@ -213,46 +154,6 @@ function flag_entity_extra_field_info() { return $extra; } -/** - * Implements hook_form_FORM_ID_alter(): node_type_form. - *//* -function flag_form_node_type_form_alter(&$form, FormStateInterface $form_state, $form_id) { - global $user; - $node_type = $form_state->getFormObject()->getEntity(); - $flags = \Drupal::service('flag')->getFlags('node', $node_type->id(), $user); - foreach ($flags as $flag) { - // @todo: Revisit when form functionality is implemented. - if (!empty($flag->show_on_form)) { - // To be able to process node tokens in flag labels, we create a fake - // node and store it in the flag's cache for replace_tokens() to find, - // with a fake ID. - $flag->remember_entity('fake', (object) [ - 'nid' => NULL, - 'type' => $form['#node_type']->type, - 'title' => '', - ]); - $var = 'flag_' . $flag->name . '_default'; - $form['workflow']['flag'][$var] = [ - '#type' => 'checkbox', - '#title' => $flag->get_label('flag_short', 'fake'), - '#default_value' => variable_get($var . '_' . $form['#node_type']->type, 0), - '#return_value' => 1, - ]; - } - } - - if (isset($form['workflow']['flag'])) { - $form['workflow']['flag'] += [ - '#type' => 'item', - '#title' => t('Default flags'), - '#description' => t('Above are the flags you elected to show on the node editing form. You may specify their initial state here.', ['@flag-url' => url(FLAG_ADMIN_PATH)]), - // Make the spacing a bit more compact: - '#prefix' => '
', - '#suffix' => '
', - ]; - } -} -*/ function flag_node_links_alter(array &$links, NodeInterface $entity, array &$context) { //@todo: Define this for handling the showOnLinks() flag mode. } @@ -347,54 +248,6 @@ function flag_entity_delete(EntityInterface $entity) { // @todo Actually delete the flaggings and clear associated flag counts. } -/** - * Implements hook_user_login(). - */ -function flag_user_login($account) { - // Migrate anonymous flags to this user's account. - if (\Drupal::moduleHandler()->moduleExists('session_api') && ($sid = flag_get_sid(0))) { - // Get a list of flagging IDs that will be moved over. - $duplicate_flaggings = []; - $flaggings = db_select('flagging', 'fc') - ->fields('fc', ['flagging_id', 'fid', 'entity_id']) - ->condition('uid', 0) - ->condition('sid', $sid) - ->execute() - ->fetchAllAssoc('flagging_id', PDO::FETCH_ASSOC); - - // Convert anonymous flaggings to their authenticated account. - foreach ($flaggings as $flagging_id => $flagging) { - // Each update is wrapped in a try block to prevent unique key errors. - // Any duplicate object that was flagged as anonoymous is deleted in the - // subsequent db_delete() call. - try { - db_update('flagging') - ->fields([ - 'uid' => $account->uid, - 'sid' => 0, - ]) - ->condition('flagging_id', $flagging_id) - ->execute(); - } - catch (Exception $e) { - $duplicate_flaggings[$flagging_id] = $flagging; - } - } - - // Delete any remaining flags this user had as an anonymous user. We use the - // proper unflag action here to make sure the count gets decremented again - // and so that other modules can clean up their tables if needed. - $anonymous_user = drupal_anonymous_user(); - foreach ($duplicate_flaggings as $flagging_id => $flagging) { - $flag = flag_get_flag(NULL, $flagging['fid']); - $flag->flag('unflag', $flagging['entity_id'], $anonymous_user, TRUE); - } - - // Clean up anonymous cookies. - FlagCookieStorage::drop(); - } -} - /** * Implements hook_user_cancel(). */ @@ -449,38 +302,6 @@ function flag_user_account_removal(UserInterface $account) { //_flag_entity_delete('user', $account->id()); } -/** - * Implements hook_user_view(). - *//* -function flag_user_view($account, $view_mode) { - $flags = flag_get_flags('user'); - $flag_items = array(); - foreach ($flags as $flag) { - if (!$flag->access($account->uid)) { - // User has no permission to use this flag. - continue; - } - if (empty($flag->show_on_profile)) { - // Flag not set to appear on profile. - continue; - } - $flag_items[$flag->name] = array( - '#type' => 'user_profile_item', - '#title' => $flag->get_title($account->uid), - '#markup' => $flag->theme($flag->is_flagged($account->uid) ? 'unflag' : 'flag', $account->uid), - '#attributes' => array('class' => array('flag-profile-' . $flag->name)), - ); - } - if (!empty($flag_items)) { - $account->content['flags'] = $flag_items; - $account->content['flags'] += array( - '#type' => 'user_profile_category', - '#title' => t('Actions'), - '#attributes' => array('class' => array('flag-profile')), - ); - } -}*/ - /** * Implements hook_flag_access(). */ @@ -592,174 +413,6 @@ function flag_flag_access_multiple($flag, $entity_ids, $account) { return $access; } -/** - * Implements hook_theme(). - *//* -function flag_theme() { - $path = drupal_get_path('module', 'flag') . '/theme'; - - return array( - 'flag' => array( - 'variables' => array( - 'flag' => NULL, - 'action' => NULL, - 'entity_id' => NULL, - 'after_flagging' => FALSE, - 'needs_wrapping_element' => FALSE, - 'errors' => array(), - ), - 'template' => 'flag', - 'pattern' => 'flag__', - 'path' => $path, - ), - 'flag_tokens_browser' => array( - 'variables' => array( - 'types' => array('all'), - 'global_types' => TRUE, - ), - 'file' => 'flag.tokens.inc', - ), - 'flag_admin_listing' => array( - 'render element' => 'form', - 'file' => 'includes/flag.admin.inc', - ), - 'flag_admin_listing_disabled' => array( - 'variables' => array( - 'flags' => NULL, - 'default_flags' => NULL, - ), - 'file' => 'includes/flag.admin.inc', - ), - 'flag_admin_page' => array( - 'variables' => array( - 'flags' => NULL, - 'default_flags' => NULL, - 'flag_admin_listing' => NULL, - ), - 'file' => 'includes/flag.admin.inc', - ), - 'flag_form_roles' => array( - 'render element' => 'element', - 'file' => 'includes/flag.admin.inc', - ), - ); -} -*/ -/** - * A preprocess function for our theme('flag'). It generates the - * variables needed there. - * - * The $variables array initially contains the following arguments: - * - $flag - * - $action - * - $entity_id - * - $after_flagging - * - $errors - * - $needs_wrapping_element - * - * See 'flag.tpl.php' for their documentation. - */ -function template_preprocess_flag(&$variables) { - global $user; - $initialized = &drupal_static(__FUNCTION__, array()); - - // Some typing shotcuts: - $flag =& $variables['flag']; - $action = $variables['action']; - $entity_id = $variables['entity_id']; - $errors = join('
', $variables['errors']); - $flag_css_name = str_replace('_', '-', $flag->name); - - // Generate the link URL. - $link_type = $flag->get_link_type(); - $link = module_invoke($link_type['module'], 'flag_link', $flag, $action, $entity_id); - if (isset($link['title']) && empty($link['html'])) { - $link['title'] = String::checkPlain($link['title']); - } - - // Replace the link with the access denied text if unable to flag. - if ($action == 'unflag' && !$flag->access($entity_id, 'unflag')) { - $link['title'] = $flag->get_label('unflag_denied_text', $entity_id); - unset($link['href']); - } - - // Anonymous users always need the JavaScript to maintain their flag state. - if ($user->uid == 0) { - $link_type['uses standard js'] = TRUE; - } - - // Load the JavaScript/CSS, if the link type requires it. - if (!isset($initialized[$link_type['name']])) { - if ($link_type['uses standard css']) { - drupal_add_css(drupal_get_path('module', 'flag') . '/theme/flag.css'); - } - if ($link_type['uses standard js']) { - drupal_add_js(drupal_get_path('module', 'flag') . '/theme/flag.js'); - } - $initialized[$link_type['name']] = TRUE; - } - - $variables['link'] = $link; - $variables['link_href'] = isset($link['href']) ? check_url(url($link['href'], $link)) : FALSE; - $variables['link_text'] = isset($link['title']) ? $link['title'] : $flag->get_label($action . '_short', $entity_id); - $variables['link_title'] = isset($link['attributes']['title']) ? String::checkPlain($link['attributes']['title']) : String::checkPlain(strip_tags($flag->get_label($action . '_long', $entity_id))); - $variables['status'] = ($action == 'flag' ? 'unflagged' : 'flagged'); - $variables['flag_name_css'] = $flag_css_name; - - $variables['flag_wrapper_classes_array'] = []; - $variables['flag_wrapper_classes_array'][] = 'flag-wrapper'; - $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name; - $variables['flag_wrapper_classes_array'][] = 'flag-' . $flag_css_name . '-' . $entity_id; - - $variables['flag_classes_array'] = []; - $variables['flag_classes_array'][] = 'flag'; - if (isset($link['href'])) { - $variables['flag_classes_array'][] = $variables['action'] . '-action'; - $variables['flag_classes_array'][] = 'flag-link-' . $flag->link_type; - } - else { - $variables['flag_classes_array'][] = $variables['action'] . '-disabled'; - } - if (isset($link['attributes']['class'])) { - $link['attributes']['class'] = is_string($link['attributes']['class']) ? array_filter(explode(' ', $link['attributes']['class'])) : $link['attributes']['class']; - $variables['flag_classes_array'] = array_merge($variables['flag_classes_array'], $link['attributes']['class']); - } - $variables['message_classes_array'] = []; - if ($variables['after_flagging']) { - $variables['message_classes_array'][] = 'flag-message'; - if ($errors) { - $variables['message_classes_array'][] = 'flag-failure-message'; - $variables['message_text'] = $errors; - } - else { - $inverse_action = ($action == 'flag' ? 'unflag' : 'flag'); - $variables['message_classes_array'][] = 'flag-success-message'; - $variables['message_classes_array'][] = 'flag-' . $variables['status'] . '-message'; - $variables['message_text'] = $flag->get_label($inverse_action . '_message', $entity_id); - $variables['flag_classes_array'][] = $variables['status']; - // By default we make our JS code remove, after a few seconds, only success messages. - $variables['message_classes_array'][] = 'flag-auto-remove'; - } - } - else { - $variables['message_text'] = ''; - } -} - -/** - * Theme processor for flag.tpl.php. - * - * @param array &$variables - * An array of variables for the template. See 'flag.tpl.php' for their - * documentation. - */ -function template_process_flag(&$variables) { - // Convert class arrays to strings. - $variables['flag_wrapper_classes'] = implode(' ', $variables['flag_wrapper_classes_array']); - $variables['flag_classes'] = implode(' ', $variables['flag_classes_array']); - $variables['message_classes'] = implode(' ', $variables['message_classes_array']); -} - // --------------------------------------------------------------------------- // Non-Views public API @@ -773,6 +426,9 @@ function template_process_flag(&$variables) { * * @return * The flag count with the flag name and entity type as the array key. + * + * @deprecated In Drupal 8. + * @todo Move flag_get_entity_flag_counts() into FlagCountService. */ function flag_get_entity_flag_counts($flag, $entity_type) { $counts = &drupal_static(__FUNCTION__); @@ -804,6 +460,9 @@ function flag_get_entity_flag_counts($flag, $entity_type) { * * @return * The flag count with the flag name and the uid as the array key. + * + * @deprecated In Drupal 8. + * @todo Move flag_get_user_flag_counts() to FlagCountsService. */ function flag_get_user_flag_counts($flag, $user) { $counts = &drupal_static(__FUNCTION__); @@ -835,6 +494,9 @@ function flag_get_user_flag_counts($flag, $user) { * * @return * The flag count with the entity type and id as array keys. + * + * @deprecated In Drupal 8 + * @todo Move flag_get_counts() to FlagCountService. */ function flag_get_counts($entity_type, $entity_id) { $counts = &drupal_static(__FUNCTION__); @@ -864,6 +526,9 @@ function flag_get_counts($entity_type, $entity_id) { * The flag name for which to retrieve a flag count. * @param $reset * (optional) Reset the internal cache and execute the SQL query another time. + * + * @deprecated In Drupal 8. + * @todo Move flag_get_flag_counts() into FlagCountService. */ function flag_get_flag_counts($flag_name, $reset = FALSE) { $counts = &drupal_static(__FUNCTION__); @@ -884,16 +549,6 @@ function flag_get_flag_counts($flag_name, $reset = FALSE) { return $counts[$flag_name]; } -/** - * Comparison function for uasort(). - */ -function _flag_compare_weight($flag1, $flag2) { - if ($flag1->weight == $flag2->weight) { - return 0; - } - return $flag1->weight < $flag2->weight ? -1 : 1; -} - /** * Remove all flagged entities from a flag. * @@ -902,6 +557,9 @@ function _flag_compare_weight($flag1, $flag2) { * @param $entity_id * (optional) The entity ID on which all flaggings will be removed. If left * empty, this will remove all of this flag's entities. + * + * @deprecated In Drupal 8. + * @todo Move to Flag::reset(). */ function flag_reset_flag($flag, $entity_id = NULL) { $query = db_select('flagging', 'fc') @@ -929,128 +587,3 @@ function flag_reset_flag($flag, $entity_id = NULL) { $count_query->execute(); return $query->execute(); } - -/** - * Set the Session ID for a user. Utilizes the Session API module. - * - * Creates a Session ID for an anonymous user and returns it. It will always - * return 0 for registered users. - * - * @param int $uid - * (optional) The user ID to create a session ID for. Defaults to the - * current user. - * @param bool $create - * (optional) Determines whether a session should be created if it doesn't - * exist yet. Defaults to TRUE. - * - * @return - * The session ID, if a session was created. If not, the return value is 0. - * - * @see flag_get_sid() - */ -function flag_set_sid($uid = NULL, $create = TRUE) { - $sids = &drupal_static(__FUNCTION__, array()); - - if (!isset($uid)) { - $uid = $GLOBALS['user']->uid; - } - - // Set the sid if none has been set yet. If the caller specified to create an - // sid and we have an invalid one (-1), create it. - if (!isset($sids[$uid]) || ($sids[$uid] == -1 && $create)) { - if (\Drupal::moduleHandler()->moduleExists('session_api') && session_api_available() && $uid == 0) { - // This returns one of the following: - // - -1. This indicates that no session exists and none was created. - // - A positive integer with the Session ID when it does exist. - $sids[$uid] = session_api_get_sid($create); - } - else { - $sids[$uid] = 0; - } - } - - // Keep the -1 case internal and let the outside world only distinguish two - // cases: (1) there is an SID; (2) there is no SID (-> 0). - return $sids[$uid] == -1 ? 0 : $sids[$uid]; -} - -/** - * Get the Session ID for a user. Utilizes the Session API module. - * - * Gets the Session ID for an anonymous user. It will always return 0 for - * registered users. - * - * @param int $uid - * (optional) The user ID to return the session ID for. Defaults to the - * current user. - * @param bool $create - * (optional) Determines whether a session should be created if it doesn't - * exist yet. Defaults to FALSE. - * - * @return - * The session ID, if the session exists. If not, the return value is 0. - * - * @see flag_set_sid() - */ -function flag_get_sid($uid = NULL, $create = FALSE) { - return flag_set_sid($uid, $create); -} - -// --------------------------------------------------------------------------- -// Contrib integration hooks - -/** - * Implements hook_views_api(). - */ -function flag_views_api() { - return array( - 'api' => 3.0, - 'path' => drupal_get_path('module', 'flag') . '/includes/views', - ); -} - -/** - * Implements hook_features_api(). - */ -function flag_features_api() { - return array( - 'flag' => array( - 'name' => t('Flag'), - 'feature_source' => TRUE, - 'default_hook' => 'flag_default_flags', - 'file' => drupal_get_path('module', 'flag') . '/includes/flag.features.inc', - ), - ); -} - -// --------------------------------------------------------------------------- -// Entity Metadata callbacks - -/** - * Getter callback that returns the SID of the user that is being retrieved. - * - * Callback for hook_entity_property_info_alter(). - * - * @param stdobj $entity - * The entity object representing a user for which we are getting inforamtion for. - * - * @param array $options - * Options reguarding the nature of the entity. Language, etc. - * - * @param string $name - * The name of the property we are running this callback for. - * - * @param string $entity_type - * The type that the stdobj $entity is supposed to be. - * - * @param $property_info - * The ifnromatin that represents the property we are providing a result for. - * - * @return an integer representing the user's sid field from the session_api table - * - * @ingroup callbacks - */ -function flag_properties_get_user_sid($entity, array $options, $name, $entity_type, $property_info) { - $sid = flag_get_sid($entity->uid, FALSE); - return $sid; -} From c9e1ddfd3b6324244e808d9e533b32cc869da467 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 21 Oct 2014 21:32:03 -0500 Subject: [PATCH 605/629] Mofied Travis CI to use Apache. --- .travis.yml | 31 +++++++++++++++++++++++-------- .travis/php.ini | 16 ++++++++++++++++ .travis/vhost.conf | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 .travis/php.ini create mode 100644 .travis/vhost.conf diff --git a/.travis.yml b/.travis.yml index 7e3f6c9..cec882b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,22 +19,32 @@ env: - CODER_VERSION='dev-8.x-2.x' before_install: + # Install Apache and FastCGI extension to connect to PHP-FPM. - sudo apt-get update > /dev/null + - sudo apt-get install apache2 libapache2-mod-fastcgi > /dev/null + - sudo a2enmod rewrite actions fastcgi alias + - sudo cp -f core/misc/travis-ci/vhost.conf /etc/apache2/sites-available/default + - sudo sed -i -e "s,/var/www,`pwd`,g" /etc/apache2/sites-available/default + + # Start PHP-FPM. There is no process manager available to start PHP-FPM on + # Travis CI currently, so we have to locate and enable it manually. + - sudo cp $HOME/.phpenv/versions/`php -r "print PHP_VERSION;"`/etc/php-fpm.conf.default $HOME/.phpenv/versions/`php -r "print PHP_VERSION;"`/etc/php-fpm.conf + - $HOME/.phpenv/versions/`php -r "print PHP_VERSION;"`/sbin/php-fpm + + # Import the PHP configuration. + - phpenv config-add core/misc/travis-ci/php.ini + # Always update Composer to the recent version, otherwise the drush # installation fails. - composer selfupdate install: - # Install php packages required for running a web server from drush. - - sudo apt-get install -y --force-yes php5-cgi php5-mysql - # Add composer's global bin directory to the path. # @see: https://github.com/drush-ops/drush#install---composer - export PATH="$HOME/.composer/vendor/bin:$PATH" # install drush globally - composer global require drush/drush:dev-master - - composer global require youngj/httpserver:dev-master - composer global require squizlabs/php_codesniffer:$PHPCS_VERSION - composer global require drupal/coder:$CODER_VERSION @@ -55,7 +65,7 @@ before_script: - git clone --depth 1 --branch $DRUPAL_VERSION $DRUPAL_REPO drupal - cd drupal # Install Drupal. - - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@127.0.0.1/drupal testing + - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@1localhost/drupal testing # Reference and enable flag in build site. - ln -s $TESTDIR modules/$MODULE_NAME @@ -64,13 +74,18 @@ before_script: # Start a web server on port 8080, run in the background; wait for # initialization. This is temporarly disabled since there are no web tests # yet. - - drush runserver 127.0.0.1:8080 & - - until netstat -an 2>/dev/null | grep '8080.*LISTEN'; do true; done + - sudo apachectl restart + - until netstat -an 2>/dev/null | grep '80.*LISTEN'; do true; done script: # Run the Coder sniffer for Flag. - phpcs --report=full --standard=Drupal ./modules/$MODULE_NAME # Run the Simpletests for Flag. - - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://127.0.0.1:8080 --verbose --color "$MODULE_TEST_GROUP" + - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://localhost --verbose --color "$MODULE_TEST_GROUP" # Run the PHPUnit tests. - ./core/vendor/phpunit/phpunit/phpunit -c ./core/phpunit.xml.dist ./modules/$MODULE_NAME + +after_failure: + - echo "Failures detected. Outputing additional logs:" + - sudo cat /var/log/apache2/error.log + - sudo cat /var/log/mysql/error.log diff --git a/.travis/php.ini b/.travis/php.ini new file mode 100644 index 0000000..3891e56 --- /dev/null +++ b/.travis/php.ini @@ -0,0 +1,16 @@ +; +; INI file used to populate PHP settings to Travis CI. +; +; This file is included by the .travis.yml configuration in the root of the +; Flag repository. Configuration set here will be utilized when the testing +; suite is run by Travis CI. +; + +; Disable mail sending. +sendmail_path = 'true' + +; Set memory limit. +memory_limit = 128M + +; Ensure a default of fixing paths is enabled. +cgi.fix_pathinfo = 1 \ No newline at end of file diff --git a/.travis/vhost.conf b/.travis/vhost.conf new file mode 100644 index 0000000..22ee6f2 --- /dev/null +++ b/.travis/vhost.conf @@ -0,0 +1,40 @@ +# +# Apache VirtualHost configuration used by Travis CI. +# +# This configuration file will be placed into the default Apache configuration +# on test machines, making it so that the localhost URL will be able to serve +# pages generated by PHP-FPM. +# + + ServerAdmin webmaster@localhost + DocumentRoot /var/www + + + Options FollowSymLinks + AllowOverride None + + + # This directory will be replaced with the appropriate web root by the + # .travis.yml configuration. + + Options Indexes FollowSymLinks MultiViews ExecCGI + AllowOverride All + Order allow,deny + Allow from all + + + # Wire up Apache to use Travis CI's php-fpm. + + AddHandler php5-fcgi .php + Action php5-fcgi /php5-fcgi + Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi + FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -idle-timeout 120 -host 127.0.0.1:9000 -pass-header Authorization + + + # Possible values include: debug, info, notice, warn, error, crit, + # alert, emerg. + LogLevel warn + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + \ No newline at end of file From 6aff4f94ff26d72d7fa066f4c516f3a9874585de Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 21 Oct 2014 21:38:49 -0500 Subject: [PATCH 606/629] Corrected incorrect php.ini and vhost.conf copy path. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cec882b..d0079c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ before_install: - sudo apt-get update > /dev/null - sudo apt-get install apache2 libapache2-mod-fastcgi > /dev/null - sudo a2enmod rewrite actions fastcgi alias - - sudo cp -f core/misc/travis-ci/vhost.conf /etc/apache2/sites-available/default + - sudo cp -f .travis/vhost.conf /etc/apache2/sites-available/default - sudo sed -i -e "s,/var/www,`pwd`,g" /etc/apache2/sites-available/default # Start PHP-FPM. There is no process manager available to start PHP-FPM on @@ -32,7 +32,7 @@ before_install: - $HOME/.phpenv/versions/`php -r "print PHP_VERSION;"`/sbin/php-fpm # Import the PHP configuration. - - phpenv config-add core/misc/travis-ci/php.ini + - phpenv config-add ./travis/php.ini # Always update Composer to the recent version, otherwise the drush # installation fails. From 88144d4cef2b5fdf9dfe993183cab53268d74d20 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 21 Oct 2014 21:51:15 -0500 Subject: [PATCH 607/629] Fixed broken php.ini copy directive. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d0079c4..ffb75d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ before_install: - $HOME/.phpenv/versions/`php -r "print PHP_VERSION;"`/sbin/php-fpm # Import the PHP configuration. - - phpenv config-add ./travis/php.ini + - phpenv config-add .travis/php.ini # Always update Composer to the recent version, otherwise the drush # installation fails. From aa0c3aa18f55a182df64f2c825bca56b90ffc9c8 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 21 Oct 2014 22:10:48 -0500 Subject: [PATCH 608/629] Fixed broken drush si DB string. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ffb75d3..7f95d7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,7 +65,7 @@ before_script: - git clone --depth 1 --branch $DRUPAL_VERSION $DRUPAL_REPO drupal - cd drupal # Install Drupal. - - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@1localhost/drupal testing + - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@localhost/drupal testing # Reference and enable flag in build site. - ln -s $TESTDIR modules/$MODULE_NAME From e4d64443a5190ffbad79531508a23692f6412227 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 21 Oct 2014 22:48:23 -0500 Subject: [PATCH 609/629] Updated Flag and FlagInterface due to https://www.drupal.org/node/2352673. --- src/Entity/Flag.php | 2 +- src/FlagInterface.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 4127216..9848534 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -259,7 +259,7 @@ public function getFlaggableEntityType() { /** * {@inheritdoc} */ - public function getPluginBags() { + public function getPluginCollections() { return [ 'flagTypeConfig' => $this->flagTypeBag, 'linkTypeConfig' => $this->linkTypeBag, diff --git a/src/FlagInterface.php b/src/FlagInterface.php index 6673569..0354d57 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -8,7 +8,7 @@ use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityWithPluginBagsInterface; +use Drupal\Core\Entity\EntityWithPluginCollectionInterface; use Drupal\Core\Session\AccountInterface; /** @@ -16,7 +16,7 @@ * * @package Drupal\flag */ -interface FlagInterface extends ConfigEntityInterface, EntityWithPluginBagsInterface { +interface FlagInterface extends ConfigEntityInterface, EntityWithPluginCollectionInterface { /* @todo: Add getters and setters as necessary. */ @@ -243,7 +243,7 @@ public function setUnflagDeniedText($unflag_denied_text); /** * {@inheritdoc} */ - public function getPluginBags(); + public function getPluginCollections(); /** * User access permission for flagging actions. From 3e14cd01a0c14fcc3beb02ef8ec3171ca3b0d0cb Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 21 Oct 2014 23:15:55 -0500 Subject: [PATCH 610/629] Updated references to DefaultSingleLazyPluginCollection. --- src/Entity/Flag.php | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 9848534..ff14bd0 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -6,7 +6,7 @@ namespace Drupal\flag\Entity; -use Drupal\Core\Plugin\DefaultSinglePluginBag; +use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; @@ -156,7 +156,7 @@ class Flag extends ConfigEntityBase implements FlagInterface { /** * A bag to store the FlagType plugin. * - * @var \Drupal\Core\Plugin\DefaultSinglePluginBag + * @var \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection */ protected $flagTypeBag; @@ -178,7 +178,7 @@ class Flag extends ConfigEntityBase implements FlagInterface { /** * A bag to store the ActionLink plugin. * - * @var \Drupal\Core\Plugin\DefaultSinglePluginBag + * @var \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection */ protected $linkTypeBag; @@ -203,13 +203,17 @@ public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); if ($this->flag_type) { - $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), - $this->flag_type, $this->flagTypeConfig); + $this->flagTypeBag = new DefaultSingleLazyPluginCollection( + \Drupal::service('plugin.manager.flag.flagtype'), + $this->flag_type, $this->flagTypeConfig + ); } if ($this->link_type) { - $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), - $this->link_type, $this->linkTypeConfig); + $this->linkTypeBag = new DefaultSingleLazyPluginCollection( + \Drupal::service('plugin.manager.flag.linktype'), + $this->link_type, $this->linkTypeConfig + ); } } @@ -280,8 +284,10 @@ public function setFlagTypePlugin($plugin_id) { $this->flag_type = $plugin_id; // $this->flagTypeBag->addInstanceId($pluginID); // Workaround for https://www.drupal.org/node/2288805 - $this->flagTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.flagtype'), - $this->flag_type, $this->flagTypeConfig); + $this->flagTypeBag = new DefaultSingleLazyPluginCollection( + \Drupal::service('plugin.manager.flag.flagtype'), + $this->flag_type, $this->flagTypeConfig + ); // Get the entity type from the plugin definition. $plugin = $this->getFlagTypePlugin(); @@ -304,8 +310,10 @@ public function setlinkTypePlugin($plugin_id) { // $this->linkTypeBag->addInstanceId($pluginID); // Workaround for https://www.drupal.org/node/2288805 - $this->linkTypeBag = new DefaultSinglePluginBag(\Drupal::service('plugin.manager.flag.linktype'), - $this->link_type, $this->linkTypeConfig); + $this->linkTypeBag = new DefaultSingleLazyPluginCollection( + \Drupal::service('plugin.manager.flag.linktype'), + $this->link_type, $this->linkTypeConfig + ); } /** From 623431e222b3820b49f508cbc1c745b21943d402 Mon Sep 17 00:00:00 2001 From: Sascha Grossenbacher Date: Wed, 26 Nov 2014 19:24:12 +0100 Subject: [PATCH 611/629] Rename _content to _controller --- flag.routing.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag.routing.yml b/flag.routing.yml index 7c1df01..9170730 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -89,7 +89,7 @@ flag.confirm_unflag: flag.field_entry: path: '/flag/details/flag/{flag_id}/{entity_id}' defaults: - _content: '\Drupal\flag\Controller\FieldEntryFormController::flag' + _controller: '\Drupal\flag\Controller\FieldEntryFormController::flag' _title_callback: '\Drupal\flag\Controller\FieldEntryFormController::flagTitle' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' @@ -97,7 +97,7 @@ flag.field_entry: flag.field_entry.edit: path: '/flag/details/edit/{flag_id}/{entity_id}' defaults: - _content: '\Drupal\flag\Controller\FieldEntryFormController::edit' + _controller: '\Drupal\flag\Controller\FieldEntryFormController::edit' _title_callback: '\Drupal\flag\Controller\FieldEntryFormController::editTitle' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' From b9c6fb83bce65f599af4fb91989ee81bf69c4d23 Mon Sep 17 00:00:00 2001 From: socketwench Date: Wed, 3 Dec 2014 22:13:56 -0600 Subject: [PATCH 612/629] Fixed broken ActionLinkTypeBase due to https://www.drupal.org/node/2382211 --- src/ActionLinkTypeBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 520d9fa..2d45454 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -72,7 +72,7 @@ public function renderLink($action, FlagInterface $flag, EntityInterface $entity // @todo: Use whatever https://www.drupal.org/node/2302065 comes up with // instead. - $url->setRouteParameter('destination', current_path()); + $url->setRouteParameter('destination', Url::fromRoute('')); $render = $url->toRenderArray(); $render['#type'] = 'link'; From 8e204717bf7a8cb24e3a0038f5c39ae2546f158b Mon Sep 17 00:00:00 2001 From: Florian Weber Date: Thu, 11 Dec 2014 15:37:00 +0100 Subject: [PATCH 613/629] Replace current_path() with Url::fromRoute() --- src/ActionLinkTypeBase.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index 520d9fa..479c7bc 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -69,10 +69,7 @@ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) */ public function renderLink($action, FlagInterface $flag, EntityInterface $entity) { $url = $this->buildLink($action, $flag, $entity); - - // @todo: Use whatever https://www.drupal.org/node/2302065 comes up with - // instead. - $url->setRouteParameter('destination', current_path()); + $url->setRouteParameter('destination', Url::fromRoute('')->toString()); $render = $url->toRenderArray(); $render['#type'] = 'link'; From 70e9adb138d30b722cc811123261c23888158097 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 13 Dec 2014 00:43:53 -0600 Subject: [PATCH 614/629] Fixed broken confirm form destinations. --- src/ActionLinkTypeBase.php | 20 +++++++++++++++++++- src/Form/FlaggingForm.php | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/ActionLinkTypeBase.php b/src/ActionLinkTypeBase.php index cca6d84..85856ba 100644 --- a/src/ActionLinkTypeBase.php +++ b/src/ActionLinkTypeBase.php @@ -64,13 +64,31 @@ public function buildLink($action, FlagInterface $flag, EntityInterface $entity) return new Url($this->routeName($action), $parameters); } + /** + * Helper method to generate a destination URL parameter. + * + * @return string + * A string containing a destination URL parameter. + */ + protected function getDestination() { + $current_url = Url::fromRoute(''); + $route_params = $current_url->getRouteParameters(); + + if (isset($route_params['destination'])) { + return $route_params['destination']; + } + + $current_path = ltrim($current_url->toString(), '/'); + return $current_path; + } + /** * {@inheritdoc} */ public function renderLink($action, FlagInterface $flag, EntityInterface $entity) { $url = $this->buildLink($action, $flag, $entity); - $url->setRouteParameter('destination', Url::fromRoute('')->toString()); + $url->setRouteParameter('destination', $this->getDestination()); $render = $url->toRenderArray(); $render['#type'] = 'link'; diff --git a/src/Form/FlaggingForm.php b/src/Form/FlaggingForm.php index 8af5237..23954ab 100644 --- a/src/Form/FlaggingForm.php +++ b/src/Form/FlaggingForm.php @@ -47,6 +47,7 @@ public function actions(array $form, FormStateInterface $form_state) { $route_params = [ 'flag_id' => $this->entity->getFlagId(), 'entity_id' => $this->entity->getFlaggableId(), + 'destination' => \Drupal::request()->get('destination'), ]; $url = Url::fromRoute('flag.confirm_unflag', $route_params); From 43ea519695d1d9109ebd1c29d39cb952bf465ea1 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 13 Dec 2014 22:32:28 -0600 Subject: [PATCH 615/629] #97 core doesn't use the term 'plugin bag' any more --- src/Entity/Flag.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index ff14bd0..6061199 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -154,11 +154,11 @@ class Flag extends ConfigEntityBase implements FlagInterface { protected $flag_type; /** - * A bag to store the FlagType plugin. + * A collection to store the FlagType plugin. * * @var \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection */ - protected $flagTypeBag; + protected $flagTypeCollection; /** * An array to store and load the FlagType plugin configuration. @@ -176,11 +176,11 @@ class Flag extends ConfigEntityBase implements FlagInterface { protected $link_type; /** - * A bag to store the ActionLink plugin. + * A collection to store the ActionLink plugin. * * @var \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection */ - protected $linkTypeBag; + protected $linkTypeCollection; /** * An array to store and load the ActionLink plugin configuration. @@ -203,14 +203,14 @@ public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); if ($this->flag_type) { - $this->flagTypeBag = new DefaultSingleLazyPluginCollection( + $this->flagTypeCollection = new DefaultSingleLazyPluginCollection( \Drupal::service('plugin.manager.flag.flagtype'), $this->flag_type, $this->flagTypeConfig ); } if ($this->link_type) { - $this->linkTypeBag = new DefaultSingleLazyPluginCollection( + $this->linkTypeCollection = new DefaultSingleLazyPluginCollection( \Drupal::service('plugin.manager.flag.linktype'), $this->link_type, $this->linkTypeConfig ); @@ -265,8 +265,8 @@ public function getFlaggableEntityType() { */ public function getPluginCollections() { return [ - 'flagTypeConfig' => $this->flagTypeBag, - 'linkTypeConfig' => $this->linkTypeBag, + 'flagTypeConfig' => $this->flagTypeCollection, + 'linkTypeConfig' => $this->linkTypeCollection, ]; } @@ -274,7 +274,7 @@ public function getPluginCollections() { * {@inheritdoc} */ public function getFlagTypePlugin() { - return $this->flagTypeBag->get($this->flag_type); + return $this->flagTypeCollection->get($this->flag_type); } /** @@ -284,7 +284,7 @@ public function setFlagTypePlugin($plugin_id) { $this->flag_type = $plugin_id; // $this->flagTypeBag->addInstanceId($pluginID); // Workaround for https://www.drupal.org/node/2288805 - $this->flagTypeBag = new DefaultSingleLazyPluginCollection( + $this->flagTypeCollection = new DefaultSingleLazyPluginCollection( \Drupal::service('plugin.manager.flag.flagtype'), $this->flag_type, $this->flagTypeConfig ); @@ -299,7 +299,7 @@ public function setFlagTypePlugin($plugin_id) { * {@inheritdoc} */ public function getLinkTypePlugin() { - return $this->linkTypeBag->get($this->link_type); + return $this->linkTypeCollection->get($this->link_type); } /** @@ -310,7 +310,7 @@ public function setlinkTypePlugin($plugin_id) { // $this->linkTypeBag->addInstanceId($pluginID); // Workaround for https://www.drupal.org/node/2288805 - $this->linkTypeBag = new DefaultSingleLazyPluginCollection( + $this->linkTypeCollection = new DefaultSingleLazyPluginCollection( \Drupal::service('plugin.manager.flag.linktype'), $this->link_type, $this->linkTypeConfig ); From 1c9727db73fceb1ccff4fb402196d8a27d63fa13 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 14 Dec 2014 11:10:10 -0600 Subject: [PATCH 616/629] #78: Standardise Mgr suffix. --- src/FlagService.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/FlagService.php b/src/FlagService.php index dbbe0cc..7d077b4 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -28,7 +28,7 @@ class FlagService { * * @var FlagTypePluginManager */ - private $flagTypeMgr; + private $flagTypeManager; /** * The event dispatcher injected into the service. @@ -42,7 +42,7 @@ class FlagService { * * @var QueryFactory */ - private $entityQueryMgr; + private $entityQueryManager; /** * The current user injected into the service. @@ -54,7 +54,7 @@ class FlagService { /* * @var EntityManagerInterface * */ - private $entityMgr; + private $entityManager; /** * Constructor. @@ -75,11 +75,11 @@ public function __construct(FlagTypePluginManager $flag_type, QueryFactory $entity_query, AccountInterface $current_user, EntityManagerInterface $entity_manager) { - $this->flagTypeMgr = $flag_type; + $this->flagTypeManager = $flag_type; $this->eventDispatcher = $event_dispatcher; - $this->entityQueryMgr = $entity_query; + $this->entityQueryManager = $entity_query; $this->currentUser = $current_user; - $this->entityMgr = $entity_manager; + $this->entityManager = $entity_manager; } /** @@ -97,10 +97,10 @@ public function __construct(FlagTypePluginManager $flag_type, public function fetchDefinition($entity_type = NULL) { // @todo Add caching, PLS! if (!empty($entity_type)) { - return $this->flagTypeMgr->getDefinition($entity_type); + return $this->flagTypeManager->getDefinition($entity_type); } - return $this->flagTypeMgr->getDefinitions(); + return $this->flagTypeManager->getDefinitions(); } /** @@ -121,7 +121,7 @@ public function fetchDefinition($entity_type = NULL) { * An array of the structure [fid] = flag_object. */ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $account = NULL) { - $query = $this->entityQueryMgr->get('flag'); + $query = $this->entityQueryManager->get('flag'); if ($entity_type != NULL) { $query->condition('entity_type', $entity_type); @@ -133,7 +133,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ $result = $query->execute(); - $flags = $this->entityMgr->getStorage('flag')->loadMultiple($result); + $flags = $this->entityManager->getStorage('flag')->loadMultiple($result); if ($account == NULL) { return $flags; @@ -166,7 +166,7 @@ public function getFlags($entity_type = NULL, $bundle = NULL, AccountInterface $ * An array of flaggings. */ public function getFlaggings(EntityInterface $entity = NULL, FlagInterface $flag = NULL, AccountInterface $account = NULL) { - $query = $this->entityQueryMgr->get('flagging'); + $query = $this->entityQueryManager->get('flagging'); if (!empty($account)) { $query = $query->condition('uid', $account->id()); @@ -185,7 +185,7 @@ public function getFlaggings(EntityInterface $entity = NULL, FlagInterface $flag $flaggings = []; foreach ($result as $flagging_id) { - $flaggings[$flagging_id] = $this->entityMgr->getStorage('flagging')->load($flagging_id); + $flaggings[$flagging_id] = $this->entityManager->getStorage('flagging')->load($flagging_id); } return $flaggings; @@ -201,7 +201,7 @@ public function getFlaggings(EntityInterface $entity = NULL, FlagInterface $flag * The flag entity. */ public function getFlagById($flag_id) { - return $this->entityMgr->getStorage('flag')->load($flag_id); + return $this->entityManager->getStorage('flag')->load($flag_id); } /** @@ -216,7 +216,7 @@ public function getFlagById($flag_id) { * The flaggable entity object. */ public function getFlaggableById(FlagInterface $flag, $entity_id) { - return $this->entityMgr->getStorage($flag->getFlaggableEntityType())->load($entity_id); + return $this->entityManager->getStorage($flag->getFlaggableEntityType())->load($entity_id); } /** @@ -231,7 +231,7 @@ public function getFlaggableById(FlagInterface $flag, $entity_id) { * An array of users who have flagged the entity. */ public function getFlaggingUsers(EntityInterface $entity, FlagInterface $flag = NULL) { - $query = $this->entityQueryMgr->get('users') + $query = $this->entityQueryManager->get('users') ->condition('entity_type', $entity->getEntityTypeId()) ->condition('entity_id', $entity->id()); @@ -268,7 +268,7 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $account = $this->currentUser; } - $flagging = $this->entityMgr->getStorage('flagging')->create([ + $flagging = $this->entityManager->getStorage('flagging')->create([ 'type' => 'flag', 'uid' => $account->id(), 'fid' => $flag->id(), @@ -280,7 +280,7 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $this->incrementFlagCounts($flag, $entity); - $this->entityMgr + $this->entityManager ->getViewBuilder($entity->getEntityTypeId()) ->resetCache([ $entity, From c9c97fab18e16cff23cf622b107bfd858c1e2444 Mon Sep 17 00:00:00 2001 From: socketwench Date: Tue, 16 Dec 2014 23:11:59 -0600 Subject: [PATCH 617/629] Flag disable confirm form, operation entry. --- flag.module | 26 ++++++++++ flag.routing.yml | 16 ++++++ src/Controller/FlagListController.php | 3 ++ src/Entity/Flag.php | 31 ++++++++++++ src/FlagInterface.php | 6 +++ src/Form/FlagDisableConfirmForm.php | 70 +++++++++++++++++++++++++++ 6 files changed, 152 insertions(+) create mode 100644 src/Form/FlagDisableConfirmForm.php diff --git a/flag.module b/flag.module index 2603769..455d146 100644 --- a/flag.module +++ b/flag.module @@ -587,3 +587,29 @@ function flag_reset_flag($flag, $entity_id = NULL) { $count_query->execute(); return $query->execute(); } + +/** + * Implements hook_entity_operation(). + */ +function flag_entity_operation(\Drupal\Core\Entity\EntityInterface $entity) { + $operations = []; + + if ($entity instanceof \Drupal\flag\FlagInterface) { + if ($entity->isEnabled()) { + $operations['enable'] = [ + 'title' => t('Enable'), + 'route_name' => 'flag.enable', + 'weight' => 50, + ]; + } + else { + $operations['disable'] = [ + 'title' => t('Disable'), + 'route_name' => 'flag.disable', + 'weight' => 50, + ]; + } + } + + return $operations; +} \ No newline at end of file diff --git a/flag.routing.yml b/flag.routing.yml index 9170730..43eec97 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -101,3 +101,19 @@ flag.field_entry.edit: _title_callback: '\Drupal\flag\Controller\FieldEntryFormController::editTitle' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + +flag.enable: + path: '/flag/enable/{flag}' + defaults: + _form: '\Drupal\flag\Form\FlagDisableConfirmForm' + _title: 'Enable Flag?' + requirements: + _permission: 'administer flags' + +flag.disable: + path: '/flag/disable/{flag}' + defaults: + _form: '\Drupal\flag\Form\FlagDisableConfirmForm' + _title: 'Disable Flag?' + requirements: + _permission: 'administer flags' diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 238450c..d162f0c 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -26,6 +26,7 @@ public function buildHeader() { $header['label'] = t('Flag'); $header['roles'] = t('Roles'); $header['is_global'] = t('Global?'); + $header['status'] = t('Status'); return $header + parent::buildHeader(); } @@ -71,6 +72,8 @@ public function buildRow(EntityInterface $entity) { $row['is_global'] = $entity->isGlobal() ? t('Yes') : t('No'); + $row['status'] = $entity->isEnabled() ? t('enabled') : t('disabled'); + return $row + parent::buildRow($entity); } diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 6061199..71dcd08 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -231,6 +231,13 @@ public function disable() { $this->enabled = FALSE; } + /** + * {@inheritdoc} + */ + public function isEnabled() { + return $this->enabled; + } + /** * {@inheritdoc} */ @@ -514,6 +521,30 @@ public static function preDelete(EntityStorageInterface $storage, array $entitie } } + /** + * Sorts the flag entities, putting disabled flags at the bottom. + * + * @see \Drupal\Core\Config\Entity\ConfigEntityBase::sort() + */ + public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) { + + // Check if the entities are flags, if not go with the default. + if ($a instanceof FlagInterface && $b instanceof FlagInterface) { + + if ($a->isEnabled() && $b->isEnabled()) { + return parent::sort($a, $b); + } + elseif (!$a->isEnabled()) { + return -1; + } + elseif (!$b->isEnabled()) { + return 1; + } + } + + return parent::sort($a, $b); + } + /** * {@inheritdoc} */ diff --git a/src/FlagInterface.php b/src/FlagInterface.php index 0354d57..2e0ad87 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -30,6 +30,12 @@ public function enable(); */ public function disable(); + /** + * @return bool + * TRUE if the flag is enabled, FALSE otherwise. + */ + public function isEnabled(); + /** * Returns true of there's a flagging for this flag and the given entity. * diff --git a/src/Form/FlagDisableConfirmForm.php b/src/Form/FlagDisableConfirmForm.php new file mode 100644 index 0000000..2c222bb --- /dev/null +++ b/src/Form/FlagDisableConfirmForm.php @@ -0,0 +1,70 @@ +flag = $flag; + return parent::buildForm($form, $form_state); + } + + public function getFormID() { + return 'flag_disable_confirm_form'; + } + + public function getQuestion() { + if ($flag->isEnabled()) { + return t('Disable flag @name?', array('@name' => $flag->label())); + } + + return t('Enable flag @name?', array('@name' => $flag->label())); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + $destination = \Drupal::request()->get('destination'); + if (!empty($destination)) { + return Url::createFromPath($destination); + } + + return $this->entity->urlInfo(); + } + + public function getDescription() { + if ($this->flag->isEnabled()) { + return t('Users will no longer be able to use the flag, but no data will be lost.'); + } + + return t('The flag will appear once more on configured nodes.'); + } + + public function getConfirmText() { + if ($this->flag->isEnabled()) { + return $this->t('Disable'); + } + + return $this->t('Enable'); + } + + public function submitForm(array &$form, FormStateInterface $form_state) { + if ($this->flag->isEnabled()) { + $this->flag->disable(); + } + + $this->flag->enable(); + } + +} \ No newline at end of file From 1fefd14ca348a36c681dadb6c52fdfed1eee4522 Mon Sep 17 00:00:00 2001 From: socketwench Date: Fri, 19 Dec 2014 23:19:15 -0600 Subject: [PATCH 618/629] Working enable/disable confirm form. --- config/schema/flag.schema.yml | 3 ++ flag.module | 26 ++++++++++ flag.routing.yml | 16 ++++++ src/Controller/FlagListController.php | 3 ++ src/Entity/Flag.php | 35 ++++++++++++- src/FlagInterface.php | 6 +++ src/Form/FlagDisableConfirmForm.php | 71 +++++++++++++++++++++++++++ 7 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 src/Form/FlagDisableConfirmForm.php diff --git a/config/schema/flag.schema.yml b/config/schema/flag.schema.yml index 3e07818..f3dbb6c 100644 --- a/config/schema/flag.schema.yml +++ b/config/schema/flag.schema.yml @@ -18,6 +18,9 @@ flag.flag.*: entity_type: type: string label: 'Flaggable Entity Type' + enabled: + type: boolean + label: 'Is flag enabled' is_global: type: boolean label: 'Is flag global' diff --git a/flag.module b/flag.module index 2603769..4b14c8b 100644 --- a/flag.module +++ b/flag.module @@ -587,3 +587,29 @@ function flag_reset_flag($flag, $entity_id = NULL) { $count_query->execute(); return $query->execute(); } + +/** + * Implements hook_entity_operation(). + */ +function flag_entity_operation(\Drupal\Core\Entity\EntityInterface $entity) { + $operations = []; + + if ($entity instanceof \Drupal\flag\FlagInterface) { + if (!$entity->isEnabled()) { + $operations['enable'] = [ + 'title' => t('Enable'), + 'url' => $entity->urlInfo('enable'), + 'weight' => 50, + ]; + } + else { + $operations['disable'] = [ + 'title' => t('Disable'), + 'url' => $entity->urlInfo('disable'), + 'weight' => 50, + ]; + } + } + + return $operations; +} diff --git a/flag.routing.yml b/flag.routing.yml index 9170730..43eec97 100644 --- a/flag.routing.yml +++ b/flag.routing.yml @@ -101,3 +101,19 @@ flag.field_entry.edit: _title_callback: '\Drupal\flag\Controller\FieldEntryFormController::editTitle' requirements: _custom_access: '\Drupal\flag\FlaggingAccessController::checkflag' + +flag.enable: + path: '/flag/enable/{flag}' + defaults: + _form: '\Drupal\flag\Form\FlagDisableConfirmForm' + _title: 'Enable Flag?' + requirements: + _permission: 'administer flags' + +flag.disable: + path: '/flag/disable/{flag}' + defaults: + _form: '\Drupal\flag\Form\FlagDisableConfirmForm' + _title: 'Disable Flag?' + requirements: + _permission: 'administer flags' diff --git a/src/Controller/FlagListController.php b/src/Controller/FlagListController.php index 238450c..d162f0c 100644 --- a/src/Controller/FlagListController.php +++ b/src/Controller/FlagListController.php @@ -26,6 +26,7 @@ public function buildHeader() { $header['label'] = t('Flag'); $header['roles'] = t('Roles'); $header['is_global'] = t('Global?'); + $header['status'] = t('Status'); return $header + parent::buildHeader(); } @@ -71,6 +72,8 @@ public function buildRow(EntityInterface $entity) { $row['is_global'] = $entity->isGlobal() ? t('Yes') : t('No'); + $row['status'] = $entity->isEnabled() ? t('enabled') : t('disabled'); + return $row + parent::buildRow($entity); } diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index 6061199..ee7be06 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -39,7 +39,9 @@ * }, * links = { * "edit-form" = "flag.edit", - * "delete-form" = "flag.delete" + * "delete-form" = "flag.delete", + * "enable" = "flag.enable", + * "disable" = "flag.disable" * } * ) */ @@ -231,6 +233,13 @@ public function disable() { $this->enabled = FALSE; } + /** + * {@inheritdoc} + */ + public function isEnabled() { + return $this->enabled; + } + /** * {@inheritdoc} */ @@ -514,6 +523,30 @@ public static function preDelete(EntityStorageInterface $storage, array $entitie } } + /** + * Sorts the flag entities, putting disabled flags at the bottom. + * + * @see \Drupal\Core\Config\Entity\ConfigEntityBase::sort() + */ + public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) { + + // Check if the entities are flags, if not go with the default. + if ($a instanceof FlagInterface && $b instanceof FlagInterface) { + + if ($a->isEnabled() && $b->isEnabled()) { + return parent::sort($a, $b); + } + elseif (!$a->isEnabled()) { + return -1; + } + elseif (!$b->isEnabled()) { + return 1; + } + } + + return parent::sort($a, $b); + } + /** * {@inheritdoc} */ diff --git a/src/FlagInterface.php b/src/FlagInterface.php index 0354d57..2e0ad87 100644 --- a/src/FlagInterface.php +++ b/src/FlagInterface.php @@ -30,6 +30,12 @@ public function enable(); */ public function disable(); + /** + * @return bool + * TRUE if the flag is enabled, FALSE otherwise. + */ + public function isEnabled(); + /** * Returns true of there's a flagging for this flag and the given entity. * diff --git a/src/Form/FlagDisableConfirmForm.php b/src/Form/FlagDisableConfirmForm.php new file mode 100644 index 0000000..684501c --- /dev/null +++ b/src/Form/FlagDisableConfirmForm.php @@ -0,0 +1,71 @@ +flag = $flag; + return parent::buildForm($form, $form_state); + } + + public function getFormID() { + return 'flag_disable_confirm_form'; + } + + public function getQuestion() { + if ($this->flag->isEnabled()) { + return t('Disable flag @name?', array('@name' => $this->flag->label())); + } + + return t('Enable flag @name?', array('@name' => $this->flag->label())); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return new Url('flag.list'); + } + + public function getDescription() { + if ($this->flag->isEnabled()) { + return t('Users will no longer be able to use the flag, but no data will be lost.'); + } + + return t('The flag will appear once more on configured nodes.'); + } + + public function getConfirmText() { + if ($this->flag->isEnabled()) { + return $this->t('Disable'); + } + + return $this->t('Enable'); + } + + public function submitForm(array &$form, FormStateInterface $form_state) { + if ($this->flag->isEnabled()) { + $this->flag->disable(); + } + else { + $this->flag->enable(); + } + + $this->flag->save(); + + $form_state->setRedirect('flag.list'); + } + +} \ No newline at end of file From 09e0d2eef7d2402d65ef9255b8aabd819cd7a5d2 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 21 Dec 2014 23:15:51 -0600 Subject: [PATCH 619/629] Prevented display of links for disabled flags. Invalidated the render cache of the flaggable. --- flag.module | 7 ++++++- src/Form/FlagDisableConfirmForm.php | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/flag.module b/flag.module index 4b14c8b..e159c72 100644 --- a/flag.module +++ b/flag.module @@ -164,7 +164,7 @@ function flag_node_links_alter(array &$links, NodeInterface $entity, array &$con * Handles the 'show_in_links' and 'show_as_field' flag options. */ function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode, $langcode) { - // Don't act on previews. + // Don't show on previews. if ($entity->isNew()) { return; } @@ -176,6 +176,11 @@ function flag_entity_view(array &$build, EntityInterface $entity, EntityViewDisp $flags = $flag_service->getFlags($entity->getEntityTypeID(), $entity->bundle()); foreach ($flags as $flag) { + // Do not display the flag if disabled. + if(!$flag->isEnabled()){ + continue; + } + $link_type_plugin = $flag->getLinkTypePlugin(); $flag_type_plugin = $flag->getFlagTypePlugin(); diff --git a/src/Form/FlagDisableConfirmForm.php b/src/Form/FlagDisableConfirmForm.php index 3e1fe59..e7ac0e8 100644 --- a/src/Form/FlagDisableConfirmForm.php +++ b/src/Form/FlagDisableConfirmForm.php @@ -56,6 +56,7 @@ public function getConfirmText() { } public function submitForm(array &$form, FormStateInterface $form_state) { + // Toggle the flag state. if ($this->flag->isEnabled()) { $this->flag->disable(); } @@ -63,8 +64,15 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->flag->enable(); } + // Invalidate the flaggable render cache. + \Drupal::entityManager() + ->getViewBuilder($this->flag->entity_type) + ->resetCache(); + + // Save The flag entity. $this->flag->save(); + // Redirect to the flag admin page. $form_state->setRedirect('flag.list'); } From abc03e842402f9fee4c5a85a64ac19f853784e05 Mon Sep 17 00:00:00 2001 From: socketwench Date: Mon, 22 Dec 2014 21:27:55 -0600 Subject: [PATCH 620/629] Fixed a missing namespace reference breaking Flag::sort(). --- src/Entity/Flag.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Entity/Flag.php b/src/Entity/Flag.php index ee7be06..91169b9 100644 --- a/src/Entity/Flag.php +++ b/src/Entity/Flag.php @@ -11,6 +11,7 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\flag\Event\FlagDeleteEvent; use Drupal\flag\Event\FlagEvents; use Drupal\flag\FlagInterface; From 4a9e191a4743c1894f74a8570ccb2d8ae785c8f6 Mon Sep 17 00:00:00 2001 From: socketwench Date: Thu, 25 Dec 2014 23:27:46 -0600 Subject: [PATCH 621/629] Added test for enable/disable feature. --- src/Tests/FlagEnableDisableTest.php | 152 ++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 src/Tests/FlagEnableDisableTest.php diff --git a/src/Tests/FlagEnableDisableTest.php b/src/Tests/FlagEnableDisableTest.php new file mode 100644 index 0000000..23cec77 --- /dev/null +++ b/src/Tests/FlagEnableDisableTest.php @@ -0,0 +1,152 @@ +adminUser = $this->drupalCreateUser([ + 'administer flags', + 'administer flagging display', + 'administer node display', + ]); + + $this->drupalLogin($this->adminUser); + + $this->doCreateFlag(); + $this->doCreateNode(); + $this->doDisableFlag(); + $this->doEnableFlag(); + } + + /** + * Create a node type and a flag. + */ + public function doCreateFlag() { + // Create content type. + $this->drupalCreateContentType(['type' => $this->nodeType]); + + // Test with minimal value requirement. + $edit = [ + 'label' => $this->label, + 'id' => $this->id, + 'flag_entity_type' => 'flagtype_node', + ]; + $this->drupalPostForm('admin/structure/flags/add', $edit, t('Continue')); + + $edit = [ + 'types[' . $this->nodeType . ']' => $this->nodeType, + 'flag_short' => $this->flagShortText, + 'unflag_short' => $this->unflagShortText, + ]; + $this->drupalPostForm(NULL, $edit, t('Create Flag')); + } + + /** + * Create a node and flag it. + */ + public function doCreateNode() { + $node = $this->drupalCreateNode(['type' => $this->nodeType]); + $this->node_id = $node->id(); + + // Grant the flag permissions to the authenticated role, so that both + // users have the same roles and share the render cache. + $role = Role::load(DRUPAL_AUTHENTICATED_RID); + $role->grantPermission('flag ' . $this->id); + $role->grantPermission('unflag ' . $this->id); + $role->save(); + + // Click the flag link. + $this->drupalGet('node/' . $this->node_id); + + $this->assertText($this->flagShortText); + } + + public function doDisableFlag() { + $this->drupalGet('admin/structure/flags'); + $this->assertText(t('enabled')); + + $this->drupalPostForm('flag/disable/' . $this->id, [], t('Disable')); + $this->assertResponse(200); + + $this->drupalGet('admin/structure/flags'); + $this->assertText(t('disabled')); + + $this->drupalGet('node/' . $this->node_id); + $this->assertNoText($this->flagShortText); + } + + public function doEnableFlag() { + $this->drupalGet('admin/structure/flags'); + $this->assertText(t('disabled')); + + $this->drupalPostForm('flag/enable/' . $this->id, [], t('Enable')); + $this->assertResponse(200); + + $this->drupalGet('admin/structure/flags'); + $this->assertText(t('enabled')); + + $this->drupalGet('node/' . $this->node_id); + $this->assertText($this->flagShortText); + } +} \ No newline at end of file From 07769bc1ce2b67fbd876e744347b6353b0b58090 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 27 Dec 2014 21:00:38 -0600 Subject: [PATCH 622/629] Added comment blocks to FlagEnableDisableTest. --- src/Tests/FlagEnableDisableTest.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Tests/FlagEnableDisableTest.php b/src/Tests/FlagEnableDisableTest.php index 23cec77..8f533a3 100644 --- a/src/Tests/FlagEnableDisableTest.php +++ b/src/Tests/FlagEnableDisableTest.php @@ -63,6 +63,9 @@ class FlagEnableDisableTest extends WebTestBase { */ public static $modules = array('views', 'flag', 'node', 'field_ui'); + /** + * Test the enabling and disabling of a flag from the Admin UI. + */ public function testDiableEnableFlag() { // Create and log in our user. $this->adminUser = $this->drupalCreateUser([ @@ -122,6 +125,9 @@ public function doCreateNode() { $this->assertText($this->flagShortText); } + /** + * Disable the flag and ensure the link does not appear on entities. + */ public function doDisableFlag() { $this->drupalGet('admin/structure/flags'); $this->assertText(t('enabled')); @@ -136,6 +142,9 @@ public function doDisableFlag() { $this->assertNoText($this->flagShortText); } + /** + * Enable the flag and ensure it appears on target entities. + */ public function doEnableFlag() { $this->drupalGet('admin/structure/flags'); $this->assertText(t('disabled')); @@ -149,4 +158,4 @@ public function doEnableFlag() { $this->drupalGet('node/' . $this->node_id); $this->assertText($this->flagShortText); } -} \ No newline at end of file +} From 6373999e216fbbe8c1e456c8aa6c40730de9abd2 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sat, 27 Dec 2014 23:58:55 -0600 Subject: [PATCH 623/629] Experimental hostname set for Travis CI. --- .travis.yml | 5 ++++- .travis/hosts | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .travis/hosts diff --git a/.travis.yml b/.travis.yml index 7f95d7b..9cfa201 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,9 @@ env: - CODER_VERSION='dev-8.x-2.x' before_install: + // Set a local hostname alias + - sudo cp -f .travis/hosts /etc/hosts + # Install Apache and FastCGI extension to connect to PHP-FPM. - sudo apt-get update > /dev/null - sudo apt-get install apache2 libapache2-mod-fastcgi > /dev/null @@ -81,7 +84,7 @@ script: # Run the Coder sniffer for Flag. - phpcs --report=full --standard=Drupal ./modules/$MODULE_NAME # Run the Simpletests for Flag. - - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://localhost --verbose --color "$MODULE_TEST_GROUP" + - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://drupal8.dev --verbose --color "$MODULE_TEST_GROUP" # Run the PHPUnit tests. - ./core/vendor/phpunit/phpunit/phpunit -c ./core/phpunit.xml.dist ./modules/$MODULE_NAME diff --git a/.travis/hosts b/.travis/hosts new file mode 100644 index 0000000..10c1f45 --- /dev/null +++ b/.travis/hosts @@ -0,0 +1 @@ +127.0.0.1 drupal8.dev From ea6f44bc9977297788e177619584dc87cdfe991b Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Dec 2014 00:01:44 -0600 Subject: [PATCH 624/629] Fixed broken .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9cfa201..7aaf907 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ env: - CODER_VERSION='dev-8.x-2.x' before_install: - // Set a local hostname alias + # Set a local hostname alias - sudo cp -f .travis/hosts /etc/hosts # Install Apache and FastCGI extension to connect to PHP-FPM. From 56eb2414f133b24ff88a7f001f7a18dee07c3c36 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Dec 2014 00:34:55 -0600 Subject: [PATCH 625/629] Removed brute force hostname set, replaced with best practice. --- .travis.yml | 9 +++++---- .travis/hosts | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 .travis/hosts diff --git a/.travis.yml b/.travis.yml index 7aaf907..3c441b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,10 @@ mysql: username: root encoding: utf8 +addons: + hosts: + - travis.dev + env: global: - MODULE_NAME='flag' @@ -19,9 +23,6 @@ env: - CODER_VERSION='dev-8.x-2.x' before_install: - # Set a local hostname alias - - sudo cp -f .travis/hosts /etc/hosts - # Install Apache and FastCGI extension to connect to PHP-FPM. - sudo apt-get update > /dev/null - sudo apt-get install apache2 libapache2-mod-fastcgi > /dev/null @@ -84,7 +85,7 @@ script: # Run the Coder sniffer for Flag. - phpcs --report=full --standard=Drupal ./modules/$MODULE_NAME # Run the Simpletests for Flag. - - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://drupal8.dev --verbose --color "$MODULE_TEST_GROUP" + - php ./core/scripts/run-tests.sh --php `which php` --concurrency 12 --url http://travis.dev --verbose --color "$MODULE_TEST_GROUP" # Run the PHPUnit tests. - ./core/vendor/phpunit/phpunit/phpunit -c ./core/phpunit.xml.dist ./modules/$MODULE_NAME diff --git a/.travis/hosts b/.travis/hosts deleted file mode 100644 index 10c1f45..0000000 --- a/.travis/hosts +++ /dev/null @@ -1 +0,0 @@ -127.0.0.1 drupal8.dev From b26585586204433affcb8243e44d61af93506961 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Dec 2014 00:48:42 -0600 Subject: [PATCH 626/629] Set URL in travis site install. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3c441b2..67b8ad3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,7 +69,7 @@ before_script: - git clone --depth 1 --branch $DRUPAL_VERSION $DRUPAL_REPO drupal - cd drupal # Install Drupal. - - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@localhost/drupal testing + - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@localhost/drupal --url=http://travis.dev testing # Reference and enable flag in build site. - ln -s $TESTDIR modules/$MODULE_NAME From 36e01f3e9ddea1a3a71d99df538914f90266552d Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Dec 2014 00:54:55 -0600 Subject: [PATCH 627/629] Fixed travis incorrect url param to drush site-install statement. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 67b8ad3..20d1595 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,7 +69,7 @@ before_script: - git clone --depth 1 --branch $DRUPAL_VERSION $DRUPAL_REPO drupal - cd drupal # Install Drupal. - - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes site-install --db-url=mysql://root:@localhost/drupal --url=http://travis.dev testing + - php -d sendmail_path=`which true` ~/.composer/vendor/bin/drush.php --yes --uri=http://travis.dev site-install --db-url=mysql://root:@localhost/drupal testing # Reference and enable flag in build site. - ln -s $TESTDIR modules/$MODULE_NAME From 1afeb9f49c4b41e533e7ddbd6a9538941fcaab30 Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Dec 2014 01:09:28 -0600 Subject: [PATCH 628/629] Set travis virtualhost ServerName directive. --- .travis/vhost.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis/vhost.conf b/.travis/vhost.conf index 22ee6f2..dddccac 100644 --- a/.travis/vhost.conf +++ b/.travis/vhost.conf @@ -8,6 +8,7 @@ ServerAdmin webmaster@localhost DocumentRoot /var/www + ServerName travis.dev Options FollowSymLinks From af27db1479c333a8be8b78a47748941468a59f5a Mon Sep 17 00:00:00 2001 From: socketwench Date: Sun, 28 Dec 2014 13:36:58 -0600 Subject: [PATCH 629/629] Added FlagDisabledException and appropriate throws in FlagService. --- src/Entity/FlagDisabledException.php | 31 ++++++++++++++++++++++++++++ src/FlagService.php | 17 +++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/Entity/FlagDisabledException.php diff --git a/src/Entity/FlagDisabledException.php b/src/Entity/FlagDisabledException.php new file mode 100644 index 0000000..90030a9 --- /dev/null +++ b/src/Entity/FlagDisabledException.php @@ -0,0 +1,31 @@ + $flag->label()))); + } + +} \ No newline at end of file diff --git a/src/FlagService.php b/src/FlagService.php index 7d077b4..e3f3ef7 100644 --- a/src/FlagService.php +++ b/src/FlagService.php @@ -8,6 +8,7 @@ use Drupal\Core\Session\AccountInterface; use Drupal\flag\Entity\Flag; +use Drupal\flag\Entity\FlagDisabledException; use Drupal\flag\Entity\Flagging; use Drupal\flag\Event\FlagEvents; use Drupal\flag\Event\FlaggingEvent; @@ -260,6 +261,9 @@ public function getFlaggingUsers(EntityInterface $entity, FlagInterface $flag = * Optional. The account of the user flagging the entity. If not given, * the current user is used. * + * @throws \Drupal\flag\Entity\FlagDisabledException + * Thrown when a flag operation is being performed against a disabled flag. + * * @return FlaggingInterface|null * The flagging. */ @@ -268,6 +272,11 @@ public function flagByObject(FlagInterface $flag, EntityInterface $entity, Accou $account = $this->currentUser; } + // Throw an exception if the flag is disabled. + if (!$flag->isEnabled()) { + throw new FlagDisabledException($flag); + } + $flagging = $this->entityManager->getStorage('flagging')->create([ 'type' => 'flag', 'uid' => $account->id(), @@ -356,10 +365,18 @@ public function unflag($flag_id, $entity_id, AccountInterface $account = NULL) { * @param AccountInterface $account * Optional. The account of the user that created the flagging. * + * @throws \Drupal\flag\Entity\FlagDisabledException + * Thrown when an unflag is being performed on a disabled flag. + * * @return array * An array of flagging IDs to delete. */ public function unflagByObject(FlagInterface $flag, EntityInterface $entity, AccountInterface $account = NULL) { + // Throw an exception if the flag is disabled. + if (!$flag->isEnabled()) { + throw new FlagDisabledException($flag); + } + $this->eventDispatcher->dispatch(FlagEvents::ENTITY_UNFLAGGED, new FlaggingEvent($flag, $entity, 'unflag')); $out = [];