/** * Tests the configurable text editor manager. */ public function testEditorEntityHooks() { $image = entity_create('file'); $image->setFileUri('core/misc/druplicon.png'); $image->setFilename(drupal_basename($image->getFileUri())); $image->save(); $file_usage = $this->container->get('file.usage'); $this->assertIdentical(array(), $file_usage->listUsage($image), 'The image has zero usages.'); $body_value = '<p>Hello, world!</p><img src="awesome-llama.jpg" data-entity-type="file" data-entity-uuid="' . $image->uuid() . '" />'; // Test handling of an invalid data-entity-uuid attribute. $body_value .= '<img src="awesome-llama.jpg" data-entity-type="file" data-entity-uuid="invalid-entity-uuid-value" />'; // Test handling of an invalid data-entity-type attribute. $body_value .= '<img src="awesome-llama.jpg" data-entity-type="invalid-entity-type-value" data-entity-uuid="' . $image->uuid() . '" />'; // Test handling of a non-existing UUID. $body_value .= '<img src="awesome-llama.jpg" data-entity-type="file" data-entity-uuid="30aac704-ba2c-40fc-b609-9ed121aa90f4" />'; // Test editor_entity_insert(): increment. $this->createUser(); $node = entity_create('node', array('type' => 'page', 'title' => 'test', 'body' => array('value' => $body_value, 'format' => 'filtered_html'), 'uid' => 1)); $node->save(); $this->assertIdentical(array('editor' => array('node' => array(1 => '1'))), $file_usage->listUsage($image), 'The image has 1 usage.'); // Test editor_entity_update(): increment, twice, by creating new revisions. $node->setNewRevision(TRUE); $node->save(); $second_revision_id = $node->getRevisionId(); $node->setNewRevision(TRUE); $node->save(); $this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image), 'The image has 3 usages.'); // Test hook_entity_update(): decrement, by modifying the last revision: // remove the data-entity-type attribute from the body field. $body = $node->get('body')->first()->get('value'); $original_value = $body->getValue(); $new_value = str_replace('data-entity-type', 'data-entity-type-modified', $original_value); $body->setValue($new_value); $node->save(); $this->assertIdentical(array('editor' => array('node' => array(1 => '2'))), $file_usage->listUsage($image), 'The image has 2 usages.'); // Test editor_entity_update(): increment again by creating a new revision: // read the data- attributes to the body field. $node->setNewRevision(TRUE); $node->get('body')->first()->get('value')->setValue($original_value); $node->save(); $this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image), 'The image has 3 usages.'); // Test hook_entity_update(): decrement, by modifying the last revision: // remove the data-entity-uuid attribute from the body field. $body = $node->get('body')->first()->get('value'); $new_value = str_replace('data-entity-uuid', 'data-entity-uuid-modified', $original_value); $body->setValue($new_value); $node->save(); $this->assertIdentical(array('editor' => array('node' => array(1 => '2'))), $file_usage->listUsage($image), 'The image has 2 usages.'); // Test hook_entity_update(): increment, by modifying the last revision: // read the data- attributes to the body field. $node->get('body')->first()->get('value')->setValue($original_value); $node->save(); $this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image), 'The image has 3 usages.'); // Test editor_entity_revision_delete(): decrement, by deleting a revision. entity_revision_delete('node', $second_revision_id); $this->assertIdentical(array('editor' => array('node' => array(1 => '2'))), $file_usage->listUsage($image), 'The image has 2 usages.'); // Test editor_entity_delete(). $node->delete(); $this->assertIdentical(array(), $file_usage->listUsage($image), 'The image has zero usages again.'); }
/** * {@inheritdoc} */ public function denormalize($data, $class, $format = NULL, array $context = array()) { $file_data = (string) $this->httpClient->get($data['uri'][0]['value'])->getBody(); $path = 'temporary://' . drupal_basename($data['uri'][0]['value']); $data['uri'] = file_unmanaged_save_data($file_data, $path); return $this->entityManager->getStorage('file')->create($data); }
/** * {@inheritdoc} */ public function guess($path) { if ($this->mapping === NULL) { $mapping = $this->defaultMapping; // Allow modules to alter the default mapping. $this->moduleHandler->alter('file_mimetype_mapping', $mapping); $this->mapping = $mapping; } $extension = ''; $file_parts = explode('.', drupal_basename($path)); // Remove the first part: a full filename should not match an extension. array_shift($file_parts); // Iterate over the file parts, trying to find a match. // For my.awesome.image.jpeg, we try: // - jpeg // - image.jpeg, and // - awesome.image.jpeg while ($additional_part = array_pop($file_parts)) { $extension = strtolower($additional_part . ($extension ? '.' . $extension : '')); if (isset($this->mapping['extensions'][$extension])) { return $this->mapping['mimetypes'][$this->mapping['extensions'][$extension]]; } } return 'application/octet-stream'; }
public function generateValues($object, $instance, $plugin_definition, $form_display_options) { static $file; $settings = $instance->getFieldSettings(); if (empty($file)) { if ($path = $this->generateTextFile()) { $source = new stdClass(); $source->uri = $path; $source->uid = 1; // TODO: randomize? use case specific. $source->filemime = 'text/plain'; $source->filename = drupal_basename($path); $destination_dir = $settings['uri_scheme'] . '://' . $settings['file_directory']; file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY); $destination = $destination_dir . '/' . basename($path); $file = file_move($source, $destination, FILE_CREATE_DIRECTORY); } else { return FALSE; } } if (!$file) { // In case a previous file operation failed or no file is set, return FALSE return FALSE; } else { $object_field['target_id'] = $file->id(); $object_field['display'] = $settings['display_default']; $object_field['description'] = DevelGenerateBase::createGreeking(10); return $object_field; } }
public function generateImage($object, $field, $instance, $bundle) { $object_field = array(); static $available_images = array(); if (empty($available_images)) { $available_images = $this->getImages(); } if (empty($available_images)) { $args = func_get_args(); return call_user_func_array('_image_devel_generate', $args); } $extension = array_rand(array('jpg' => 'jpg', 'png' => 'png')); $min_resolution = empty($instance['settings']['min_resolution']) ? '100x100' : $instance['settings']['min_resolution']; $max_resolution = empty($instance['settings']['max_resolution']) ? '600x600' : $instance['settings']['max_resolution']; if (FALSE === ($tmp_file = drupal_tempnam('temporary://', 'imagefield_'))) { return FALSE; } $destination = $tmp_file . '.' . $extension; file_unmanaged_move($tmp_file, $destination, FILE_EXISTS_REPLACE); $rand_file = array_rand($available_images); if (!empty($instance['settings']['file_directory'])) { $instance['settings']['file_directory'] = $instance['settings']['file_directory'] . '/'; } $destination_dir = $field['settings']['uri_scheme'] . '://' . $instance['settings']['file_directory']; file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY); if ($this->settings['devel_image_no_alter']) { $file = $available_images[$rand_file]; $file = file_copy($file, $destination_dir); } else { $image = image_load($rand_file); $min = explode('x', $min_resolution); $max = explode('x', $max_resolution); $max[0] = $max[0] < $min[0] ? $min[0] : $max[0]; $max[1] = $max[1] < $min[1] ? $min[1] : $max[1]; $width = rand((int) $min[0], (int) $max[0]); $height = rand((int) $min[1], (int) $max[1]); if (!image_scale_and_crop($image, $width, $height)) { return FALSE; } // Use destination image type. $image->info['extension'] = $extension; if (!image_save($image, $destination)) { return FALSE; } $source = new stdClass(); $source->uri = $destination; $source->uid = 1; // TODO: randomize? Use case specific. $source->filemime = $image->info['mime_type']; $source->filename = drupal_basename($image->source); $destination = $destination_dir . basename($destination); $file = file_move($source, $destination, FILE_CREATE_DIRECTORY); } $object_field['fid'] = $file->fid; $object_field['alt'] = devel_create_greeking(4); $object_field['title'] = devel_create_greeking(4); return $object_field; }
/** * Alter the favicon file URI. * * @param string $uri * A file URI. * * @see DrupalFavicon::getFileFromUri() */ function hook_favicon_file_uri_alter(&$uri) { $basename = drupal_basename($uri); // Allow for individual user variations of the favicon file. $uri_with_uid = str_replace($basename, $basename . '-' . $GLOBALS['user']->uid, $uri); if (is_file($uri_with_uid)) { $uri = $uri_with_uid; } }
/** * Asserts that a collected error matches what we are expecting. */ function assertError($error, $group, $function, $file, $message = NULL) { $this->assertEqual($error['group'], $group, format_string("Group was %group", array('%group' => $group))); $this->assertEqual($error['caller']['function'], $function, format_string("Function was %function", array('%function' => $function))); $this->assertEqual(drupal_basename($error['caller']['file']), $file, format_string("File was %file", array('%file' => $file))); if (isset($message)) { $this->assertEqual($error['message'], $message, format_string("Message was %message", array('%message' => $message))); } }
protected function setUp() { parent::setUp(); $this->image = entity_create('file'); $this->image->setFileUri('core/misc/druplicon.png'); $this->image->setFilename(drupal_basename($this->image->getFileUri())); $this->nonImage = entity_create('file'); $this->nonImage->setFileUri('core/assets/vendor/jquery/jquery.min.js'); $this->nonImage->setFilename(drupal_basename($this->nonImage->getFileUri())); }
/** * Validates a single file path. * * @param string $filepath * The file path. * * @return bool * Returns true if the file is valid, and false if not. */ protected function validateFilePath($filepath) { $filename = drupal_basename($filepath); // Don't allow hidden files. if (substr($filename, 0, 1) === '.') { return FALSE; } // Validate file extension. $extension = substr($filename, strrpos($filename, '.') + 1); return in_array($extension, $this->configuration['allowed_extensions'], TRUE); }
/** * Test the file_unmanaged_save_data() function. */ function testFileSaveData() { $contents = $this->randomMachineName(8); $this->settingsSet('file_chmod_file', 0777); // No filename. $filepath = file_unmanaged_save_data($contents); $this->assertTrue($filepath, 'Unnamed file saved correctly.'); $this->assertEqual(file_uri_scheme($filepath), file_default_scheme(), "File was placed in Drupal's files directory."); $this->assertEqual($contents, file_get_contents($filepath), 'Contents of the file are correct.'); // Provide a filename. $filepath = file_unmanaged_save_data($contents, 'public://asdf.txt', FILE_EXISTS_REPLACE); $this->assertTrue($filepath, 'Unnamed file saved correctly.'); $this->assertEqual('asdf.txt', drupal_basename($filepath), 'File was named correctly.'); $this->assertEqual($contents, file_get_contents($filepath), 'Contents of the file are correct.'); $this->assertFilePermissions($filepath, 0777); }
/** * Test the file_save_data() function when a filename is provided. */ function testWithFilename() { $contents = $this->randomName(8); // Using filename with non-latin characters. $filename = 'Текстовый файл.txt'; $result = file_save_data($contents, 'public://' . $filename); $this->assertTrue($result, 'Unnamed file saved correctly.'); $this->assertEqual('public', file_uri_scheme($result->getFileUri()), "File was placed in Drupal's files directory."); $this->assertEqual($filename, drupal_basename($result->getFileUri()), 'File was named correctly.'); $this->assertEqual($contents, file_get_contents($result->getFileUri()), 'Contents of the file are correct.'); $this->assertEqual($result->getMimeType(), 'text/plain', 'A MIME type was set.'); $this->assertTrue($result->isPermanent(), "The file's status was set to permanent."); // Check that the correct hooks were called. $this->assertFileHooksCalled(array('insert')); // Verify that what was returned is what's in the database. $this->assertFileUnchanged($result, file_load($result->id(), TRUE)); }
/** * {@inheritdoc} */ public function denormalize($data, $class, $format = NULL, array $context = array()) { // File content can be passed base64 encoded in a special "data" property. // That property is not a field, so we remove it before denormalizing the // rest of the file entity. $file_data = $data['data'][0]['value']; unset($data['data']); $entity = parent::denormalize($data, $class, $format, $context); // Decode and save to file if it's a new file. if (!isset($context['request_method']) || $context['request_method'] != 'patch') { $file_contents = base64_decode($file_data); $dirname = $this->fileSystem->dirname($entity->getFileUri()); file_prepare_directory($dirname, FILE_CREATE_DIRECTORY); if ($uri = file_unmanaged_save_data($file_contents, file_build_uri(drupal_basename($entity->getFilename())))) { $entity->setFileUri($uri); } else { throw new RuntimeException('failed to write ' . $entity->getFilename()); } } return $entity; }
function generateValues($object, $instance, $plugin_definition, $form_display_options) { $object_field = array(); static $images = array(); $settings = $instance->getSettings(); $min_resolution = empty($settings['min_resolution']) ? '100x100' : $settings['min_resolution']; $max_resolution = empty($settings['max_resolution']) ? '600x600' : $settings['max_resolution']; $extensions = array_intersect(explode(' ', $settings['file_extensions']), array('png', 'gif', 'jpg', 'jpeg')); $extension = array_rand(array_combine($extensions, $extensions)); // Generate a max of 5 different images. if (!isset($images[$extension][$min_resolution][$max_resolution]) || count($images[$extension][$min_resolution][$max_resolution]) <= DEVEL_GENERATE_IMAGE_MAX) { if ($path = $this->generateImage($extension, $min_resolution, $max_resolution)) { $account = user_load(1); $image = entity_create('file', array()); $image->setFileUri($path); $image->setOwner($account); $image->setMimeType('image/' . pathinfo($path, PATHINFO_EXTENSION)); $image->setFileName(drupal_basename($path)); $destination_dir = $settings['uri_scheme'] . '://' . $settings['file_directory']; file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY); $destination = $destination_dir . '/' . basename($path); $file = file_move($image, $destination, FILE_CREATE_DIRECTORY); $images[$extension][$min_resolution][$max_resolution][$file->id()] = $file; } else { return FALSE; } } else { // Select one of the images we've already generated for this field. $image_index = array_rand($images[$extension][$min_resolution][$max_resolution]); $file = $images[$extension][$min_resolution][$max_resolution][$image_index]; } $object_field['target_id'] = $file->id(); $object_field['alt'] = DevelGenerateBase::createGreeking(4); $object_field['title'] = DevelGenerateBase::createGreeking(4); return $object_field; }
/** * Tests the configurable text editor manager. */ public function testEditorEntityHooks() { $image_paths = array(0 => 'core/misc/druplicon.png', 1 => 'core/misc/tree.png', 2 => 'core/misc/help.png'); $image_entities = array(); foreach ($image_paths as $key => $image_path) { $image = File::create(); $image->setFileUri($image_path); $image->setFilename(drupal_basename($image->getFileUri())); $image->save(); $file_usage = $this->container->get('file.usage'); $this->assertIdentical(array(), $file_usage->listUsage($image), 'The image ' . $image_paths[$key] . ' has zero usages.'); $image_entities[] = $image; } $body = array(); foreach ($image_entities as $key => $image_entity) { // Don't be rude, say hello. $body_value = '<p>Hello, world!</p>'; // Test handling of a valid image entry. $body_value .= '<img src="awesome-llama-' . $key . '.jpg" data-entity-type="file" data-entity-uuid="' . $image_entity->uuid() . '" />'; // Test handling of an invalid data-entity-uuid attribute. $body_value .= '<img src="awesome-llama-' . $key . '.jpg" data-entity-type="file" data-entity-uuid="invalid-entity-uuid-value" />'; // Test handling of an invalid data-entity-type attribute. $body_value .= '<img src="awesome-llama-' . $key . '.jpg" data-entity-type="invalid-entity-type-value" data-entity-uuid="' . $image_entity->uuid() . '" />'; // Test handling of a non-existing UUID. $body_value .= '<img src="awesome-llama-' . $key . '.jpg" data-entity-type="file" data-entity-uuid="30aac704-ba2c-40fc-b609-9ed121aa90f4" />'; $body[] = array('value' => $body_value, 'format' => 'filtered_html'); } // Test editor_entity_insert(): increment. $this->createUser(); $node = $node = Node::create(['type' => 'page', 'title' => 'test', 'body' => $body, 'uid' => 1]); $node->save(); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array('editor' => array('node' => array(1 => '1'))), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has 1 usage.'); } // Test editor_entity_update(): increment, twice, by creating new revisions. $node->setNewRevision(TRUE); $node->save(); $second_revision_id = $node->getRevisionId(); $node->setNewRevision(TRUE); $node->save(); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has 3 usages.'); } // Test hook_entity_update(): decrement, by modifying the last revision: // remove the data-entity-type attribute from the body field. $original_values = array(); for ($i = 0; $i < count($image_entities); $i++) { $original_value = $node->body[$i]->value; $new_value = str_replace('data-entity-type', 'data-entity-type-modified', $original_value); $node->body[$i]->value = $new_value; $original_values[$i] = $original_value; } $node->save(); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array('editor' => array('node' => array(1 => '2'))), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has 2 usages.'); } // Test editor_entity_update(): increment again by creating a new revision: // read the data- attributes to the body field. $node->setNewRevision(TRUE); foreach ($original_values as $key => $original_value) { $node->body[$key]->value = $original_value; } $node->save(); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has 3 usages.'); } // Test hook_entity_update(): decrement, by modifying the last revision: // remove the data-entity-uuid attribute from the body field. foreach ($original_values as $key => $original_value) { $original_value = $node->body[$key]->value; $new_value = str_replace('data-entity-type', 'data-entity-type-modified', $original_value); $node->body[$key]->value = $new_value; } $node->save(); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array('editor' => array('node' => array(1 => '2'))), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has 2 usages.'); } // Test hook_entity_update(): increment, by modifying the last revision: // read the data- attributes to the body field. foreach ($original_values as $key => $original_value) { $node->body[$key]->value = $original_value; } $node->save(); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array('editor' => array('node' => array(1 => '3'))), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has 3 usages.'); } // Test editor_entity_revision_delete(): decrement, by deleting a revision. entity_revision_delete('node', $second_revision_id); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array('editor' => array('node' => array(1 => '2'))), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has 2 usages.'); } // Test editor_entity_delete(). $node->delete(); foreach ($image_entities as $key => $image_entity) { $this->assertIdentical(array(), $file_usage->listUsage($image_entity), 'The image ' . $image_paths[$key] . ' has zero usages again.'); } }
/** * Test the file_save_upload() function. */ function testNormal() { $max_fid_after = db_query('SELECT MAX(fid) AS fid FROM {file_managed}')->fetchField(); $this->assertTrue($max_fid_after > $this->maxFidBefore, 'A new file was created.'); $file1 = File::load($max_fid_after); $this->assertTrue($file1, 'Loaded the file.'); // MIME type of the uploaded image may be either image/jpeg or image/png. $this->assertEqual(substr($file1->getMimeType(), 0, 5), 'image', 'A MIME type was set.'); // Reset the hook counters to get rid of the 'load' we just called. file_test_reset(); // Upload a second file. $image2 = current($this->drupalGetTestFiles('image')); $edit = array('files[file_test_upload]' => drupal_realpath($image2->uri)); $this->drupalPostForm('file-test/upload', $edit, t('Submit')); $this->assertResponse(200, 'Received a 200 response for posted test file.'); $this->assertRaw(t('You WIN!')); $max_fid_after = db_query('SELECT MAX(fid) AS fid FROM {file_managed}')->fetchField(); // Check that the correct hooks were called. $this->assertFileHooksCalled(array('validate', 'insert')); $file2 = File::load($max_fid_after); $this->assertTrue($file2, 'Loaded the file'); // MIME type of the uploaded image may be either image/jpeg or image/png. $this->assertEqual(substr($file2->getMimeType(), 0, 5), 'image', 'A MIME type was set.'); // Load both files using File::loadMultiple(). $files = File::loadMultiple(array($file1->id(), $file2->id())); $this->assertTrue(isset($files[$file1->id()]), 'File was loaded successfully'); $this->assertTrue(isset($files[$file2->id()]), 'File was loaded successfully'); // Upload a third file to a subdirectory. $image3 = current($this->drupalGetTestFiles('image')); $image3_realpath = drupal_realpath($image3->uri); $dir = $this->randomMachineName(); $edit = array('files[file_test_upload]' => $image3_realpath, 'file_subdir' => $dir); $this->drupalPostForm('file-test/upload', $edit, t('Submit')); $this->assertResponse(200, 'Received a 200 response for posted test file.'); $this->assertRaw(t('You WIN!')); $this->assertTrue(is_file('temporary://' . $dir . '/' . trim(drupal_basename($image3_realpath)))); }
/** * {@inheritdoc} */ public static function generateSampleValue(FieldDefinitionInterface $field_definition) { $random = new Random(); $settings = $field_definition->getSettings(); static $images = array(); $min_resolution = empty($settings['min_resolution']) ? '100x100' : $settings['min_resolution']; $max_resolution = empty($settings['max_resolution']) ? '600x600' : $settings['max_resolution']; $extensions = array_intersect(explode(' ', $settings['file_extensions']), array('png', 'gif', 'jpg', 'jpeg')); $extension = array_rand(array_combine($extensions, $extensions)); // Generate a max of 5 different images. if (!isset($images[$extension][$min_resolution][$max_resolution]) || count($images[$extension][$min_resolution][$max_resolution]) <= 5) { $tmp_file = drupal_tempnam('temporary://', 'generateImage_'); $destination = $tmp_file . '.' . $extension; file_unmanaged_move($tmp_file, $destination, FILE_CREATE_DIRECTORY); if ($path = $random->image(drupal_realpath($destination), $min_resolution, $max_resolution)) { $image = File::create(); $image->setFileUri($path); $image->setOwnerId(\Drupal::currentUser()->id()); $image->setMimeType(\Drupal::service('file.mime_type.guesser')->guess($path)); $image->setFileName(drupal_basename($path)); $destination_dir = static::doGetUploadLocation($settings); file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY); $destination = $destination_dir . '/' . basename($path); $file = file_move($image, $destination, FILE_CREATE_DIRECTORY); $images[$extension][$min_resolution][$max_resolution][$file->id()] = $file; } else { return array(); } } else { // Select one of the images we've already generated for this field. $image_index = array_rand($images[$extension][$min_resolution][$max_resolution]); $file = $images[$extension][$min_resolution][$max_resolution][$image_index]; } list($width, $height) = getimagesize($file->getFileUri()); $values = array('target_id' => $file->id(), 'alt' => $random->sentences(4), 'title' => $random->sentences(4), 'width' => $width, 'height' => $height); return $values; }
/** * {@inheritdoc} */ public function buildForm(array $form, array &$form_state, $test_id = NULL) { $this->buildStatusImageMap(); // Make sure there are test results to display and a re-run is not being // performed. $results = array(); if (is_numeric($test_id) && !($results = $this->getResults($test_id))) { drupal_set_message($this->t('No test results to display.'), 'error'); return new RedirectResponse(url('admin/config/development/testing', array('absolute' => TRUE))); } // Load all classes and include CSS. $form['#attached']['css'][] = drupal_get_path('module', 'simpletest') . '/css/simpletest.module.css'; // Keep track of which test cases passed or failed. $filter = array('pass' => array(), 'fail' => array()); // Summary result widget. $form['result'] = array('#type' => 'fieldset', '#title' => $this->t('Results')); $form['result']['summary'] = $summary = array('#theme' => 'simpletest_result_summary', '#pass' => 0, '#fail' => 0, '#exception' => 0, '#debug' => 0); simpletest_classloader_register(); // Cycle through each test group. $header = array($this->t('Message'), $this->t('Group'), $this->t('Filename'), $this->t('Line'), $this->t('Function'), array('colspan' => 2, 'data' => $this->t('Status'))); $form['result']['results'] = array(); foreach ($results as $group => $assertions) { // Create group details with summary information. $info = TestDiscovery::getTestInfo(new \ReflectionClass($group)); $form['result']['results'][$group] = array('#type' => 'details', '#title' => $info['name'], '#open' => TRUE, '#description' => $info['description']); $form['result']['results'][$group]['summary'] = $summary; $group_summary =& $form['result']['results'][$group]['summary']; // Create table of assertions for the group. $rows = array(); foreach ($assertions as $assertion) { $row = array(); // Assertion messages are in code, so we assume they are safe. $row[] = SafeMarkup::set($assertion->message); $row[] = $assertion->message_group; $row[] = drupal_basename($assertion->file); $row[] = $assertion->line; $row[] = $assertion->function; $row[] = $this->statusImageMap[$assertion->status]; $class = 'simpletest-' . $assertion->status; if ($assertion->message_group == 'Debug') { $class = 'simpletest-debug'; } $rows[] = array('data' => $row, 'class' => array($class)); $group_summary['#' . $assertion->status]++; $form['result']['summary']['#' . $assertion->status]++; } $form['result']['results'][$group]['table'] = array('#type' => 'table', '#header' => $header, '#rows' => $rows); // Set summary information. $group_summary['#ok'] = $group_summary['#fail'] + $group_summary['#exception'] == 0; $form['result']['results'][$group]['#open'] = !$group_summary['#ok']; // Store test group (class) as for use in filter. $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group; } // Overall summary status. $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0; // Actions. $form['#action'] = url('admin/config/development/testing/results/re-run'); $form['action'] = array('#type' => 'fieldset', '#title' => $this->t('Actions'), '#attributes' => array('class' => array('container-inline')), '#weight' => -11); $form['action']['filter'] = array('#type' => 'select', '#title' => 'Filter', '#options' => array('all' => $this->t('All (@count)', array('@count' => count($filter['pass']) + count($filter['fail']))), 'pass' => $this->t('Pass (@count)', array('@count' => count($filter['pass']))), 'fail' => $this->t('Fail (@count)', array('@count' => count($filter['fail']))))); $form['action']['filter']['#default_value'] = $filter['fail'] ? 'fail' : 'all'; // Categorized test classes for to be used with selected filter value. $form['action']['filter_pass'] = array('#type' => 'hidden', '#default_value' => implode(',', $filter['pass'])); $form['action']['filter_fail'] = array('#type' => 'hidden', '#default_value' => implode(',', $filter['fail'])); $form['action']['op'] = array('#type' => 'submit', '#value' => $this->t('Run tests')); $form['action']['return'] = array('#type' => 'link', '#title' => $this->t('Return to list'), '#href' => 'admin/config/development/testing'); if (is_numeric($test_id)) { simpletest_clean_results_table($test_id); } return $form; }
/** * Returns the canonical absolute path of the URI, if possible. * * @param string $uri * (optional) The stream wrapper URI to be converted to a canonical * absolute path. This may point to a directory or another type of file. * * @return string|bool * If $uri is not set, returns the canonical absolute path of the URI * previously set by the * Drupal\Core\StreamWrapper\StreamWrapperInterface::setUri() function. * If $uri is set and valid for this class, returns its canonical absolute * path, as determined by the realpath() function. If $uri is set but not * valid, returns FALSE. */ protected function getLocalPath($uri = NULL) { if (!isset($uri)) { $uri = $this->uri; } $path = $this->getDirectoryPath() . '/' . $this->getTarget($uri); // In PHPUnit tests, the base path for local streams may be a virtual // filesystem stream wrapper URI, in which case this local stream acts like // a proxy. realpath() is not supported by vfsStream, because a virtual // file system does not have a real filepath. if (strpos($path, 'vfs://') === 0) { return $path; } $realpath = realpath($path); if (!$realpath) { // This file does not yet exist. $realpath = realpath(dirname($path)) . '/' . drupal_basename($path); } $directory = realpath($this->getDirectoryPath()); if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) { return FALSE; } return $realpath; }
/** * @method: * This method is used to download the project for static sites */ public function _download_json($items) { //default variables $zip = new ZipArchive(); $DelFilePath = "project.zip"; $public = variable_get('file_public_path', 'sites/default/files'); $path = DRUPAL_ROOT . '/' . $public . '/'; //ensures that we delete the old file if (file_exists($path . $DelFilePath)) { unlink($path . $DelFilePath); } //creates the zip file and starts to append if ($zip->open($path . $DelFilePath, ZIPARCHIVE::CREATE) != TRUE) { watchdog('getty project', "Could not open archive at " . print_r($path . $DelFilePath, 1)); } //appends the format requested foreach ($items as $id => $output) { $zip->addFromString('source/' . $id . '.html.md.erb', $output); } //does for each image included to download foreach ($this->include_images as $key => $images) { //ensures that the file exists on the server before adding if (file_exists($images)) { $zip->addFile($images, 'source/assets/images/' . drupal_basename($images)); } } // close and save archive $zip->close(); //returns the path of the zip return $path . $DelFilePath; }
/** * {@inheritdoc} */ public static function preCreate(EntityStorageInterface $storage, array &$values) { // Automatically detect filename if not set. if (!isset($values['filename']) && isset($values['uri'])) { $values['filename'] = drupal_basename($values['uri']); } // Automatically detect filemime if not set. if (!isset($values['filemime']) && isset($values['uri'])) { $values['filemime'] = file_get_mimetype($values['uri']); } }
/** * {@inheritdoc} */ public static function preCreate(EntityStorageInterface $storage, array &$values) { // Automatically detect filename if not set. if (!isset($values['filename']) && isset($values['uri'])) { $values['filename'] = drupal_basename($values['uri']); } // Automatically detect filemime if not set. if (!isset($values['filemime']) && isset($values['uri'])) { $values['filemime'] = \Drupal::service('file.mime_type.guesser')->guess($values['uri']); } }
/** * Returns the chroot property for this connection. * * It does this by moving up the tree until it finds itself * * @return string|bool * If successful, the chroot path for this connection, otherwise FALSE. */ function findChroot() { // If the file exists as is, there is no chroot. $path = __FILE__; $path = $this->fixRemotePath($path, FALSE); if ($this->isFile($path)) { return FALSE; } $path = __DIR__; $path = $this->fixRemotePath($path, FALSE); $parts = explode('/', $path); $chroot = ''; while (count($parts)) { $check = implode($parts, '/'); if ($this->isFile($check . '/' . drupal_basename(__FILE__))) { // Remove the trailing slash. return substr($chroot, 0, -1); } $chroot .= array_shift($parts) . '/'; } return FALSE; }
/** * {@inheritdoc} */ public function getActiveTheme(Extension $theme, array $base_themes = []) { $theme_path = $theme->getPath(); $values['path'] = $theme_path; $values['name'] = $theme->getName(); // Prepare stylesheets from this theme as well as all ancestor themes. // We work it this way so that we can have child themes override parent // theme stylesheets easily. $values['stylesheets'] = array(); // CSS file basenames to override, pointing to the final, overridden filepath. $values['stylesheets_override'] = array(); // CSS file basenames to remove. $values['stylesheets_remove'] = array(); // Grab stylesheets from base theme. $final_stylesheets = array(); foreach ($base_themes as $base) { if (!empty($base->stylesheets)) { foreach ($base->stylesheets as $media => $stylesheets) { foreach ($stylesheets as $name => $stylesheet) { $final_stylesheets[$media][$name] = $stylesheet; } } } $base_theme_path = $base->getPath(); if (!empty($base->info['stylesheets-remove'])) { foreach ($base->info['stylesheets-remove'] as $basename) { $values['stylesheets_remove'][$basename] = $base_theme_path . '/' . $basename; } } if (!empty($base->info['stylesheets-override'])) { foreach ($base->info['stylesheets-override'] as $name) { $basename = drupal_basename($name); $values['stylesheets_override'][$basename] = $base_theme_path . '/' . $name; } } } // Add stylesheets used by this theme. if (!empty($theme->stylesheets)) { foreach ($theme->stylesheets as $media => $stylesheets) { foreach ($stylesheets as $name => $stylesheet) { $final_stylesheets[$media][$name] = $stylesheet; } } } if (!empty($theme->info['stylesheets-remove'])) { foreach ($theme->info['stylesheets-remove'] as $basename) { $values['stylesheets_remove'][$basename] = $theme_path . '/' . $basename; if (isset($values['stylesheets_override'][$basename])) { unset($values['stylesheets_override'][$basename]); } } } if (!empty($theme->info['stylesheets-override'])) { foreach ($theme->info['stylesheets-override'] as $name) { $basename = drupal_basename($name); $values['stylesheets_override'][$basename] = $theme_path . '/' . $name; if (isset($values['stylesheets_remove'][$basename])) { unset($values['stylesheets_remove'][$basename]); } } } // And now add the stylesheets properly. $values['stylesheets'] = $final_stylesheets; // Do basically the same as the above for libraries $values['libraries'] = array(); // Grab libraries from base theme foreach ($base_themes as $base) { if (!empty($base->libraries)) { foreach ($base->libraries as $library) { $values['libraries'][] = $library; } } } // Add libraries used by this theme. if (!empty($theme->libraries)) { foreach ($theme->libraries as $library) { $values['libraries'][] = $library; } } $values['engine'] = isset($theme->engine) ? $theme->engine : NULL; $values['owner'] = isset($theme->owner) ? $theme->owner : NULL; $values['extension'] = $theme; $base_active_themes = array(); foreach ($base_themes as $base_theme) { $base_active_themes[$base_theme->getName()] = $this->getActiveTheme($base_theme, array_slice($base_themes, 1)); } $values['base_themes'] = $base_active_themes; return new ActiveTheme($values); }
/** * An adaptation of file_save_upload() that includes more verbose errors. * * @param string $source * A string specifying the filepath or URI of the uploaded file to save. * * @return stdClass * The saved file object. * * @throws \RestfulBadRequestException * @throws \RestfulServiceUnavailable * * @see file_save_upload() */ protected function fileSaveUpload($source) { static $upload_cache; $account = $this->getAccount(); $options = $this->getPluginKey('options'); $validators = $options['validators']; $destination = $options['scheme'] . "://"; $replace = $options['replace']; // Return cached objects without processing since the file will have // already been processed and the paths in _FILES will be invalid. if (isset($upload_cache[$source])) { return $upload_cache[$source]; } // Make sure there's an upload to process. if (empty($_FILES['files']['name'][$source])) { return NULL; } // Check for file upload errors and return FALSE if a lower level system // error occurred. For a complete list of errors: // See http://php.net/manual/features.file-upload.errors.php. switch ($_FILES['files']['error'][$source]) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $message = format_string('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$source], '%maxsize' => format_size(file_upload_max_size()))); throw new \RestfulBadRequestException($message); case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_NO_FILE: $message = format_string('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$source])); throw new \RestfulBadRequestException($message); case UPLOAD_ERR_OK: // Final check that this is a valid upload, if it isn't, use the // default error handler. if (is_uploaded_file($_FILES['files']['tmp_name'][$source])) { break; } // Unknown error default: $message = format_string('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$source])); throw new \RestfulServiceUnavailable($message); } // Begin building file object. $file = new stdClass(); $file->uid = $account->uid; $file->status = 0; $file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.'); $file->uri = $_FILES['files']['tmp_name'][$source]; $file->filemime = file_get_mimetype($file->filename); $file->filesize = $_FILES['files']['size'][$source]; $extensions = ''; if (isset($validators['file_validate_extensions'])) { if (isset($validators['file_validate_extensions'][0])) { // Build the list of non-munged extensions if the caller provided them. $extensions = $validators['file_validate_extensions'][0]; } else { // If 'file_validate_extensions' is set and the list is empty then the // caller wants to allow any extension. In this case we have to remove the // validator or else it will reject all extensions. unset($validators['file_validate_extensions']); } } else { // No validator was provided, so add one using the default list. // Build a default non-munged safe list for file_munge_filename(). $extensions = 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'; $validators['file_validate_extensions'] = array(); $validators['file_validate_extensions'][0] = $extensions; } if (!empty($extensions)) { // Munge the filename to protect against possible malicious extension hiding // within an unknown file type (ie: filename.html.foo). $file->filename = file_munge_filename($file->filename, $extensions); } // Rename potentially executable files, to help prevent exploits (i.e. will // rename filename.php.foo and filename.php to filename.php.foo.txt and // filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads' // evaluates to TRUE. if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) { $file->filemime = 'text/plain'; $file->uri .= '.txt'; $file->filename .= '.txt'; // The .txt extension may not be in the allowed list of extensions. We have // to add it here or else the file upload will fail. if (!empty($extensions)) { $validators['file_validate_extensions'][0] .= ' txt'; // Unlike file_save_upload() we don't need to let the user know that // for security reasons, your upload has been renamed, since RESTful // will return the file name in the response. } } // If the destination is not provided, use the temporary directory. if (empty($destination)) { $destination = 'temporary://'; } // Assert that the destination contains a valid stream. $destination_scheme = file_uri_scheme($destination); if (!$destination_scheme || !file_stream_wrapper_valid_scheme($destination_scheme)) { $message = format_string('The file could not be uploaded, because the destination %destination is invalid.', array('%destination' => $destination)); throw new \RestfulServiceUnavailable($message); } $file->source = $source; // A URI may already have a trailing slash or look like "public://". if (substr($destination, -1) != '/') { $destination .= '/'; } $file->destination = file_destination($destination . $file->filename, $replace); // If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and // there's an existing file so we need to bail. if ($file->destination === FALSE) { $message = format_string('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $source, '%directory' => $destination)); throw new \RestfulServiceUnavailable($message); } // Add in our check of the the file name length. $validators['file_validate_name_length'] = array(); // Call the validation functions specified by this function's caller. $errors = file_validate($file, $validators); // Check for errors. if (!empty($errors)) { $message = format_string('The specified file %name could not be uploaded.', array('%name' => $file->filename)); if (count($errors) > 1) { $message .= theme('item_list', array('items' => $errors)); } else { $message .= ' ' . array_pop($errors); } throw new \RestfulServiceUnavailable($message); } // Move uploaded files from PHP's upload_tmp_dir to Drupal's temporary // directory. This overcomes open_basedir restrictions for future file // operations. $file->uri = $file->destination; if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) { watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri)); $message = 'File upload error. Could not move uploaded file.'; throw new \RestfulServiceUnavailable($message); } // Set the permissions on the new file. drupal_chmod($file->uri); // If we are replacing an existing file re-use its database record. if ($replace == FILE_EXISTS_REPLACE) { $existing_files = file_load_multiple(array(), array('uri' => $file->uri)); if (count($existing_files)) { $existing = reset($existing_files); $file->fid = $existing->fid; } } // If we made it this far it's safe to record this file in the database. if ($file = file_save($file)) { // Add file to the cache. $upload_cache[$source] = $file; return $file; } // Something went wrong, so throw a general exception. throw new \RestfulServiceUnavailable('Unknown error has occurred.'); }
/** * Test styled image dimensions cumulatively. */ function testImageDimensions() { $image_factory = $this->container->get('image.factory'); // Create a working copy of the file. $files = $this->drupalGetTestFiles('image'); $file = reset($files); $original_uri = file_unmanaged_copy($file->uri, 'public://', FILE_EXISTS_RENAME); // Create a style. /** @var $style \Drupal\image\ImageStyleInterface */ $style = entity_create('image_style', array('name' => 'test', 'label' => 'Test')); $style->save(); $generated_uri = 'public://styles/test/public/' . drupal_basename($original_uri); $url = $style->buildUrl($original_uri); $variables = array('#theme' => 'image_style', '#style_name' => 'test', '#uri' => $original_uri, '#width' => 40, '#height' => 20); // Verify that the original image matches the hard-coded values. $image_file = $image_factory->get($original_uri); $this->assertEqual($image_file->getWidth(), $variables['#width']); $this->assertEqual($image_file->getHeight(), $variables['#height']); // Scale an image that is wider than it is high. $effect = array('id' => 'image_scale', 'data' => array('width' => 120, 'height' => 90, 'upscale' => TRUE), 'weight' => 0); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="120" height="60" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); $this->assertEqual($image_file->getWidth(), 120); $this->assertEqual($image_file->getHeight(), 60); // Rotate 90 degrees anticlockwise. $effect = array('id' => 'image_rotate', 'data' => array('degrees' => -90, 'random' => FALSE), 'weight' => 1); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="60" height="120" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); $this->assertEqual($image_file->getWidth(), 60); $this->assertEqual($image_file->getHeight(), 120); // Scale an image that is higher than it is wide (rotated by previous effect). $effect = array('id' => 'image_scale', 'data' => array('width' => 120, 'height' => 90, 'upscale' => TRUE), 'weight' => 2); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); $this->assertEqual($image_file->getWidth(), 45); $this->assertEqual($image_file->getHeight(), 90); // Test upscale disabled. $effect = array('id' => 'image_scale', 'data' => array('width' => 400, 'height' => 200, 'upscale' => FALSE), 'weight' => 3); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); $this->assertEqual($image_file->getWidth(), 45); $this->assertEqual($image_file->getHeight(), 90); // Add a desaturate effect. $effect = array('id' => 'image_desaturate', 'data' => array(), 'weight' => 4); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="45" height="90" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); $this->assertEqual($image_file->getWidth(), 45); $this->assertEqual($image_file->getHeight(), 90); // Add a random rotate effect. $effect = array('id' => 'image_rotate', 'data' => array('degrees' => 180, 'random' => TRUE), 'weight' => 5); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); // Add a crop effect. $effect = array('id' => 'image_crop', 'data' => array('width' => 30, 'height' => 30, 'anchor' => 'center-center'), 'weight' => 6); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" width="30" height="30" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $image_file = $image_factory->get($generated_uri); $this->assertEqual($image_file->getWidth(), 30); $this->assertEqual($image_file->getHeight(), 30); // Rotate to a non-multiple of 90 degrees. $effect = array('id' => 'image_rotate', 'data' => array('degrees' => 57, 'random' => FALSE), 'weight' => 7); $effect_id = $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" alt="" class="image-style-test" />'); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $this->drupalGet($url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $effect_plugin = $style->getEffect($effect_id); $style->deleteImageEffect($effect_plugin); // Ensure that an effect with no dimensions callback unsets the dimensions. // This ensures compatibility with 7.0 contrib modules. $effect = array('id' => 'image_module_test_null', 'data' => array(), 'weight' => 8); $style->addImageEffect($effect); $style->save(); $this->assertEqual($this->getImageTag($variables), '<img src="' . $url . '" alt="" class="image-style-test" />'); }
/** * Tests that new JavaScript and CSS files are lazy-loaded on an AJAX request. */ public function testLazyLoad() { $expected = array('setting_name' => 'ajax_forms_test_lazy_load_form_submit', 'setting_value' => 'executed', 'css' => drupal_get_path('module', 'system') . '/css/system.admin.css', 'js' => drupal_get_path('module', 'system') . '/system.js'); // CSS files are stored by basename, see _drupal_add_css(). $expected_css_basename = drupal_basename($expected['css']); // @todo D8: Add a drupal_css_defaults() helper function. $expected_css_html = drupal_get_css(array($expected_css_basename => array('type' => 'file', 'group' => CSS_AGGREGATE_DEFAULT, 'weight' => 0, 'every_page' => FALSE, 'media' => 'all', 'preprocess' => TRUE, 'data' => $expected['css'], 'browsers' => array('IE' => TRUE, '!IE' => TRUE))), TRUE); $expected_js_html = drupal_get_js('header', array($expected['js'] => drupal_js_defaults($expected['js'])), TRUE); // Get the base page. $this->drupalGet('ajax_forms_test_lazy_load_form'); $original_settings = $this->getDrupalSettings(); $original_css = $original_settings['ajaxPageState']['css']; $original_js = $original_settings['ajaxPageState']['js']; // Verify that the base page doesn't have the settings and files that are to // be lazy loaded as part of the next requests. $this->assertTrue(!isset($original_settings[$expected['setting_name']]), format_string('Page originally lacks the %setting, as expected.', array('%setting' => $expected['setting_name']))); $this->assertTrue(!isset($original_css[$expected['css']]), format_string('Page originally lacks the %css file, as expected.', array('%css' => $expected['css']))); $this->assertTrue(!isset($original_js[$expected['js']]), format_string('Page originally lacks the %js file, as expected.', array('%js' => $expected['js']))); // Submit the AJAX request without triggering files getting added. $commands = $this->drupalPostAjaxForm(NULL, array('add_files' => FALSE), array('op' => t('Submit'))); $new_settings = $this->getDrupalSettings(); $new_css = $new_settings['ajaxPageState']['css']; $new_js = $new_settings['ajaxPageState']['js']; // Verify the setting was not added when not expected. $this->assertTrue(!isset($new_settings[$expected['setting_name']]), format_string('Page still lacks the %setting, as expected.', array('%setting' => $expected['setting_name']))); $this->assertTrue(!isset($new_css[$expected['css']]), format_string('Page still lacks the %css file, as expected.', array('%css' => $expected['css']))); $this->assertTrue(!isset($new_js[$expected['js']]), format_string('Page still lacks the %js file, as expected.', array('%js' => $expected['js']))); // Verify a settings command does not add CSS or scripts to drupalSettings // and no command inserts the corresponding tags on the page. $found_settings_command = FALSE; $found_markup_command = FALSE; foreach ($commands as $command) { if ($command['command'] == 'settings' && (array_key_exists('css', $command['settings']['ajaxPageState']) || array_key_exists('js', $command['settings']['ajaxPageState']))) { $found_settings_command = TRUE; } if (isset($command['data']) && ($command['data'] == $expected_js_html || $command['data'] == $expected_css_html)) { $found_markup_command = TRUE; } } $this->assertFalse($found_settings_command, format_string('Page state still lacks the %css and %js files, as expected.', array('%css' => $expected['css'], '%js' => $expected['js']))); $this->assertFalse($found_markup_command, format_string('Page still lacks the %css and %js files, as expected.', array('%css' => $expected['css'], '%js' => $expected['js']))); // Submit the AJAX request and trigger adding files. $commands = $this->drupalPostAjaxForm(NULL, array('add_files' => TRUE), array('op' => t('Submit'))); $new_settings = $this->getDrupalSettings(); $new_css = $new_settings['ajaxPageState']['css']; $new_js = $new_settings['ajaxPageState']['js']; // Verify the expected setting was added, both to drupalSettings, and as // the first AJAX command. $this->assertIdentical($new_settings[$expected['setting_name']], $expected['setting_value'], format_string('Page now has the %setting.', array('%setting' => $expected['setting_name']))); $expected_command = new SettingsCommand(array($expected['setting_name'] => $expected['setting_value']), TRUE); $this->assertCommand(array_slice($commands, 0, 1), $expected_command->render(), format_string('The settings command was first.')); // Verify the expected CSS file was added, both to drupalSettings, and as // the second AJAX command for inclusion into the HTML. $this->assertEqual($new_css, $original_css + array($expected_css_basename => 1), format_string('Page state now has the %css file.', array('%css' => $expected['css']))); $this->assertCommand(array_slice($commands, 1, 1), array('data' => $expected_css_html), format_string('Page now has the %css file.', array('%css' => $expected['css']))); // Verify the expected JS file was added, both to drupalSettings, and as // the third AJAX command for inclusion into the HTML. By testing for an // exact HTML string containing the SCRIPT tag, we also ensure that // unexpected JavaScript code, such as a jQuery.extend() that would // potentially clobber rather than properly merge settings, didn't // accidentally get added. $this->assertEqual($new_js, $original_js + array($expected['js'] => 1), format_string('Page state now has the %js file.', array('%js' => $expected['js']))); $this->assertCommand(array_slice($commands, 2, 1), array('data' => $expected_js_html), format_string('Page now has the %js file.', array('%js' => $expected['js']))); }
/** * Test file_url_transform_relative(). */ function testRelativeFileURL() { // Disable file_test.module's hook_file_url_alter() implementation. \Drupal::state()->set('file_test.hook_file_url_alter', NULL); // Create a mock Request for file_url_transform_relative(). $request = Request::create($GLOBALS['base_url']); $this->container->get('request_stack')->push($request); \Drupal::setContainer($this->container); // Shipped file. $filepath = 'core/assets/vendor/jquery/jquery.min.js'; $url = file_create_url($filepath); $this->assertIdentical(base_path() . $filepath, file_url_transform_relative($url)); // Managed file. $uri = $this->createUri(); $url = file_create_url($uri); $public_directory_path = \Drupal::service('stream_wrapper_manager')->getViaScheme('public')->getDirectoryPath(); $this->assertIdentical(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url)); }
/** * Returns a Drupal file object of the enclosed resource. * * @param string $destination * The path or uri specifying the target directory in which the file is * expected. Don't use trailing slashes unless it's a streamwrapper scheme. * @param int $replace * (optional) Replace behavior when the destination file already exists: * - FILE_EXISTS_REPLACE - Replace the existing file. If a managed file with * the destination name exists then its database entry will be updated. * If no database entry is found then a new one will be created. * - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename * is unique. * - FILE_EXISTS_ERROR - Do nothing and return FALSE. * Defaults to FILE_EXISTS_RENAME. * * @return \Drupal\file\Entity\FileInterface * A Drupal temporary file object of the enclosed resource. * * @throws \RuntimeException * If file object could not be created. * * @todo Refactor this */ public function getFile($destination, $replace = FILE_EXISTS_RENAME) { $file = FALSE; if (!$this->uri) { return $file; } // Prepare destination directory. file_prepare_directory($destination, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY); // Copy or save file depending on whether it is remote or local. if (drupal_realpath($this->uri)) { $file = entity_create('file', ['uid' => 0, 'uri' => $this->uri, 'filemime' => $this->mimeType, 'filename' => basename($this->uri)]); if (drupal_dirname($file->getFileUri()) != $destination) { $file = file_copy($file, $destination, $replace); } else { // If file is not to be copied, check whether file already exists, // as file_save() won't do that for us (compare file_copy() and // file_save()) $existing_files = file_load_multiple([], ['uri' => $file->getFileUri()]); if ($existing_files) { return reset($existing_files); } $file->save(); } } else { $filename = drupal_basename($this->uri); if (\Drupal::moduleHandler()->moduleExists('transliteration')) { require_once drupal_get_path('module', 'transliteration') . '/transliteration.inc'; $filename = transliteration_clean_filename($filename); } if (file_uri_target($destination)) { $destination = trim($destination, '/') . '/'; } try { $file = file_save_data($this->getContent(), $destination . $filename, $replace); } catch (\Exception $e) { watchdog_exception('Feeds', $e, nl2br(SafeMarkup::checkPlain($e))); } } // We couldn't make sense of this enclosure, throw an exception. if (!$file) { throw new \RuntimeException(SafeMarkup::format('Invalid enclosure %enclosure', ['%enclosure' => $this->uri])); } return $file; }
/** * Gets the name of the project directory (basename). * * @todo It would be nice, if projects contained an info file which could * provide their canonical name. * * @param string $directory * * @return string * The name of the project. */ public static function getProjectName($directory) { return drupal_basename($directory); }
/** * Tests building an image style URL. */ function doImageStyleUrlAndPathTests($scheme, $clean_url = TRUE, $extra_slash = FALSE) { $this->prepareRequestForGenerator($clean_url); // Make the default scheme neither "public" nor "private" to verify the // functions work for other than the default scheme. $this->config('system.file')->set('default_scheme', 'temporary')->save(); // Create the directories for the styles. $directory = $scheme . '://styles/' . $this->style->id(); $status = file_prepare_directory($directory, FILE_CREATE_DIRECTORY); $this->assertNotIdentical(FALSE, $status, 'Created the directory for the generated images for the test style.'); // Create a working copy of the file. $files = $this->drupalGetTestFiles('image'); $file = array_shift($files); $original_uri = file_unmanaged_copy($file->uri, $scheme . '://', FILE_EXISTS_RENAME); // Let the image_module_test module know about this file, so it can claim // ownership in hook_file_download(). \Drupal::state()->set('image.test_file_download', $original_uri); $this->assertNotIdentical(FALSE, $original_uri, 'Created the generated image file.'); // Get the URL of a file that has not been generated and try to create it. $generated_uri = $this->style->buildUri($original_uri); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $generate_url = $this->style->buildUrl($original_uri, $clean_url); // Ensure that the tests still pass when the file is generated by accessing // a poorly constructed (but still valid) file URL that has an extra slash // in it. if ($extra_slash) { $modified_uri = str_replace('://', ':///', $original_uri); $this->assertNotEqual($original_uri, $modified_uri, 'An extra slash was added to the generated file URI.'); $generate_url = $this->style->buildUrl($modified_uri, $clean_url); } if (!$clean_url) { $this->assertTrue(strpos($generate_url, 'index.php/') !== FALSE, 'When using non-clean URLS, the system path contains the script name.'); } // Add some extra chars to the token. $this->drupalGet(str_replace(IMAGE_DERIVATIVE_TOKEN . '=', IMAGE_DERIVATIVE_TOKEN . '=Zo', $generate_url)); $this->assertResponse(403, 'Image was inaccessible at the URL with an invalid token.'); // Change the parameter name so the token is missing. $this->drupalGet(str_replace(IMAGE_DERIVATIVE_TOKEN . '=', 'wrongparam=', $generate_url)); $this->assertResponse(403, 'Image was inaccessible at the URL with a missing token.'); // Check that the generated URL is the same when we pass in a relative path // rather than a URI. We need to temporarily switch the default scheme to // match the desired scheme before testing this, then switch it back to the // "temporary" scheme used throughout this test afterwards. $this->config('system.file')->set('default_scheme', $scheme)->save(); $relative_path = file_uri_target($original_uri); $generate_url_from_relative_path = $this->style->buildUrl($relative_path, $clean_url); $this->assertEqual($generate_url, $generate_url_from_relative_path); $this->config('system.file')->set('default_scheme', 'temporary')->save(); // Fetch the URL that generates the file. $this->drupalGet($generate_url); $this->assertResponse(200, 'Image was generated at the URL.'); $this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.'); $this->assertRaw(file_get_contents($generated_uri), 'URL returns expected file.'); $image = $this->container->get('image.factory')->get($generated_uri); $this->assertEqual($this->drupalGetHeader('Content-Type'), $image->getMimeType(), 'Expected Content-Type was reported.'); $this->assertEqual($this->drupalGetHeader('Content-Length'), $image->getFileSize(), 'Expected Content-Length was reported.'); if ($scheme == 'private') { $this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', 'Expires header was sent.'); $this->assertNotEqual(strpos($this->drupalGetHeader('Cache-Control'), 'no-cache'), FALSE, 'Cache-Control header contains \'no-cache\' to prevent caching.'); $this->assertEqual($this->drupalGetHeader('X-Image-Owned-By'), 'image_module_test', 'Expected custom header has been added.'); // Make sure that a second request to the already existing derivative // works too. $this->drupalGet($generate_url); $this->assertResponse(200, 'Image was generated at the URL.'); // Make sure that access is denied for existing style files if we do not // have access. \Drupal::state()->delete('image.test_file_download'); $this->drupalGet($generate_url); $this->assertResponse(403, 'Confirmed that access is denied for the private image style.'); // Repeat this with a different file that we do not have access to and // make sure that access is denied. $file_noaccess = array_shift($files); $original_uri_noaccess = file_unmanaged_copy($file_noaccess->uri, $scheme . '://', FILE_EXISTS_RENAME); $generated_uri_noaccess = $scheme . '://styles/' . $this->style->id() . '/' . $scheme . '/' . drupal_basename($original_uri_noaccess); $this->assertFalse(file_exists($generated_uri_noaccess), 'Generated file does not exist.'); $generate_url_noaccess = $this->style->buildUrl($original_uri_noaccess); $this->drupalGet($generate_url_noaccess); $this->assertResponse(403, 'Confirmed that access is denied for the private image style.'); // Verify that images are not appended to the response. Currently this test only uses PNG images. if (strpos($generate_url, '.png') === FALSE) { $this->fail('Confirming that private image styles are not appended require PNG file.'); } else { // Check for PNG-Signature (cf. http://www.libpng.org/pub/png/book/chapter08.html#png.ch08.div.2) in the // response body. $this->assertNoRaw(chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10), 'No PNG signature found in the response body.'); } } else { $this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', 'Expires header was sent.'); $this->assertEqual(strpos($this->drupalGetHeader('Cache-Control'), 'no-cache'), FALSE, 'Cache-Control header contains \'no-cache\' to prevent caching.'); if ($clean_url) { // Add some extra chars to the token. $this->drupalGet(str_replace(IMAGE_DERIVATIVE_TOKEN . '=', IMAGE_DERIVATIVE_TOKEN . '=Zo', $generate_url)); $this->assertResponse(200, 'Existing image was accessible at the URL with an invalid token.'); } } // Allow insecure image derivatives to be created for the remainder of this // test. $this->config('image.settings')->set('allow_insecure_derivatives', TRUE)->save(); // Create another working copy of the file. $files = $this->drupalGetTestFiles('image'); $file = array_shift($files); $original_uri = file_unmanaged_copy($file->uri, $scheme . '://', FILE_EXISTS_RENAME); // Let the image_module_test module know about this file, so it can claim // ownership in hook_file_download(). \Drupal::state()->set('image.test_file_download', $original_uri); // Suppress the security token in the URL, then get the URL of a file that // has not been created and try to create it. Check that the security token // is not present in the URL but that the image is still accessible. $this->config('image.settings')->set('suppress_itok_output', TRUE)->save(); $generated_uri = $this->style->buildUri($original_uri); $this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.'); $generate_url = $this->style->buildUrl($original_uri, $clean_url); $this->assertIdentical(strpos($generate_url, IMAGE_DERIVATIVE_TOKEN . '='), FALSE, 'The security token does not appear in the image style URL.'); $this->drupalGet($generate_url); $this->assertResponse(200, 'Image was accessible at the URL with a missing token.'); // Stop supressing the security token in the URL. $this->config('image.settings')->set('suppress_itok_output', FALSE)->save(); // Ensure allow_insecure_derivatives is enabled. $this->assertEqual($this->config('image.settings')->get('allow_insecure_derivatives'), TRUE); // Check that a security token is still required when generating a second // image derivative using the first one as a source. $nested_url = $this->style->buildUrl($generated_uri, $clean_url); $matches_expected_url_format = (bool) preg_match('/styles\\/' . $this->style->id() . '\\/' . $scheme . '\\/styles\\/' . $this->style->id() . '\\/' . $scheme . '/', $nested_url); $this->assertTrue($matches_expected_url_format, "URL for a derivative of an image style matches expected format."); $nested_url_with_wrong_token = str_replace(IMAGE_DERIVATIVE_TOKEN . '=', 'wrongparam=', $nested_url); $this->drupalGet($nested_url_with_wrong_token); $this->assertResponse(403, 'Image generated from an earlier derivative was inaccessible at the URL with a missing token.'); // Check that this restriction cannot be bypassed by adding extra slashes // to the URL. $this->drupalGet(substr_replace($nested_url_with_wrong_token, '//styles/', strrpos($nested_url_with_wrong_token, '/styles/'), strlen('/styles/'))); $this->assertResponse(403, 'Image generated from an earlier derivative was inaccessible at the URL with a missing token, even with an extra forward slash in the URL.'); $this->drupalGet(substr_replace($nested_url_with_wrong_token, '////styles/', strrpos($nested_url_with_wrong_token, '/styles/'), strlen('/styles/'))); $this->assertResponse(403, 'Image generated from an earlier derivative was inaccessible at the URL with a missing token, even with multiple forward slashes in the URL.'); // Make sure the image can still be generated if a correct token is used. $this->drupalGet($nested_url); $this->assertResponse(200, 'Image was accessible when a correct token was provided in the URL.'); // Check that requesting a nonexistent image does not create any new // directories in the file system. $directory = $scheme . '://styles/' . $this->style->id() . '/' . $scheme . '/' . $this->randomMachineName(); $this->drupalGet(file_create_url($directory . '/' . $this->randomString())); $this->assertFalse(file_exists($directory), 'New directory was not created in the filesystem when requesting an unauthorized image.'); }