/** * Determines whether or not the current user has access to the specified media work. If no username is provided, this function defaults to the currently-loggin-in username. * * @param string $username * @return boolean user has access */ public function user_has_access_to_media($username = '') { // First, get the restricted group--if one exists $es = new entity_selector(); $es->add_type(id_of('group_type')); $es->add_right_relationship($this->media_work->id(), relationship_id_of('av_restricted_to_group')); $group = current($es->run_one()); if (!empty($group)) { $gh = new group_helper(); $gh->set_group_by_id($group->id()); if ($gh->requires_login()) { if (!$username) { $username = reason_check_authentication(); } if ($username) { if (!$gh->is_username_member_of_group($username)) { return false; } } else { return false; } } } return true; // Return true if the user has access to view media work }
/** * Get values for filtering index * @param boolean $raw [description] * @return [type] [description] */ public function get_index($raw = false) { if ($raw === false) { $raw = $this->get_raw(); } $id = $this->Tag->id(); $out = array(); if (is_array($raw)) { if (isset($raw['_default'])) { $out[] = array('key' => $id, 'value' => trim($raw['_default'])); } else { if (isset($raw['processed'])) { $out[] = array('key' => $id, 'value' => trim($raw['processed'])); } } foreach ($raw as $key => $val) { if (!is_array($val)) { $out[] = array('key' => $id . '_' . $key, 'value' => trim($val)); } } } else { $out[] = array('key' => $id, 'value' => trim($raw)); } return $out; }
/** * Get an offset if already set or traverse Pod and then set plus reutrn. * * @since 0.1.0 * * @param mixed $offset Offset to get * * @return mixed */ public function offsetGet($offset) { if ($this->offsetExists($offset)) { return parent::offsetGet($offset); } else { if ('id' == $offset || 'ID' == $offset) { $_value = $this->pod->id(); } else { $_value = $this->pod->field($offset); } if ($_value) { parent::offsetSet($offset, $_value); return $_value; } } }
/** * Tests that cron clears day counts and expired access logs. */ function testExpiredLogs() { \Drupal::config('statistics.settings')->set('count_content_views', 1)->save(); \Drupal::state()->set('statistics.day_timestamp', 8640000); $this->drupalGet('node/' . $this->test_node->id()); // Manually calling statistics.php, simulating ajax behavior. $nid = $this->test_node->id(); $post = array('nid' => $nid); global $base_url; $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; $this->client->post($stats_path, array('body' => $post)); $this->drupalGet('node/' . $this->test_node->id()); $this->client->post($stats_path, array('body' => $post)); $this->assertText('1 view', 'Node is viewed once.'); // statistics_cron() will subtract // statistics.settings:accesslog.max_lifetime config from REQUEST_TIME in // the delete query, so wait two secs here to make sure the access log will // be flushed for the node just hit. sleep(2); $this->cronRun(); $this->drupalGet('admin/reports/pages'); $this->assertNoText('node/' . $this->test_node->id(), 'No hit URL found.'); $result = db_select('node_counter', 'nc')->fields('nc', array('daycount'))->condition('nid', $this->test_node->id(), '=')->execute()->fetchField(); $this->assertFalse($result, 'Daycounter is zero.'); }
/** * Initializes group helper by setting the group is to wrap up * @param integer $group_id * @access public * @return void */ function set_group_by_id($group_id) { if (empty($this->group)) { $this->group = new entity($group_id); $this->init_audiences($this->group->id()); } else { trigger_error('Group already set on group helper'); } }
/** * Create taxonomy term reference field for testing categories. * * @param object $vocabulary * Taxonomy vocabulary. * * @return string * Created field name. */ protected function createTaxonomyTermReferenceField($vocabulary) { $field_tags_name = Unicode::strtolower($this->randomMachineName()); $field_storage = entity_create('field_storage_config', array('field_name' => $field_tags_name, 'entity_type' => 'node', 'type' => 'taxonomy_term_reference', 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, 'settings' => array('allowed_values' => array(array('vocabulary' => $vocabulary->id(), 'parent' => '0'))))); $field_storage->save(); entity_create('field_config', array('field_storage' => $field_storage, 'bundle' => 'article'))->save(); entity_get_form_display('node', 'article', 'default')->setComponent($field_tags_name, array('type' => 'taxonomy_autocomplete'))->save(); entity_get_display('node', 'article', 'full')->setComponent($field_tags_name, array('type' => 'taxonomy_term_reference_link'))->save(); return $field_tags_name; }
/** * Check role on user object. * * @param object $account * The user account to check. * @param string $rid * The role ID to search for. * @param bool $is_assigned * (optional) Whether to assert that $rid exists (TRUE) or not (FALSE). * Defaults to TRUE. */ private function userLoadAndCheckRoleAssigned($account, $rid, $is_assigned = TRUE) { $user_storage = $this->container->get('entity.manager')->getStorage('user'); $user_storage->resetCache(array($account->id())); $account = $user_storage->load($account->id()); if ($is_assigned) { $this->assertFalse(array_search($rid, $account->getRoles()) === FALSE, 'The role is present in the user object.'); } else { $this->assertTrue(array_search($rid, $account->getRoles()) === FALSE, 'The role is not present in the user object.'); } }
/** * Verifies that the history endpoints work. */ function testHistory() { $nid = $this->testNode->id(); // Retrieve "last read" timestamp for test node, for the current user. $response = $this->getNodeReadTimestamps(array($nid)); $this->assertResponse(200); $json = Json::decode($response); $this->assertIdentical(array(1 => 0), $json, 'The node has not yet been read.'); // View the node. $this->drupalGet('node/' . $nid); $this->assertCacheContext('user.roles:authenticated'); // JavaScript present to record the node read. $settings = $this->getDrupalSettings(); $libraries = explode(',', $settings['ajaxPageState']['libraries']); $this->assertTrue(in_array('history/mark-as-read', $libraries), 'history/mark-as-read library is present.'); $this->assertEqual([$nid => TRUE], $settings['history']['nodesToMarkAsRead'], 'drupalSettings to mark node as read are present.'); // Simulate JavaScript: perform HTTP request to mark node as read. $response = $this->markNodeAsRead($nid); $this->assertResponse(200); $timestamp = Json::decode($response); $this->assertTrue(is_numeric($timestamp), 'Node has been marked as read. Timestamp received.'); // Retrieve "last read" timestamp for test node, for the current user. $response = $this->getNodeReadTimestamps(array($nid)); $this->assertResponse(200); $json = Json::decode($response); $this->assertIdentical(array(1 => $timestamp), $json, 'The node has been read.'); // Failing to specify node IDs for the first endpoint should return a 404. $this->getNodeReadTimestamps(array()); $this->assertResponse(404); // Accessing either endpoint as the anonymous user should return a 403. $this->drupalLogout(); $this->getNodeReadTimestamps(array($nid)); $this->assertResponse(403); $this->getNodeReadTimestamps(array()); $this->assertResponse(403); $this->markNodeAsRead($nid); $this->assertResponse(403); }
/** * Returns the disconnect URL. * * @static * * @param object $account * @param bool $is_admin * @param string $before * @param string $after * * @return string */ public function disconnect_url($account, $is_admin = false, $before = '', $after = '') { $params = array('social_controller' => 'auth', 'social_action' => 'disconnect', 'id' => $account->id(), 'service' => $this->_key); if ($is_admin) { $personal = defined('IS_PROFILE_PAGE'); $url = Social::settings_url($params, $personal); } else { $params['redirect_to'] = isset($_GET['redirect_to']) ? $_GET['redirect_to'] : $_SERVER['REQUEST_URI']; foreach ($params as $key => $value) { $params[$key] = urlencode($value); } $url = add_query_arg($params, home_url()); } return $url; }
/** * Handles charge.succeeded. * * @param object $eventData * @param object $member * * @return bool */ public function handleChargeSucceeded($eventData, $member) { // currently only handle card charges if ($eventData->source->object != 'card') { return true; } // add to billing history $description = $eventData->description; if (empty($eventData->description) && $member->hasProperty('plan')) { $description = $member->plan; } $history = new BillingHistory(); $history->create(['user_id' => $member->id(), 'payment_time' => $eventData->created, 'amount' => $eventData->amount / 100, 'stripe_customer' => $eventData->customer, 'stripe_transaction' => $eventData->id, 'description' => $description, 'success' => true]); // email member with a receipt if ($this->app['config']->get('billing.emails.payment_receipt')) { $member->sendEmail('payment-received', ['subject' => 'Payment receipt on ' . $this->app['config']->get('app.title'), 'timestamp' => $eventData->created, 'payment_time' => date('F j, Y g:i a T', $eventData->created), 'amount' => number_format($eventData->amount / 100, 2), 'description' => $description, 'card_last4' => $eventData->source->last4, 'card_expires' => $eventData->source->exp_month . '/' . $eventData->source->exp_year, 'card_type' => $eventData->source->brand, 'tags' => ['billing', 'payment-received']]); } return true; }
/** * Tests the access for deleting top-level book nodes. */ function testBookDelete() { $nodes = $this->createBook(); $this->drupalLogin($this->admin_user); $edit = array(); // Test access to delete top-level and child book nodes. $this->drupalGet('node/' . $this->book->id() . '/outline/remove'); $this->assertResponse('403', 'Deleting top-level book node properly forbidden.'); $this->drupalPostForm('node/' . $nodes[4]->id() . '/outline/remove', $edit, t('Remove')); $node4 = node_load($nodes[4]->id(), TRUE); $this->assertTrue(empty($node4->book), 'Deleting child book node properly allowed.'); // Delete all child book nodes and retest top-level node deletion. foreach ($nodes as $node) { $nids[] = $node->id(); } entity_delete_multiple('node', $nids); $this->drupalPostForm('node/' . $this->book->id() . '/outline/remove', $edit, t('Remove')); $node = node_load($this->book->id(), TRUE); $this->assertTrue(empty($node->book), 'Deleting childless top-level book node properly allowed.'); }
/** * Tests the addition and clearing of log events through the admin interface. * * Logs in the admin user, creates a database log event, and tests the * functionality of clearing the database log through the admin interface. */ protected function testDBLogAddAndClear() { global $base_root; // Get a count of how many watchdog entries already exist. $count = db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(); $log = array('channel' => 'system', 'message' => 'Log entry added to test the doClearTest clear down.', 'variables' => array(), 'severity' => WATCHDOG_NOTICE, 'link' => NULL, 'user' => $this->big_user, 'uid' => $this->big_user->id(), 'request_uri' => $base_root . request_uri(), 'referer' => \Drupal::request()->server->get('HTTP_REFERER'), 'ip' => '127.0.0.1', 'timestamp' => REQUEST_TIME); // Add a watchdog entry. $this->container->get('logger.dblog')->log($log['severity'], $log['message'], $log); // Make sure the table count has actually been incremented. $this->assertEqual($count + 1, db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), format_string('dblog_watchdog() added an entry to the dblog :count', array(':count' => $count))); // Login the admin user. $this->drupalLogin($this->big_user); // Post in order to clear the database table. $this->drupalPostForm('admin/reports/dblog', array(), t('Clear log messages')); // Confirm that the logs should be cleared. $this->drupalPostForm(NULL, array(), 'Confirm'); // Count the rows in watchdog that previously related to the deleted user. $count = db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(); $this->assertEqual($count, 0, format_string('DBLog contains :count records after a clear.', array(':count' => $count))); }
/** * Tests the personal contact form flood protection. */ function testPersonalContactFlood() { $flood_limit = 3; \Drupal::config('contact.settings')->set('flood.limit', $flood_limit)->save(); // Clear flood table in preparation for flood test and allow other checks to complete. db_delete('flood')->execute(); $num_records_flood = db_query("SELECT COUNT(*) FROM {flood}")->fetchField(); $this->assertIdentical($num_records_flood, '0', 'Flood table emptied.'); $this->drupalLogin($this->web_user); // Submit contact form with correct values and check flood interval. for ($i = 0; $i < $flood_limit; $i++) { $this->submitPersonalContact($this->contact_user); $this->assertText(t('Your message has been sent.'), 'Message sent.'); } // Submit contact form one over limit. $this->drupalGet('user/' . $this->contact_user->id() . '/contact'); $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => $flood_limit, '@interval' => \Drupal::service('date.formatter')->formatInterval(\Drupal::config('contact.settings')->get('flood.interval')))), 'Normal user denied access to flooded contact form.'); // Test that the admin user can still access the contact form even though // the flood limit was reached. $this->drupalLogin($this->admin_user); $this->assertNoText('Try again later.', 'Admin user not denied access to flooded contact form.'); }
/** * Tests that existing nodes are indexed by cron. */ function testTrackerCronIndexing() { $this->drupalLogin($this->user); // Create 3 nodes. $edits = array(); $nodes = array(); for ($i = 1; $i <= 3; $i++) { $edits[$i] = array('title' => $this->randomMachineName()); $nodes[$i] = $this->drupalCreateNode($edits[$i]); } // Add a comment to the last node as other user. $this->drupalLogin($this->other_user); $comment = array('subject[0][value]' => $this->randomMachineName(), 'comment_body[0][value]' => $this->randomMachineName(20)); $this->drupalPostForm('comment/reply/node/' . $nodes[3]->id() . '/comment', $comment, t('Save')); // Start indexing backwards from node 3. \Drupal::state()->set('tracker.index_nid', 3); // Clear the current tracker tables and rebuild them. db_delete('tracker_node')->execute(); db_delete('tracker_user')->execute(); tracker_cron(); $this->drupalLogin($this->user); // Fetch the user's tracker. $this->drupalGet('activity/' . $this->user->id()); // Assert that all node titles are displayed. foreach ($nodes as $i => $node) { $this->assertText($node->label(), format_string('Node @i is displayed on the tracker listing pages.', array('@i' => $i))); } $this->assertText('1 new', 'One new comment is counted on the tracker listing pages.'); $this->assertText('updated', 'Node is listed as updated'); // Fetch the site-wide tracker. $this->drupalGet('activity'); // Assert that all node titles are displayed. foreach ($nodes as $i => $node) { $this->assertText($node->label(), format_string('Node @i is displayed on the tracker listing pages.', array('@i' => $i))); } $this->assertText('1 new', 'New comment is counted on the tracker listing pages.'); }
/** * Verifies that the history endpoints work. */ function testHistory() { $nid = $this->test_node->id(); // Retrieve "last read" timestamp for test node, for the current user. $response = $this->getNodeReadTimestamps(array($nid)); $this->assertResponse(200); $json = Json::decode($response); $this->assertIdentical(array(1 => 0), $json, 'The node has not yet been read.'); // View the node. $this->drupalGet('node/' . $nid); // JavaScript present to record the node read. $settings = $this->getDrupalSettings(); $this->assertTrue(isset($settings['ajaxPageState']['js']['core/modules/history/js/history.js']), 'drupal.history library is present.'); $this->assertRaw('Drupal.history.markAsRead(' . $nid . ')', 'History module JavaScript API call to mark node as read present on page.'); // Simulate JavaScript: perform HTTP request to mark node as read. $response = $this->markNodeAsRead($nid); $this->assertResponse(200); $timestamp = Json::decode($response); $this->assertTrue(is_numeric($timestamp), 'Node has been marked as read. Timestamp received.'); // Retrieve "last read" timestamp for test node, for the current user. $response = $this->getNodeReadTimestamps(array($nid)); $this->assertResponse(200); $json = Json::decode($response); $this->assertIdentical(array(1 => $timestamp), $json, 'The node has been read.'); // Failing to specify node IDs for the first endpoint should return a 404. $this->getNodeReadTimestamps(array()); $this->assertResponse(404); // Accessing either endpoint as the anonymous user should return a 403. $this->drupalLogout(); $this->getNodeReadTimestamps(array($nid)); $this->assertResponse(403); $this->getNodeReadTimestamps(array()); $this->assertResponse(403); $this->markNodeAsRead($nid); $this->assertResponse(403); }
/** * Ensure the loaded book in hook_node_load() does not depend on the user. */ public function testHookNodeLoadAccess() { \Drupal::service('module_installer')->install(['node_access_test']); // Ensure that the loaded book in hook_node_load() does NOT depend on the // current user. $this->drupalLogin($this->bookAuthor); $this->book = $this->createBookNode('new'); // Reset any internal static caching. $node_storage = \Drupal::entityManager()->getStorage('node'); $node_storage->resetCache(); // Login as user without access to the book node, so no 'node test view' // permission. // @see node_access_test_node_grants(). $this->drupalLogin($this->webUserWithoutNodeAccess); $book_node = $node_storage->load($this->book->id()); $this->assertTrue(!empty($book_node->book)); $this->assertEqual($book_node->book['bid'], $this->book->id()); // Reset the internal cache to retrigger the hook_node_load() call. $node_storage->resetCache(); $this->drupalLogin($this->webUser); $book_node = $node_storage->load($this->book->id()); $this->assertTrue(!empty($book_node->book)); $this->assertEqual($book_node->book['bid'], $this->book->id()); }
/** * Performs the specified operation on the specified comment. * * @param object $comment * Comment to perform operation on. * @param string $operation * Operation to perform. * @param bool $approval * Operation is found on approval page. */ function performCommentOperation($comment, $operation, $approval = FALSE) { $edit = array(); $edit['operation'] = $operation; $edit['comments[' . $comment->id() . ']'] = TRUE; $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update')); if ($operation == 'delete') { $this->drupalPostForm(NULL, array(), t('Delete comments')); $this->assertRaw(\Drupal::translation()->formatPlural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation "@operation" was performed on comment.', array('@operation' => $operation))); } else { $this->assertText(t('The update has been performed.'), format_string('Operation "@operation" was performed on comment.', array('@operation' => $operation))); } }
/** * delete granted permssions for an object * * @param object $obj optional * @return bool TRUE */ private function deleteGrantedPermissions($obj = NULL) { $gperm_handler = icms::handler("icms_member_groupperm"); $module = icms::handler("icms_module")->getByDirname($this->_moduleName); $permissions = $this->getPermissions(); if ($permissions === FALSE) { return TRUE; } foreach ($permissions as $permission) { if ($obj != NULL) { $gperm_handler->deleteByModule($module->getVar("mid"), $permission["perm_name"], $obj->id()); } else { $gperm_handler->deleteByModule($module->getVar("mid"), $permission["perm_name"]); } } return TRUE; }
/** * Returns entity's data using the JSON-API format. * * @param object $entity The Chaos entity. * @param boolean $attributes Extract entities attributes or not. * @return array The JSON-API formatted data. */ protected function _data($entity, $attributes = true) { $definition = $entity::definition(); $key = $entity::definition()->key(); $result = ['type' => $definition->source()]; if ($entity->exists()) { $result['id'] = $entity->id(); } if (!$attributes) { return $result; } $attrs = []; $exporter = $this->_exporter; $data = $exporter($entity); foreach ($data as $name => $value) { $attrs[$name] = $value; } unset($attrs[$key]); $result['attributes'] = $attrs; return $result; }
/** * Instantiates a new markup generator and passes it the correct variables. * @param string $type Type of markup generator to instantiate (this needs to be a key in {@link markup_generator_info}) * @param object $item New item entity (optional - pass if this is a markup generator to display an individual item). * @return the new markup generator */ function set_up_generator_of_type($type, $item = false) { if(!isset($this->markup_generators[$type])) $this->markup_generators[$type] = array(); $item_id = !empty($item) ? $item->id() : 0; if(!isset($this->markup_generators[$type][$item_id])) { if(isset($this->markup_generator_info[$type]['filename'])) { if(!reason_include_once( $this->markup_generator_info[$type]['filename'] )) { trigger_error('Markup generator file not found at '.$this->markup_generator_info[$type]['filename'].'. Empty markup generator substituted.'); reason_include_once('minisite_templates/modules/publication/empty_markup_generator.php'); } } else { trigger_error('No markup generator filename found for "'.$type.'". Empty markup generator substituted.'); reason_include_once('minisite_templates/modules/publication/empty_markup_generator.php'); } if(isset($this->markup_generator_info[$type]['classname'])) { if(class_exists($this->markup_generator_info[$type]['classname'])) $markup_generator = new $this->markup_generator_info[$type]['classname'](); else { trigger_error('Class '.$this->markup_generator_info[$type]['classname'].' not found. Empty markup generator substituted.'); $markup_generator = new EmptyMarkupGenerator(); } } else { trigger_error('No markup generator classname found for "'.$type.'". Empty markup generator substituted.'); $markup_generator = new EmptyMarkupGenerator(); } $markup_generator_settings = (!empty($this->markup_generator_info[$type]['settings'])) ? $this->markup_generator_info[$type]['settings'] : ''; if (!empty($markup_generator_settings)) $markup_generator->set_passed_variables($markup_generator_settings); $markup_generator->set_passed_variables($this->get_values_to_pass($markup_generator, $item)); //pray($this->get_values_to_pass($markup_generator, $item)); $this->markup_generators[$type][$item_id] = $markup_generator; } return $this->markup_generators[$type][$item_id]; }
/** * Get information about the placard image to use for a given media file * @param object $media_file * @param mixed $media_work entity object or null. If null, media work will be found * @return array('image'=>entity,'url'=>sized url,'width' =>width,'height'=>height) */ function reason_get_media_placard_image_info($media_file,$media_work = null) { if(empty($media_file)) { trigger_error('reason_get_media_placard_image_info(0 requires a media file as the first argument'); return null; } if($media_file->get_value('av_type') == 'Audio') return null; if(empty($media_work)) { $es = new entity_selector(); $es->add_type(id_of('av')); $es->add_left_relationship($media_file->id(),relationship_id_of('av_to_av_file')); $es->set_num(1); $works = $es->run_one(); if(!empty($works)) $media_work = current($works); else return null; } $es = new entity_selector(); $es->add_type(id_of('image')); $es->add_right_relationship($media_work->id(),relationship_id_of('av_to_primary_image')); $es->set_num(1); $images = $es->run_one(); if(!empty($images)) { $image = current($images); $rsi = new reasonSizedImage(); $rsi->set_id($image->id()); $width = 480; $height = 320; if($media_file->get_value('width') && $media_file->get_value('height')) { $width = $media_file->get_value('width'); $height = $media_file->get_value('height'); } $rsi->set_width($width); $rsi->set_height($height); $rsi->set_crop_style('fill'); $image_url = $rsi->get_url(); return array( 'image' => $image, 'url' => $image_url, 'width' => $rsi->get_image_width(), 'height' => $rsi->get_image_height() ); } return null; }
/** * Helper to recursively build table rows to hold existing components. * * @param object $node * A node object the components belong to. * @param int $cid * A cid of the component. * @param array $component * A component. * @param int $level * The nesting level of this component. * @param array $form * The form that is being modified, passed by reference. * @param array $add_form * The add form which will be inserted under any previously added/edited * component. * * @see self::buildForm() */ protected function buildComponentsTableRow($node, $cid, $component, $level, &$form, &$add_form) { $row_class = ['draggable']; if (!webform_component_feature($component['type'], 'group')) { $row_class[] = 'tabledrag-leaf'; } if ($component['type'] == 'pagebreak') { $row_class[] = 'tabledrag-root'; $row_class[] = 'webform-pagebreak'; } $form['components'][$cid]['#attributes']['class'] = $row_class; $form['components'][$cid]['#attributes']['data-cid'] = $cid; $indentation = ''; if ($level >= 1) { $indentation = ['#theme' => 'indentation', '#size' => $level]; $indentation = drupal_render($indentation); } $form['components'][$cid]['name'] = ['#prefix' => $indentation, '#markup' => Xss::filter($component['name']), '#attributes' => ['class' => ['webform-component-name', $component['type'] == 'pagebreak' ? 'webform-pagebreak' : '']]]; $form['components'][$cid]['type'] = ['#markup' => $form['#component_options'][$component['type']], '#attributes' => ['class' => ['webform-component-type']]]; // Create a presentable value. if (Unicode::strlen($component['value']) > 30) { $component['value'] = Unicode::substr($component['value'], 0, 30); $component['value'] .= '...'; } $component['value'] = SafeMarkup::checkPlain($component['value']); $form['components'][$cid]['value'] = ['#markup' => $component['value'] == '' ? '-' : $component['value'], '#attributes' => ['class' => ['webform-component-value']]]; $form['components'][$cid]['required'] = ['#type' => 'checkbox', '#title' => $this->t('Required'), '#title_display' => 'invisible', '#default_value' => $component['required'], '#access' => webform_component_feature($component['type'], 'required'), '#attributes' => ['class' => ['webform-component-required']]]; $form['components'][$cid]['weight'] = ['#type' => 'textfield', '#title' => $this->t('Weight for @title', ['@title' => $component['name']]), '#title_display' => 'invisible', '#size' => 4, '#delta' => count($node->webform['components']) > 10 ? count($node->webform['components']) : 10, '#default_value' => $form['#component_weights'][$cid], '#attributes' => ['class' => ['webform-weight']]]; $form['components'][$cid]['parent']['cid'] = ['#parents' => ['components', $cid, 'cid'], '#type' => 'hidden', '#default_value' => $component['cid'], '#attributes' => ['class' => ['webform-cid']]]; $form['components'][$cid]['parent']['pid'] = ['#parents' => ['components', $cid, 'pid'], '#type' => 'hidden', '#default_value' => $component['pid'], '#attributes' => ['class' => ['webform-pid']]]; $form['components'][$cid]['operations'] = ['#type' => 'operations', '#links' => []]; // @todo Fix these links once the routes exist. $form['components'][$cid]['operations']['#links']['edit'] = ['title' => $this->t('Edit'), 'url' => Url::fromRoute('webform.component_edit_form', ['node' => $node->id(), 'component' => $cid])]; $form['components'][$cid]['operations']['#links']['clone'] = ['title' => $this->t('Clone'), 'url' => Url::fromRoute('entity.node.webform', ['node' => $node->id()])]; $form['components'][$cid]['operations']['#links']['delete'] = ['title' => $this->t('Delete'), 'url' => Url::fromRoute('webform.component_delete_form', ['node' => $node->id(), 'component' => $cid])]; if (isset($component['children']) && is_array($component['children'])) { foreach ($component['children'] as $cid => $component) { $this->buildComponentsTableRow($node, $cid, $component, $level + 1, $form, $add_form); } } // Add the add form if this was the last edited component. if (isset($_GET['cid']) && $component['cid'] == $_GET['cid'] && $add_form) { $add_form['name']['#prefix'] = $indentation; $form['components']['add'] = $add_form; $add_form = FALSE; } }
/** * Tests editing a page using a disallowed text format. * * Verifies that regular users and administrators are able to edit a page, but * not allowed to change the fields which use an inaccessible text format. * Also verifies that fields which use a text format that does not exist can * be edited by administrators only, but that the administrator is forced to * choose a new format before saving the page. */ function testFormatWidgetPermissions() { $body_value_key = 'body[0][value]'; $body_format_key = 'body[0][format]'; // Create node to edit. $this->drupalLogin($this->adminUser); $edit = array(); $edit['title[0][value]'] = $this->randomMachineName(8); $edit[$body_value_key] = $this->randomMachineName(16); $edit[$body_format_key] = $this->disallowedFormat->id(); $this->drupalPostForm('node/add/page', $edit, t('Save')); $node = $this->drupalGetNodeByTitle($edit['title[0][value]']); // Try to edit with a less privileged user. $this->drupalLogin($this->webUser); $this->drupalGet('node/' . $node->id()); $this->clickLink(t('Edit')); // Verify that body field is read-only and contains replacement value. $this->assertFieldByXPath("//textarea[@name='{$body_value_key}' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Text format access denied message found.'); // Verify that title can be changed, but preview displays original body. $new_edit = array(); $new_edit['title[0][value]'] = $this->randomMachineName(8); $this->drupalPostForm(NULL, $new_edit, t('Preview')); $this->assertText($edit[$body_value_key], 'Old body found in preview.'); // Save and verify that only the title was changed. $this->drupalPostForm('node/' . $node->id() . '/edit', $new_edit, t('Save')); $this->assertNoText($edit['title[0][value]'], 'Old title not found.'); $this->assertText($new_edit['title[0][value]'], 'New title found.'); $this->assertText($edit[$body_value_key], 'Old body found.'); // Check that even an administrator with "administer filters" permission // cannot edit the body field if they do not have specific permission to // use its stored format. (This must be disallowed so that the // administrator is never forced to switch the text format to something // else.) $this->drupalLogin($this->filterAdminUser); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertFieldByXPath("//textarea[@name='{$body_value_key}' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Text format access denied message found.'); // Disable the text format used above. $this->disallowedFormat->disable()->save(); $this->resetFilterCaches(); // Log back in as the less privileged user and verify that the body field // is still disabled, since the less privileged user should not be able to // edit content that does not have an assigned format. $this->drupalLogin($this->webUser); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertFieldByXPath("//textarea[@name='{$body_value_key}' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Text format access denied message found.'); // Log back in as the filter administrator and verify that the body field // can be edited. $this->drupalLogin($this->filterAdminUser); $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertNoFieldByXPath("//textarea[@name='{$body_value_key}' and @disabled='disabled']", NULL, 'Text format access denied message not found.'); $this->assertFieldByXPath("//select[@name='{$body_format_key}']", NULL, 'Text format selector found.'); // Verify that trying to save the node without selecting a new text format // produces an error message, and does not result in the node being saved. $old_title = $new_edit['title[0][value]']; $new_title = $this->randomMachineName(8); $edit = array(); $edit['title[0][value]'] = $new_title; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->assertText(t('@name field is required.', array('@name' => t('Text format'))), 'Error message is displayed.'); $this->drupalGet('node/' . $node->id()); $this->assertText($old_title, 'Old title found.'); $this->assertNoText($new_title, 'New title not found.'); // Now select a new text format and make sure the node can be saved. $edit[$body_format_key] = filter_fallback_format(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->assertUrl('node/' . $node->id()); $this->assertText($new_title, 'New title found.'); $this->assertNoText($old_title, 'Old title not found.'); // Switch the text format to a new one, then disable that format and all // other formats on the site (leaving only the fallback format). $this->drupalLogin($this->adminUser); $edit = array($body_format_key => $this->allowedFormat->id()); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->assertUrl('node/' . $node->id()); foreach (filter_formats() as $format) { if (!$format->isFallbackFormat()) { $format->disable()->save(); } } // Since there is now only one available text format, the widget for // selecting a text format would normally not display when the content is // edited. However, we need to verify that the filter administrator still // is forced to make a conscious choice to reassign the text to a different // format. $this->drupalLogin($this->filterAdminUser); $old_title = $new_title; $new_title = $this->randomMachineName(8); $edit = array(); $edit['title[0][value]'] = $new_title; $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->assertText(t('@name field is required.', array('@name' => t('Text format'))), 'Error message is displayed.'); $this->drupalGet('node/' . $node->id()); $this->assertText($old_title, 'Old title found.'); $this->assertNoText($new_title, 'New title not found.'); $edit[$body_format_key] = filter_fallback_format(); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); $this->assertUrl('node/' . $node->id()); $this->assertText($new_title, 'New title found.'); $this->assertNoText($old_title, 'Old title not found.'); }
/** * updates one or more fields per entity * * {{{$entity->updateFields(array('fieldname' => $value));}}} * * @see lithium\data\Model::update() * @param object $entity current instance * @param array $values an array of values to be changed * @param array $options Possible options are: * - `updated`: set to false to supress automatic updating of the `updated` field * @return true on success, false otherwise * @filter */ public function updateFields($entity, array $values, array $options = array()) { $defaults = array('updated' => true); $options += $defaults; $params = compact('entity', 'values', 'options'); return $this->_filter(get_called_class() . '::updateFields', $params, function ($self, $params) { extract($params); $key = $self::key(); $conditions = array($key => $entity->id()); if ($options['updated']) { $values['updated'] = time(); } $success = $self::update($values, $conditions); if (!$success) { $model = $entity->model(); $msg = sprintf('Update of %s [%s] returned false', $model, $entity->id()); $data = compact('values', 'conditions', 'model'); return false; } $entity->set($values); return true; }); }
/** * Verify the blog links are displayed to the logged in user. * * @param object $user * The logged in user. */ private function verifyBlogLinks($user) { // Confirm blog entries link exists on the user page. $this->drupalGet('user/' . $user->id()); $this->assertResponse(200); $this->assertText(t('View recent blog entries'), t('View recent blog entries link was displayed')); // Confirm the recent blog entries link goes to the user's blog page. $this->clickLink('View recent blog entries'); $this->assertTitle(t("@name's blog | Drupal", array('@name' => $user->getUsername())), t('View recent blog entries link target was correct')); // Confirm a blog page was displayed. $this->drupalGet('blog'); $this->assertResponse(200); $this->assertTitle('Blogs | Drupal', t('Blog page was displayed')); $this->assertText(t('Home'), t('Breadcrumbs were displayed')); $this->assertLink(t('Create new blog entry')); // Confirm a blog page was displayed per user. $this->drupalGet('blog/' . $user->id()); $this->assertTitle(t("@name's blog | Drupal", array('@name' => $user->getUsername())), t('User blog node was displayed')); // Confirm a blog feed was displayed. $this->drupalGet('blog/feed'); $this->assertTitle(t('Drupal blogs'), t('Blog feed was displayed')); // Confirm a blog feed was displayed per user. $this->drupalGet('blog/' . $user->id() . '/feed'); $this->assertTitle(t("@name's blog", array('@name' => $user->getUsername())), t('User blog feed was displayed')); }
/** * Returns the allowed values for the current state. * * @param object $entity * The entity at hand. May be NULL (E.g., on a Field settings page). * @param string $field_name * @param \Drupal\Core\Session\AccountInterface|NULL $account * @param bool $force * * @return array * An array of sid=>label pairs. * If $this->id() is set, returns the allowed transitions from this state. * If $this->id() is 0 or FALSE, then labels of ALL states of the State's * Workflow are returned. */ public function getOptions($entity, $field_name, AccountInterface $account = NULL, $force = FALSE) { $options = array(); // Define an Entity-specific cache per page load. static $cache = array(); $entity_id = $entity ? $entity->id() : ''; $entity_type = $entity ? $entity->getEntityTypeId() : ''; $current_sid = $this->id(); // Get options from page cache, using a non-empty index (just to be sure). $entity_index = !$entity ? 'x' : $entity_id; if (isset($cache[$entity_type][$entity_index][$force][$current_sid])) { $options = $cache[$entity_type][$entity_index][$force][$current_sid]; return $options; } $workflow = $this->getWorkflow(); if (!$workflow) { // No workflow, no options ;-) $options = array(); } elseif (!$current_sid) { // If no State ID is given, we return all states. // We cannot use getTransitions, since there are no ConfigTransitions // from State with ID 0, and we do not want to repeat States. foreach ($workflow->getStates() as $state) { $options[$state->id()] = html_entity_decode(t('@label', array('@label' => $state->label()))); } } else { $transitions = $this->getTransitions($entity, $field_name, $account, $force); foreach ($transitions as $transition) { // Get the label of the transition, and if empty of the target state. // Beware: the target state may not exist, since it can be invented // by custom code in the above drupal_alter() hook. if (!($label = $transition->label())) { $to_state = $transition->getToState(); $label = $to_state ? $to_state->label() : ''; } $to_sid = $transition->to_sid; $options[$to_sid] = html_entity_decode(t('@label', array('@label' => $label))); } // Save to entity-specific cache. $cache[$entity_type][$entity_index][$force][$current_sid] = $options; } return $options; }
/** * Tests that toolbar cache is cleared when string translations are made. */ function testLocaleTranslationSubtreesHashCacheClear() { $toolbarCache = $this->container->get('cache.toolbar'); $admin_user = $this->admin_user; $admin_user_id = $this->admin_user->id(); // User to translate and delete string. $translate_user = $this->drupalCreateUser(array('translate interface', 'access administration pages')); // Create a new language with the langcode 'xx'. $langcode = 'xx'; // The English name for the language. This will be translated. $name = $this->randomMachineName(16); // This is the language indicator on the translation search screen for // untranslated strings. $language_indicator = "<em class=\"locale-untranslated\">{$langcode}</em> "; // This will be the translation of $name. $translation = $this->randomMachineName(16); $translation_to_en = $this->randomMachineName(16); // Add custom language. $this->drupalLogin($admin_user); $edit = array('predefined_langcode' => 'custom', 'langcode' => $langcode, 'name' => $name, 'direction' => LanguageInterface::DIRECTION_LTR); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); t($name, array(), array('langcode' => $langcode)); // Reset locale cache. $this->container->get('string_translation')->reset(); $this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.'); $this->assertText(t($name), 'Test language added.'); // Have the admin_user request a page in the new language. $this->drupalGet($langcode . '/test-page'); $this->assertResponse(200); // Assert that a cache tag in the toolbar cache under the key "user" exists // for admin_user against the language "xx". $cache = $toolbarCache->get('toolbar_' . $admin_user_id . ':' . $langcode); $this->assertEqual($cache->tags[0], 'user:'******'A cache tag in the toolbar cache under the key "user" exists for admin_user against the language "xx".'); // Get a baseline hash for the admin menu subtrees before translating one // of the menu link items. $original_subtree_hash = $this->getSubtreesHash(); $this->assertTrue($original_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); $this->drupalLogout(); // Translate the string 'Menus' in the xx language. This string appears in // a link in the admin menu subtrees. Changing the string should create a // new menu hash if the toolbar subtrees cache is properly cleared. $this->drupalLogin($translate_user); $search = array('string' => 'Menus', 'langcode' => $langcode, 'translation' => 'untranslated'); $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); $this->assertNoText(t('No strings available')); $this->assertText($name, 'Search found the string as untranslated.'); // Assume this is the only result. // Translate the string to a random string. $textarea = current($this->xpath('//textarea')); $lid = (string) $textarea[0]['name']; $edit = array($lid => $translation); $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); $this->assertText(t('The strings have been saved.'), 'The strings have been saved.'); $this->assertEqual($this->getUrl(), url('admin/config/regional/translate', array('absolute' => TRUE)), 'Correct page redirection.'); $this->drupalLogout(); // Log in the admin_user. Check the admin menu subtrees hash now that one // of the link items in the Structure tree (Menus) has had its text // translated. $this->drupalLogin($admin_user); // Have the admin_user request a page in the new language. $this->drupalGet($langcode . '/test-page'); $this->assertResponse(200); $new_subtree_hash = $this->getSubtreesHash(); // Assert that the old admin menu subtrees hash and the new admin menu // subtrees hash are different. $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); $this->assertNotEqual($original_subtree_hash, $new_subtree_hash, 'The user-specific subtree menu hash has been updated.'); }
/** * Is the user a valid administrator for registration slots for a given event? * @param object $event event entity * @return boolean */ function user_is_slot_admin($event) { return $this->user_can_inline_edit_event($event->id()); }
/** * Split a repeating event into separate entities * * If event is not repeating, nothing will happen and the returned array will contain just the * existing event's ID. * * @param object $event entity * @param integer $user_id * @return array updated/created IDs * * @todo determine a way to integrate with Carleton event calendar */ function reason_split_event($event, $user_id) { $user_id = (int) $user_id; if (empty($user_id)) { trigger_error('User ID required to split an event'); return array(); } $ret = array($event->id()); $dates = explode(', ', $event->get_value('dates')); sort($dates); if (count($dates) > 1) { $i = 1; foreach ($dates as $date) { $overrides = array('datetime' => $date . ' ' . substr($event->get_value('datetime'), 11), 'dates' => $date, 'recurrence' => 'none', 'last_occurence' => $date, 'frequency' => '', 'week_of_month' => '', 'month_day_of_week' => '', 'monthly_repeat' => ''); if ($i < 2) { reason_update_entity($event->id(), $user_id, $overrides); } else { $overrides['unique_name'] = ''; $overrides['last_modified'] = date('Y-m-d h:i:s'); $overrides['last_edited_by'] = $user_id; $overrides['creation_date'] = date('Y-m-d h:i:s'); $overrides['created_by'] = $user_id; $ret[] = duplicate_entity($event->id(), true, false, $overrides); } $i++; } } return $ret; }
/** * Get the archived entities that represent the state of the item at * the beginning of a given start date and at the end of a given end date * * @param object $item reason entity * @param string $start_date * @param string $end_date * @return array form: array('start'=>entity,'end'=>entity) */ function _get_archived_entities($item, $start_date, $end_date) { //echo $start_date.'.'.$end_date; $ret = array('start' => NULL, 'end' => NULL); $es = new entity_selector(); $es->add_type($item->get_value('type')); $es->add_right_relationship($item->id(), reason_get_archive_relationship_id($item->get_value('type'))); $es->add_relation('entity.last_modified < "' . addslashes($start_date) . '"'); $es->set_order('entity.last_modified DESC'); $es->set_num(1); $starts = $es->run_one(false, 'Archived'); if (!empty($starts)) { $ret['start'] = current($starts); } $es = new entity_selector(); $es->add_type($item->get_value('type')); $es->add_right_relationship($item->id(), reason_get_archive_relationship_id($item->get_value('type'))); $es->add_relation('entity.last_modified <= "' . addslashes($end_date) . ' 23:59:59"'); $es->set_order('entity.last_modified DESC'); $es->set_num(1); $ends = $es->run_one(false, 'Archived'); if (!empty($ends)) { $ret['end'] = current($ends); } return $ret; }