Chris@0: adminUser = $this->drupalCreateUser(['access content', 'access administration pages', 'administer site configuration', 'administer users', 'administer permissions', 'administer content types', 'administer node fields', 'administer node display', 'administer nodes', 'bypass node access']); Chris@0: $this->drupalLogin($this->adminUser); Chris@0: $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieves a sample file of the specified type. Chris@0: * Chris@0: * @return \Drupal\file\FileInterface Chris@0: */ Chris@0: public function getTestFile($type_name, $size = NULL) { Chris@0: // Get a file to upload. Chris@0: $file = current($this->drupalGetTestFiles($type_name, $size)); Chris@0: Chris@0: // Add a filesize property to files as would be read by Chris@0: // \Drupal\file\Entity\File::load(). Chris@0: $file->filesize = filesize($file->uri); Chris@0: Chris@0: return File::create((array) $file); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Retrieves the fid of the last inserted file. Chris@0: */ Chris@0: public function getLastFileId() { Chris@0: return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates a new file field. Chris@0: * Chris@0: * @param string $name Chris@0: * The name of the new field (all lowercase), exclude the "field_" prefix. Chris@0: * @param string $entity_type Chris@0: * The entity type. Chris@0: * @param string $bundle Chris@0: * The bundle that this field will be added to. Chris@0: * @param array $storage_settings Chris@0: * A list of field storage settings that will be added to the defaults. Chris@0: * @param array $field_settings Chris@0: * A list of instance settings that will be added to the instance defaults. Chris@0: * @param array $widget_settings Chris@0: * A list of widget settings that will be added to the widget defaults. Chris@0: */ Chris@0: public function createFileField($name, $entity_type, $bundle, $storage_settings = [], $field_settings = [], $widget_settings = []) { Chris@0: $field_storage = FieldStorageConfig::create([ Chris@0: 'entity_type' => $entity_type, Chris@0: 'field_name' => $name, Chris@0: 'type' => 'file', Chris@0: 'settings' => $storage_settings, Chris@0: 'cardinality' => !empty($storage_settings['cardinality']) ? $storage_settings['cardinality'] : 1, Chris@0: ]); Chris@0: $field_storage->save(); Chris@0: Chris@0: $this->attachFileField($name, $entity_type, $bundle, $field_settings, $widget_settings); Chris@0: return $field_storage; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Attaches a file field to an entity. Chris@0: * Chris@0: * @param string $name Chris@0: * The name of the new field (all lowercase), exclude the "field_" prefix. Chris@0: * @param string $entity_type Chris@0: * The entity type this field will be added to. Chris@0: * @param string $bundle Chris@0: * The bundle this field will be added to. Chris@0: * @param array $field_settings Chris@0: * A list of field settings that will be added to the defaults. Chris@0: * @param array $widget_settings Chris@0: * A list of widget settings that will be added to the widget defaults. Chris@0: */ Chris@0: public function attachFileField($name, $entity_type, $bundle, $field_settings = [], $widget_settings = []) { Chris@0: $field = [ Chris@0: 'field_name' => $name, Chris@0: 'label' => $name, Chris@0: 'entity_type' => $entity_type, Chris@0: 'bundle' => $bundle, Chris@0: 'required' => !empty($field_settings['required']), Chris@0: 'settings' => $field_settings, Chris@0: ]; Chris@0: FieldConfig::create($field)->save(); Chris@0: Chris@0: entity_get_form_display($entity_type, $bundle, 'default') Chris@0: ->setComponent($name, [ Chris@0: 'type' => 'file_generic', Chris@0: 'settings' => $widget_settings, Chris@0: ]) Chris@0: ->save(); Chris@0: // Assign display settings. Chris@0: entity_get_display($entity_type, $bundle, 'default') Chris@0: ->setComponent($name, [ Chris@0: 'label' => 'hidden', Chris@0: 'type' => 'file_default', Chris@0: ]) Chris@0: ->save(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Updates an existing file field with new settings. Chris@0: */ Chris@0: public function updateFileField($name, $type_name, $field_settings = [], $widget_settings = []) { Chris@0: $field = FieldConfig::loadByName('node', $type_name, $name); Chris@0: $field->setSettings(array_merge($field->getSettings(), $field_settings)); Chris@0: $field->save(); Chris@0: Chris@0: entity_get_form_display('node', $type_name, 'default') Chris@0: ->setComponent($name, [ Chris@0: 'settings' => $widget_settings, Chris@0: ]) Chris@0: ->save(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Uploads a file to a node. Chris@0: * Chris@0: * @param \Drupal\file\FileInterface $file Chris@0: * The File to be uploaded. Chris@0: * @param string $field_name Chris@0: * The name of the field on which the files should be saved. Chris@0: * @param $nid_or_type Chris@0: * A numeric node id to upload files to an existing node, or a string Chris@0: * indicating the desired bundle for a new node. Chris@0: * @param bool $new_revision Chris@0: * The revision number. Chris@0: * @param array $extras Chris@0: * Additional values when a new node is created. Chris@0: * Chris@0: * @return int Chris@0: * The node id. Chris@0: */ Chris@0: public function uploadNodeFile(FileInterface $file, $field_name, $nid_or_type, $new_revision = TRUE, array $extras = []) { Chris@0: return $this->uploadNodeFiles([$file], $field_name, $nid_or_type, $new_revision, $extras); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Uploads multiple files to a node. Chris@0: * Chris@0: * @param \Drupal\file\FileInterface[] $files Chris@0: * The files to be uploaded. Chris@0: * @param string $field_name Chris@0: * The name of the field on which the files should be saved. Chris@0: * @param $nid_or_type Chris@0: * A numeric node id to upload files to an existing node, or a string Chris@0: * indicating the desired bundle for a new node. Chris@0: * @param bool $new_revision Chris@0: * The revision number. Chris@0: * @param array $extras Chris@0: * Additional values when a new node is created. Chris@0: * Chris@0: * @return int Chris@0: * The node id. Chris@0: */ Chris@0: public function uploadNodeFiles(array $files, $field_name, $nid_or_type, $new_revision = TRUE, array $extras = []) { Chris@0: $edit = [ Chris@0: 'title[0][value]' => $this->randomMachineName(), Chris@0: 'revision' => (string) (int) $new_revision, Chris@0: ]; Chris@0: Chris@0: $node_storage = $this->container->get('entity.manager')->getStorage('node'); Chris@0: if (is_numeric($nid_or_type)) { Chris@0: $nid = $nid_or_type; Chris@0: $node_storage->resetCache([$nid]); Chris@0: $node = $node_storage->load($nid); Chris@0: } Chris@0: else { Chris@0: // Add a new node. Chris@0: $extras['type'] = $nid_or_type; Chris@0: $node = $this->drupalCreateNode($extras); Chris@0: $nid = $node->id(); Chris@0: // Save at least one revision to better simulate a real site. Chris@0: $node->setNewRevision(); Chris@0: $node->save(); Chris@0: $node_storage->resetCache([$nid]); Chris@0: $node = $node_storage->load($nid); Chris@0: $this->assertNotEqual($nid, $node->getRevisionId(), 'Node revision exists.'); Chris@0: } Chris@0: Chris@0: // Attach files to the node. Chris@0: $field_storage = FieldStorageConfig::loadByName('node', $field_name); Chris@0: // File input name depends on number of files already uploaded. Chris@0: $field_num = count($node->{$field_name}); Chris@0: $name = 'files[' . $field_name . "_$field_num]"; Chris@0: if ($field_storage->getCardinality() != 1) { Chris@0: $name .= '[]'; Chris@0: } Chris@0: foreach ($files as $file) { Chris@0: $file_path = $this->container->get('file_system')->realpath($file->getFileUri()); Chris@0: if (count($files) == 1) { Chris@0: $edit[$name] = $file_path; Chris@0: } Chris@0: else { Chris@0: $edit[$name][] = $file_path; Chris@0: } Chris@0: } Chris@0: $this->drupalPostForm("node/$nid/edit", $edit, t('Save and keep published')); Chris@0: Chris@0: return $nid; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Removes a file from a node. Chris@0: * Chris@0: * Note that if replacing a file, it must first be removed then added again. Chris@0: */ Chris@0: public function removeNodeFile($nid, $new_revision = TRUE) { Chris@0: $edit = [ Chris@0: 'revision' => (string) (int) $new_revision, Chris@0: ]; Chris@0: Chris@0: $this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove')); Chris@0: $this->drupalPostForm(NULL, $edit, t('Save and keep published')); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Replaces a file within a node. Chris@0: */ Chris@0: public function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE) { Chris@0: $edit = [ Chris@0: 'files[' . $field_name . '_0]' => drupal_realpath($file->getFileUri()), Chris@0: 'revision' => (string) (int) $new_revision, Chris@0: ]; Chris@0: Chris@0: $this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove')); Chris@0: $this->drupalPostForm(NULL, $edit, t('Save and keep published')); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Asserts that a file exists physically on disk. Chris@0: * Chris@0: * Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with Chris@0: * file entities. Chris@0: * Chris@0: * @param \Drupal\File\FileInterface|string $file Chris@0: * Either the file entity or the file URI. Chris@0: * @param string $message Chris@0: * (optional) A message to display with the assertion. Chris@0: */ Chris@0: public static function assertFileExists($file, $message = NULL) { Chris@0: $message = isset($message) ? $message : format_string('File %file exists on the disk.', ['%file' => $file->getFileUri()]); Chris@0: $filename = $file instanceof FileInterface ? $file->getFileUri() : $file; Chris@0: parent::assertFileExists($filename, $message); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Asserts that a file exists in the database. Chris@0: */ Chris@0: public function assertFileEntryExists($file, $message = NULL) { Chris@0: $this->container->get('entity.manager')->getStorage('file')->resetCache(); Chris@0: $db_file = File::load($file->id()); Chris@0: $message = isset($message) ? $message : format_string('File %file exists in database at the correct path.', ['%file' => $file->getFileUri()]); Chris@0: $this->assertEqual($db_file->getFileUri(), $file->getFileUri(), $message); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Asserts that a file does not exist on disk. Chris@0: * Chris@0: * Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with Chris@0: * file entities. Chris@0: * Chris@0: * @param \Drupal\File\FileInterface|string $file Chris@0: * Either the file entity or the file URI. Chris@0: * @param string $message Chris@0: * (optional) A message to display with the assertion. Chris@0: */ Chris@0: public static function assertFileNotExists($file, $message = NULL) { Chris@0: $message = isset($message) ? $message : format_string('File %file exists on the disk.', ['%file' => $file->getFileUri()]); Chris@0: $filename = $file instanceof FileInterface ? $file->getFileUri() : $file; Chris@0: parent::assertFileNotExists($filename, $message); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Asserts that a file does not exist in the database. Chris@0: */ Chris@0: public function assertFileEntryNotExists($file, $message) { Chris@0: $this->container->get('entity.manager')->getStorage('file')->resetCache(); Chris@0: $message = isset($message) ? $message : format_string('File %file exists in database at the correct path.', ['%file' => $file->getFileUri()]); Chris@0: $this->assertFalse(File::load($file->id()), $message); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Asserts that a file's status is set to permanent in the database. Chris@0: */ Chris@0: public function assertFileIsPermanent(FileInterface $file, $message = NULL) { Chris@0: $message = isset($message) ? $message : format_string('File %file is permanent.', ['%file' => $file->getFileUri()]); Chris@0: $this->assertTrue($file->isPermanent(), $message); Chris@0: } Chris@0: Chris@0: }