/** * @covers PHPExiftool\Driver\Metadata\MetadataBag::filterKeysByRegExp */ public function testFilterKeysByRegExp() { $this->object->set('oneKey', 'oneValue'); $this->object->set('oneSecondKey', 'anotherValue'); $this->object->set('thirdKey', 'thirdValue'); $this->assertEquals(2, count($this->object->filterKeysByRegExp('/one.*/'))); }
/** * {@inheritdoc} */ protected function doJob(JobData $data) { $app = $data->getApplication(); $settings = simplexml_load_string($data->getTask()->getSettings()); $clearDoc = (bool) (string) $settings->cleardoc; $MWG = (bool) (string) $settings->mwg; // move this in service provider configuration // $app['exiftool.writer']->setModule(Writer::MODULE_MWG, true); foreach ($app->getDataboxes() as $databox) { $conn = $databox->get_connection(); $metaSubdefs = []; foreach ($databox->get_subdef_structure() as $type => $definitions) { foreach ($definitions as $sub) { $name = $sub->get_name(); if ($sub->meta_writeable()) { $metaSubdefs[$name . '_' . $type] = true; } } } $sql = 'SELECT record_id, coll_id, jeton FROM record WHERE (jeton & ' . PhraseaTokens::WRITE_META . ' > 0)'; $stmt = $conn->prepare($sql); $stmt->execute(); $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); foreach ($rs as $row) { $record_id = $row['record_id']; $token = $row['jeton']; $record = $databox->get_record($record_id); $type = $record->get_type(); $subdefs = []; foreach ($record->get_subdefs() as $name => $subdef) { $write_document = $token & PhraseaTokens::WRITE_META_DOC && $name == 'document'; $write_subdef = $token & PhraseaTokens::WRITE_META_SUBDEF && isset($metaSubdefs[$name . '_' . $type]); if (($write_document || $write_subdef) && $subdef->is_physically_present()) { $subdefs[$name] = $subdef->get_pathfile(); } } $metadata = new Metadata\MetadataBag(); if ($record->getUuid()) { $metadata->add(new Metadata\Metadata(new Tag\XMPExif\ImageUniqueID(), new Value\Mono($record->getUuid()))); $metadata->add(new Metadata\Metadata(new Tag\ExifIFD\ImageUniqueID(), new Value\Mono($record->getUuid()))); $metadata->add(new Metadata\Metadata(new Tag\IPTC\UniqueDocumentID(), new Value\Mono($record->getUuid()))); } $caption = $record->get_caption(); foreach ($databox->get_meta_structure() as $fieldStructure) { $tagName = $fieldStructure->get_tag()->getTagname(); $fieldName = $fieldStructure->get_name(); // skip fields with no src if ($tagName == '') { continue; } // check exiftool known tags to skip Phraseanet:tf-* try { TagFactory::getFromRDFTagname($tagName); } catch (TagUnknown $e) { continue; } try { $field = $caption->get_field($fieldName); $data = $field->get_values(); if ($fieldStructure->is_multi()) { $values = array(); foreach ($data as $value) { $values[] = $value->getValue(); } $value = new Value\Multi($values); } else { $data = array_pop($data); $value = $data->getValue(); $value = new Value\Mono($value); } } catch (\Exception $e) { // the field is not set in the record, erase it if ($fieldStructure->is_multi()) { $value = new Value\Multi(array('')); } else { $value = new Value\Mono(''); } } $metadata->add(new Metadata\Metadata($fieldStructure->get_tag(), $value)); } $app['exiftool.writer']->reset(); if ($MWG) { $app['exiftool.writer']->setModule(ExifWriter::MODULE_MWG, true); } foreach ($subdefs as $name => $file) { $app['exiftool.writer']->erase($name != 'document' || $clearDoc, true); try { $app['exiftool.writer']->write($file, $metadata); $this->log('info', sprintf('meta written for sbasid=%1$d - recordid=%2$d (%3$s)', $databox->get_sbas_id(), $record_id, $name)); } catch (PHPExiftoolException $e) { $this->log('error', sprintf('meta NOT written for sbasid=%1$d - recordid=%2$d (%3$s) because "%s"', $databox->get_sbas_id(), $record_id, $name, $e->getMessage())); } } $sql = 'UPDATE record SET jeton=jeton & ~' . PhraseaTokens::WRITE_META . ' WHERE record_id = :record_id'; $stmt = $conn->prepare($sql); $stmt->execute([':record_id' => $record_id]); $stmt->closeCursor(); } } }
/** * Checks for UUID in metadatas * * @todo Check if a file exists with the same checksum * @todo Check if an UUID is contained in the attributes, replace It if * necessary * * @param boolean $generate if true, if no uuid found, a valid one is generated * @param boolean $write if true, writes uuid in all available metadatas * @return File */ public function getUUID($generate = false, $write = false) { if ($this->uuid && !$write) { return $this->uuid; } $availableUUIDs = ['XMP-exif:ImageUniqueID', 'SigmaRaw:ImageUniqueID', 'IPTC:UniqueDocumentID', 'ExifIFD:ImageUniqueID', 'Canon:ImageUniqueID']; if (!$this->uuid) { $metadatas = $this->media->getMetadatas(); $uuid = null; foreach ($availableUUIDs as $meta) { if ($metadatas->containsKey($meta)) { $candidate = $metadatas->get($meta)->getValue()->asString(); if (Uuid::isValid($candidate)) { $uuid = $candidate; break; } } } if (!$uuid && $generate) { $uuid = Uuid::uuid4(); } $this->uuid = $uuid; } if ($write) { $value = new MonoValue($this->uuid); $metadatas = new ExiftoolMetadataBag(); foreach ($availableUUIDs as $tagname) { $metadatas->add(new Metadata(TagFactory::getFromRDFTagname($tagname), $value)); } /** * PHPExiftool throws exception on some files not supported */ try { $this->app['exiftool.writer']->reset(); $this->app['exiftool.writer']->write($this->getFile()->getRealPath(), $metadatas); } catch (PHPExiftoolException $e) { } } return $this->uuid; }
/** * Map a Bag of metadatas indexed by **Tagnames** to a bag of metadatas * indexed by **FieldNames** * * @param \databox_descriptionStructure $metadatasStructure The databox structure related * @param ExiftoolMetadataBag $bag The metadata bag * @return MetadataBag */ protected function getIndexByFieldName(\databox_descriptionStructure $metadatasStructure, ExiftoolMetadataBag $bag) { $ret = new MetadataBag(); foreach ($metadatasStructure as $databox_field) { if ($bag->containsKey($databox_field->get_tag()->getTagname())) { $ret->set($databox_field->get_name(), $bag->get($databox_field->get_tag()->getTagname())); } } return $ret; }
/** * Parse an Entity associated DOM, returns the metadatas * * @return MetadataBag */ public function ParseMetadatas() { $nodes = $this->getDomXpath()->query('/rdf:RDF/rdf:Description/*'); $metadatas = new MetadataBag(); foreach ($nodes as $node) { $tagname = $this->normalize($node->nodeName); try { $tag = TagFactory::getFromRDFTagname($tagname); } catch (TagUnknown $e) { continue; } $metaValue = $this->readNodeValue($node, $tag); $metadata = new Metadata($tag, $metaValue); $metadatas->set($tagname, $metadata); } return $metadatas; }
/** * @covers PHPExiftool\Writer::addMetadatasArg */ public function testAddMetadatasArg() { $metadatas = new Driver\Metadata\MetadataBag(); $metadatas->add(new Driver\Metadata\Metadata(new Driver\Tag\IPTC\ObjectName(), new Driver\Value\Mono('Beautiful Object'))); $metadatas->add(new Driver\Metadata\Metadata(new Driver\Tag\XMPIptcExt\PersonInImage(), new Driver\Value\Multi(array('Romain', 'Nicolas')))); $writer = new WriterTester($this->getExiftool()); $this->assertNotContains('@', trim($writer->getSyncCommandTester())); $writer->setMode(WriterTester::MODE_EXIF2IPTC, true); $this->assertContains('@ exif2iptc.args', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_EXIF2XMP, true); $this->assertContains('@ exif2xmp.args', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_IPTC2EXIF, true); $this->assertContains('@ iptc2exif', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_IPTC2XMP, true); $this->assertContains('@ iptc2xmp', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_GPS2XMP, true); $this->assertContains('@ gps2xmp', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_PDF2XMP, true); $this->assertContains('@ pdf2xmp', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_XMP2PDF, true); $this->assertContains('@ xmp2pdf', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_XMP2GPS, true); $this->assertContains('@ xmp2gps', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_XMP2EXIF, true); $this->assertContains('@ xmp2exif', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_XMP2IPTC, true); $this->assertContains('@ xmp2iptc', $writer->getSyncCommandTester()); $writer->setMode(WriterTester::MODE_XMP2IPTC, false); $this->assertNotContains('@ xmp2iptc', $writer->getSyncCommandTester()); $writer->setModule(WriterTester::MODULE_MWG, true); $this->assertContains('-use MWG', $writer->addMetadatasArgTester($metadatas)); $writer->setModule(WriterTester::MODULE_MWG, false); $this->assertNotContains('-use MWG', $writer->addMetadatasArgTester($metadatas)); $this->assertRegExp("/\\ -XMP-iptcExt:PersonInImage=['\"]Nicolas['\"]/", $writer->addMetadatasArgTester($metadatas)); }
/** * {@inheritdoc} */ protected function doJob(JobData $data) { $app = $data->getApplication(); $settings = simplexml_load_string($data->getTask()->getSettings()); $clearDoc = (bool) (string) $settings->cleardoc; // move this in service provider configuration $app['exiftool.writer']->setModule(Writer::MODULE_MWG, true); foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) { $connbas = $databox->get_connection(); $subdefgroups = $databox->get_subdef_structure(); $metasubdefs = []; foreach ($subdefgroups as $type => $subdefs) { foreach ($subdefs as $sub) { $name = $sub->get_name(); if ($sub->meta_writeable()) { $metasubdefs[$name . '_' . $type] = true; } } } $sql = 'SELECT record_id, coll_id, jeton FROM record WHERE (jeton & ' . JETON_WRITE_META . ' > 0)'; $stmt = $connbas->prepare($sql); $stmt->execute(); $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); foreach ($rs as $row) { $record_id = $row['record_id']; $jeton = $row['jeton']; $record = $databox->get_record($record_id); $type = $record->get_type(); $subdefs = $record->get_subdefs(); $tsub = []; foreach ($subdefs as $name => $subdef) { $write_document = $jeton & JETON_WRITE_META_DOC && $name == 'document'; $write_subdef = $jeton & JETON_WRITE_META_SUBDEF && isset($metasubdefs[$name . '_' . $type]); if (($write_document || $write_subdef) && $subdef->is_physically_present()) { $tsub[$name] = $subdef->get_pathfile(); } } $metadatas = new Metadata\MetadataBag(); if ($record->get_uuid()) { $metadatas->add(new Metadata\Metadata(new Tag\XMPExif\ImageUniqueID(), new Value\Mono($record->get_uuid()))); $metadatas->add(new Metadata\Metadata(new Tag\ExifIFD\ImageUniqueID(), new Value\Mono($record->get_uuid()))); $metadatas->add(new Metadata\Metadata(new Tag\IPTC\UniqueDocumentID(), new Value\Mono($record->get_uuid()))); } foreach ($record->get_caption()->get_fields() as $field) { $meta = $field->get_databox_field(); /* @var $meta \databox_field */ $datas = $field->get_values(); if ($meta->is_multi()) { $values = []; foreach ($datas as $data) { $values[] = $data->getValue(); } $value = new Value\Multi($values); } else { $data = array_pop($datas); $value = new Value\Mono($data->getValue()); } $metadatas->add(new Metadata\Metadata($meta->get_tag(), $value)); } foreach ($tsub as $name => $file) { $app['exiftool.writer']->erase($name != 'document' || $clearDoc, true); try { $app['exiftool.writer']->write($file, $metadatas); $this->log('debug', sprintf('meta written for sbasid=%1$d - recordid=%2$d (%3$s)', $databox->get_sbas_id(), $record_id, $name)); } catch (PHPExiftoolException $e) { $this->log('error', sprintf('meta was not written for sbasid=%d - recordid=%d (%s) because "%s"', $databox->get_sbas_id(), $record_id, $name, $e->getMessage())); } } $sql = 'UPDATE record SET jeton=jeton & ~' . JETON_WRITE_META . ' WHERE record_id = :record_id'; $stmt = $connbas->prepare($sql); $stmt->execute([':record_id' => $row['record_id']]); $stmt->closeCursor(); } } }