/** * Creates a folder artefact based on the given entry. * * @param SimpleXMLElement $entry The entry to base the folder's data on * @param PluginImport $importer The importer * @param int $parent The ID of the parent artefact for this folder * @throws ImportException If the given entry is not detected as being a folder * @return int The ID of the folder artefact created */ private static function create_folder(SimpleXMLElement $entry, PluginImport $importer, $parent = null) { if (!self::is_folder($entry, $importer)) { throw new ImportException($importer, "create_folder(): Cannot create a folder artefact from an entry we don't recognise as a folder"); } $folder = new ArtefactTypeFolder(); $folder->set('title', (string) $entry->title); $folder->set('description', PluginImportLeap::get_entry_content($entry, $importer)); if ($published = strtotime((string) $entry->published)) { $folder->set('ctime', $published); } if ($updated = strtotime((string) $entry->updated)) { $folder->set('mtime', $updated); } $folder->set('owner', $importer->get('usr')); $folder->set('tags', PluginImportLeap::get_entry_tags($entry)); if ($parent) { $folder->set('parent', $parent); } $folder->commit(); return $folder->get('id'); }
/** * Creates a comment from the given entry * * @param SimpleXMLElement $entry The entry to create the comment from * @param PluginImportLeap $importer The importer * @return array A list of artefact IDs created, to be used with the artefact mapping. */ private static function create_comment(SimpleXMLElement $entry, PluginImportLeap $importer) { $createdartefacts = array(); $comment = new ArtefactTypeComment(); $comment->set('title', (string) $entry->title); $description = PluginImportLeap::get_entry_content($entry, $importer); $type = isset($entry->content['type']) ? (string) $entry->content['type'] : 'text'; if ($type == 'text') { $description = format_whitespace($description); } $comment->set('description', $description); if ($published = strtotime((string) $entry->published)) { $comment->set('ctime', $published); } if ($updated = strtotime((string) $entry->updated)) { $comment->set('mtime', $updated); } $private = PluginImportLeap::is_correct_category_scheme($entry, $importer, 'audience', 'Private'); $comment->set('private', (int) $private); $comment->set('owner', $importer->get('usr')); if (isset($entry->author->name) && strlen($entry->author->name)) { $comment->set('authorname', $entry->author->name); } else { $comment->set('author', $importer->get('usr')); } if (empty(self::$tempview)) { self::create_temporary_view($importer->get('usr')); } $comment->set('onview', self::$tempview); $comment->set('tags', PluginImportLeap::get_entry_tags($entry)); $comment->commit(); array_unshift($createdartefacts, $comment->get('id')); return $createdartefacts; }
/** * Creates a plan or task from the given entry * * @param SimpleXMLElement $entry The entry to create the plan or task from * @param PluginImportLeap $importer The importer * @return array A list of artefact IDs created, to be used with the artefact mapping. */ private static function create_plan(SimpleXMLElement $entry, PluginImportLeap $importer) { // First decide if it's going to be a plan or a task depending // on whether it has any ancestral plans. if (self::get_ancestor_entryid($entry, $importer)) { $artefact = new ArtefactTypeTask(); } else { $artefact = new ArtefactTypePlan(); } $artefact->set('title', (string) $entry->title); $artefact->set('description', PluginImportLeap::get_entry_content($entry, $importer)); $artefact->set('owner', $importer->get('usr')); if (isset($entry->author->name) && strlen($entry->author->name)) { $artefact->set('authorname', $entry->author->name); } else { $artefact->set('author', $importer->get('usr')); } if ($published = strtotime((string) $entry->published)) { $artefact->set('ctime', $published); } if ($updated = strtotime((string) $entry->updated)) { $artefact->set('mtime', $updated); } $artefact->set('tags', PluginImportLeap::get_entry_tags($entry)); // Set completiondate and completed status if we can find them if ($artefact instanceof ArtefactTypeTask) { $namespaces = $importer->get_namespaces(); $ns = $importer->get_leap2a_namespace(); $dates = PluginImportLeap::get_leap_dates($entry, $namespaces, $ns); if (!empty($dates['target']['value'])) { $completiondate = strtotime($dates['target']['value']); } $artefact->set('completiondate', empty($completiondate) ? $artefact->get('mtime') : $completiondate); if ($entry->xpath($namespaces[$ns] . ':status[@' . $namespaces[$ns] . ':stage="completed"]')) { $artefact->set('completed', 1); } } $artefact->commit(); return array($artefact->get('id')); }
/** * Import data about the feed author. * * If we have a persondata element for them, we can import lots of * different information about them into Mahara's profile section. * Otherwise, we can only import some very basic information from the * <author> element. * * TODO: Refactor this to combine it with add_import_entry_request_author_data() * * @param PluginImportLeap $importer The importer * @param string $persondataid The ID of the person entry corresponding * to the author, if there is one */ public static function import_author_data(PluginImportLeap $importer, $persondataid) { $namespaces = $importer->get_namespaces(); $ns = $namespaces[$importer->get_leap2a_namespace()]; if ($persondataid) { // Grab all the leap:persondata elements and import them $person = $importer->get_entry_by_id($persondataid); // The introduction comes from the entry content if (!self::$personcontentblank) { $introduction = new ArtefactTypeIntroduction(0, array('owner' => $importer->get('usr'))); $introduction->set('title', PluginImportLeap::get_entry_content($person, $importer)); $introduction->commit(); } // Most of the rest of the profile data comes from leap:persondata elements $persondata = $person->xpath($ns . ':persondata'); foreach ($persondata as $item) { $leapattributes = PluginImportLeap::get_attributes($item, $importer->get_leap2a_namespace()); if (isset($leapattributes['field'])) { self::import_persondata($importer, $item, $leapattributes); } else { // 'Field' is required // http://wiki.cetis.ac.uk/2009-03/Leap2A_personal_data#field $importer->trace('WARNING: persondata element did not have leap:field attribute'); continue; } } // The information about someone's name is much more comprehensive // in Leap than what Mahara has, so we have to piece it together self::import_namedata($importer, $persondata); // People can have address info associated with them $addressdata = $person->xpath($ns . ':spatial'); if (is_array($addressdata) && count($addressdata) == 1) { self::import_addressdata($importer, $addressdata[0]); } // Set default profile icon. We look at rel="related" links on this // element, and take the first one that we turned into a profile // icon to be the default. In future versions of the spec, we may use // a "depicts" type relationship to explicitly identify them. foreach ($person->link as $link) { if ($importer->curie_equals($link['rel'], '', 'related') && isset($link['href'])) { $artefactids = $importer->get_artefactids_imported_by_entryid((string) $link['href']); if (count($artefactids) == 1 && ($potentialicon = artefact_instance_from_id($artefactids[0]))) { if ($potentialicon->get('artefacttype') == 'profileicon') { $importer->get('usrobj')->profileicon = $potentialicon->get('id'); $importer->get('usrobj')->commit(); // The first one we find in the export is the profile icon break; } } } } } else { $author = $importer->get('xml')->xpath('//a:feed/a:author[1]'); $author = $author[0]; if (!isset($author->name)) { throw new ImportException($importer, 'TODO: get_string: <author> must include <name> - http://wiki.cetis.ac.uk/2009-03/Leap2A_relationships#Author'); } $name = (string) $author->name; if (false !== strpos($name, ' ')) { list($firstname, $lastname) = explode(' ', $name, 2); self::create_artefact($importer, 'firstname', trim($firstname)); self::create_artefact($importer, 'lastname', trim($lastname)); } else { // Blatant assumtion that the <name> is a first name self::create_artefact($importer, 'firstname', trim($name)); } if (isset($author->email)) { self::create_artefact($importer, 'email', (string) $author->email); } if (isset($author->uri)) { $uri = (string) $author->uri; if (preg_match('#^https?://#', $uri)) { self::create_artefact($importer, 'officialwebsite', (string) $author->uri); } } } }
public static function import_using_strategy(SimpleXMLElement $entry, PluginImportLeap $importer, $strategy, array $otherentries) { $artefactmapping = array(); switch ($strategy) { case self::STRATEGY_IMPORT_AS_ENTRY: case self::STRATEGY_IMPORT_AS_ABILITY: // Based on the mahara:type, we might be able to import it as // something useful - otherwise, there is nothing we can do. The // entry already claimed it was mahara:plugin="resume", so it's // perfectly fine for us to not import it if we don't recognise it if ($strategy == self::STRATEGY_IMPORT_AS_ENTRY) { $types = array('careergoal', 'academicgoal', 'personalgoal', 'interest', 'coverletter'); } else { $types = array('workskill', 'academicskill', 'personalskill'); } $typexpath = join('" or @mahara:type="', $types); $artefactpluginelement = $entry->xpath('mahara:artefactplugin[@mahara:type="' . $typexpath . '"]'); if (count($artefactpluginelement) == 1) { $artefactpluginelement = $artefactpluginelement[0]; $maharaattributes = PluginImportLeap::get_attributes($artefactpluginelement, PluginImportLeap::NS_MAHARA); if (isset($maharaattributes['type']) && in_array($maharaattributes['type'], $types)) { $artefactmapping[(string) $entry->id] = array(self::create_artefact($importer, $maharaattributes['type'], $entry->title, PluginImportLeap::get_entry_content($entry, $importer))); } } break; case self::STRATEGY_IMPORT_AS_ACHIEVEMENT: $dates = PluginImportLeap::get_leap_dates($entry, $importer->get_namespaces(), $importer->get_leap2a_namespace()); $enddate = isset($dates['end']) ? self::convert_leap_date_to_resume_date($dates['end']) : ''; $values = array('date' => $enddate, 'title' => $entry->title, 'description' => PluginImportLeap::get_entry_content($entry, $importer), 'displayorder' => self::get_display_order_for_entry($entry, $importer, 'certification')); ArtefactTypeResumeComposite::ensure_composite_value($values, 'certification', $importer->get('usr')); break; case self::STRATEGY_IMPORT_AS_EMPLOYMENT: $dates = PluginImportLeap::get_leap_dates($entry, $importer->get_namespaces(), $importer->get_leap2a_namespace()); $startdate = isset($dates['start']) ? self::convert_leap_date_to_resume_date($dates['start']) : ''; $enddate = isset($dates['end']) ? self::convert_leap_date_to_resume_date($dates['end']) : ''; $employer = ''; if (isset($otherentries['organization'])) { $organization = $importer->get_entry_by_id($otherentries['organization']); $employer = $organization->title; } $values = array('startdate' => $startdate, 'enddate' => $enddate, 'employer' => $employer, 'jobtitle' => $entry->title, 'positiondescription' => PluginImportLeap::get_entry_content($entry, $importer), 'displayorder' => self::get_display_order_for_entry($entry, $importer, 'employmenthistory')); ArtefactTypeResumeComposite::ensure_composite_value($values, 'employmenthistory', $importer->get('usr')); break; case self::STRATEGY_IMPORT_AS_BOOK: $dates = PluginImportLeap::get_leap_dates($entry, $importer->get_namespaces(), $importer->get_leap2a_namespace()); $enddate = isset($dates['end']) ? self::convert_leap_date_to_resume_date($dates['end']) : ''; $contribution = $description = ''; if (count($otherentries)) { $role = $importer->get_entry_by_id($otherentries[0]); $contribution = $role->title; $description = PluginImportLeap::get_entry_content($role, $importer); } // check if the import is of the version leap2a 2010-07. If it is then override the contribution and description if ($importer->get_leap2a_namespace() == PluginImportLeap::NS_LEAP) { $myrole = PluginImportLeap::get_leap_myrole($entry, $importer->get_namespaces(), $importer->get_leap2a_namespace()); if ($myrole) { $contribution = $myrole; } $description = PluginImportLeap::get_entry_content($entry, $importer); } $values = array('date' => $enddate, 'title' => $entry->title, 'contribution' => $contribution, 'description' => $description, 'displayorder' => self::get_display_order_for_entry($entry, $importer, 'book')); ArtefactTypeResumeComposite::ensure_composite_value($values, 'book', $importer->get('usr')); break; case self::STRATEGY_IMPORT_AS_EDUCATION: $dates = PluginImportLeap::get_leap_dates($entry, $importer->get_namespaces(), $importer->get_leap2a_namespace()); $startdate = isset($dates['start']) ? self::convert_leap_date_to_resume_date($dates['start']) : ''; $enddate = isset($dates['end']) ? self::convert_leap_date_to_resume_date($dates['end']) : ''; $qualtype = $qualname = ''; if (isset($otherentries['achievement'])) { $qualification = $importer->get_entry_by_id($otherentries['achievement']); $qualtype = $qualification->title; $qualname = PluginImportLeap::get_entry_content($qualification, $importer); } $institution = ''; if (isset($otherentries['organization'])) { $organization = $importer->get_entry_by_id($otherentries['organization']); $institution = $organization->title; } if (!$qualname) { $qualname = $entry->title; } $values = array('startdate' => $startdate, 'enddate' => $enddate, 'qualtype' => $qualtype, 'qualname' => $qualname, 'institution' => $institution, 'qualdescription' => PluginImportLeap::get_entry_content($entry, $importer), 'displayorder' => self::get_display_order_for_entry($entry, $importer, 'educationhistory')); ArtefactTypeResumeComposite::ensure_composite_value($values, 'educationhistory', $importer->get('usr')); break; case self::STRATEGY_IMPORT_AS_MEMBERSHIP: $dates = PluginImportLeap::get_leap_dates($entry, $importer->get_namespaces(), $importer->get_leap2a_namespace()); $startdate = isset($dates['start']) ? self::convert_leap_date_to_resume_date($dates['start']) : ''; $enddate = isset($dates['end']) ? self::convert_leap_date_to_resume_date($dates['end']) : ''; $values = array('startdate' => $startdate, 'enddate' => $enddate, 'title' => $entry->title, 'description' => PluginImportLeap::get_entry_content($entry, $importer), 'displayorder' => self::get_display_order_for_entry($entry, $importer, 'membership')); ArtefactTypeResumeComposite::ensure_composite_value($values, 'membership', $importer->get('usr')); break; case self::STRATEGY_IMPORT_AS_SELECTION: // This space intentionally left blank break; default: throw new ImportException($importer, 'TODO: get_string: unknown strategy chosen for importing entry'); } return $artefactmapping; }
/** * Logic to figure out how to process an entry into a comment * Used by import_using_strategy() and add_import_entry_request_using_strategy(). * * @param SimpleXMLElement $entry * @param PluginImportLeap $importer * @param unknown_type $strategy * @param array $otherentries * @return array An array of config stuff to either create the comment, or store an import request. * @throws ImportException */ private static function get_entry_data_using_strategy(SimpleXMLElement $entry, PluginImportLeap $importer, $strategy, array $otherentries) { if ($strategy != self::STRATEGY_IMPORT_AS_COMMENT) { throw new ImportException($importer, 'TODO: get_string: unknown strategy chosen for importing entry'); } $description = PluginImportLeap::get_entry_content($entry, $importer); $type = isset($entry->content['type']) ? (string) $entry->content['type'] : 'text'; if ($type == 'text') { $description = format_whitespace($description); } if (isset($entry->author->name) && strlen($entry->author->name)) { $authorname = (string) $entry->author->name; } else { $author = $importer->get('usr'); } return array('owner' => $importer->get('usr'), 'type' => 'comment', 'content' => array('title' => (string) $entry->title, 'description' => $description, 'ctime' => (string) $entry->published, 'mtime' => (string) $entry->updated, 'private' => (int) PluginImportLeap::is_correct_category_scheme($entry, $importer, 'audience', 'Private'), 'authorname' => isset($authorname) ? $authorname : null, 'author' => isset($author) ? $author : null, 'tags' => PluginImportLeap::get_entry_tags($entry))); }
/** * Creates a blogpost from the given entry * * @param SimpleXMLElement $entry The entry to create the blogpost from * @param PluginImportLeap $importer The importer * @param int $blogid The blog in which to put the post * @return array A list of artefact IDs created, to be used with the artefact mapping. * There will either be one (the blogpost ID), or two. If there is two, the * second one will be the ID of the file created to hold the out-of-line * content associated with the blogpost */ private static function create_blogpost(SimpleXMLElement $entry, PluginImportLeap $importer, $blogid) { $createdartefacts = array(); $blogpost = new ArtefactTypeBlogPost(); $blogpost->set('title', (string) $entry->title); // If the entry has out of line content, we import that separately as a // file and set the content to refer to it if (isset($entry->content['src']) && isset($entry->content['type'])) { $file = LeapImportFile::create_file($entry, $importer); $createdartefacts[] = $file->get('id'); $content = '<a href="' . get_config('wwwroot') . 'artefact/file/download.php?file=' . $file->get('id') . '"' . ' title="' . hsc($file->get('title')) . '">'; if (is_image_mime_type($file->get('filetype'))) { $content .= '<img src="' . get_config('wwwroot') . 'artefact/file/download.php?file=' . $file->get('id') . '&maxwidth=500&maxheight=500"' . ' alt="' . hsc($file->get('title')) . '">'; } $content .= '</a>'; $blogpost->set('description', $content); } else { $description = PluginImportLeap::get_entry_content($entry, $importer); $type = isset($entry->content['type']) ? (string) $entry->content['type'] : 'text'; if ($type == 'text') { $description = format_whitespace($description); } $blogpost->set('description', $description); } if ($published = strtotime((string) $entry->published)) { $blogpost->set('ctime', $published); } if ($updated = strtotime((string) $entry->updated)) { $blogpost->set('mtime', $updated); } $draftpost = count($entry->xpath('a:category[(' . $importer->curie_xpath('@scheme', PluginImportLeap::NS_CATEGORIES, 'readiness#') . ') and @term="Unready"]')) == 1; $blogpost->set('published', $draftpost ? 0 : 1); $blogpost->set('owner', $importer->get('usr')); $blogpost->set('parent', $blogid); $blogpost->set('tags', PluginImportLeap::get_entry_tags($entry)); $blogpost->commit(); array_unshift($createdartefacts, $blogpost->get('id')); return $createdartefacts; }
private static function get_folder_entry_data(SimpleXMLElement $entry, PluginImportLeap $importer, $parent = null) { if (!self::is_folder($entry, $importer)) { throw new ImportException($importer, "get_folder_entry_data(): Cannot add an import entry request for a folder we don't recognise as a folder"); } return array('owner' => $importer->get('usr'), 'type' => 'folder', 'parent' => $parent, 'content' => array('title' => (string) $entry->title, 'description' => PluginImportLeap::get_entry_content($entry, $importer), 'ctime' => (string) $entry->published, 'mtime' => (string) $entry->updated, 'tags' => PluginImportLeap::get_entry_tags($entry))); }
private static function get_annotationfeedback_entry_data(SimpleXMLElement $entry, PluginImportLeap $importer, $annotationentryid) { $description = PluginImportLeap::get_entry_content($entry, $importer); $type = isset($entry->content['type']) ? (string) $entry->content['type'] : 'text'; if ($type == 'text') { $description = format_whitespace($description); } if (isset($entry->author->name) && strlen($entry->author->name)) { $authorname = (string) $entry->author->name; } else { $author = $importer->get('usr'); } return array('owner' => $importer->get('usr'), 'type' => 'annotationfeedback', 'parent' => $annotationentryid, 'content' => array('title' => (string) $entry->title, 'description' => $description, 'ctime' => (string) $entry->published, 'mtime' => (string) $entry->updated, 'authorname' => isset($authorname) ? $authorname : null, 'author' => isset($author) ? $author : null, 'tags' => PluginImportLeap::get_entry_tags($entry), 'private' => (int) PluginImportLeap::is_correct_category_scheme($entry, $importer, 'audience', 'Private'), 'onannotation' => $annotationentryid)); }
private static function get_blogpost_entry_data(SimpleXMLElement $entry, PluginImportLeap $importer, $blogentryid) { // If the entry has out of line content, we import that separately as a // file and set the content to refer to it if (LeapImportFile::is_file($entry, $importer)) { $isfile = true; } else { $isfile = false; $description = PluginImportLeap::get_entry_content($entry, $importer); $type = isset($entry->content['type']) ? (string) $entry->content['type'] : 'text'; if ($type == 'text') { $description = format_whitespace($description); } } return $config = array('isfile' => $isfile, 'owner' => $importer->get('usr'), 'type' => 'blogpost', 'parent' => $blogentryid, 'content' => array('title' => (string) $entry->title, 'description' => isset($description) ? $description : null, 'files' => self::add_files_to_import_entry_request_blogpost($entry, $importer, $blogentryid), 'ctime' => (string) $entry->published, 'mtime' => (string) $entry->updated, 'published' => PluginImportLeap::is_correct_category_scheme($entry, $importer, 'readiness', 'Unready') ? 0 : 1, 'tags' => PluginImportLeap::get_entry_tags($entry))); }
/** * Creates a cpd or activity from the given entry * * @param SimpleXMLElement $entry The entry to create the cpd or activity from * @param PluginImportLeap $importer The importer * @return array A list of artefact IDs created, to be used with the artefact mapping. */ private static function create_cpd(SimpleXMLElement $entry, PluginImportLeap $importer) { // First decide if it's going to be a cpd or a activity depending // on whether it has any ancestral cpds. if (self::get_ancestor_entryid($entry, $importer)) { $artefact = new ArtefactTypeActivity(); } else { $artefact = new ArtefactTypeCPD(); } $artefact->set('title', (string) $entry->title); $artefact->set('description', PluginImportLeap::get_entry_content($entry, $importer)); $artefact->set('owner', $importer->get('usr')); if (isset($entry->author->name) && strlen($entry->author->name)) { $artefact->set('authorname', $entry->author->name); } else { $artefact->set('author', $importer->get('usr')); } if ($published = strtotime((string) $entry->published)) { $artefact->set('ctime', $published); } if ($updated = strtotime((string) $entry->updated)) { $artefact->set('mtime', $updated); } $artefact->set('tags', PluginImportLeap::get_entry_tags($entry)); // Set startdate and hours status if we can find them if ($artefact instanceof ArtefactTypeActivity) { $namespaces = $importer->get_namespaces(); $ns = $importer->get_leap2a_namespace(); $startdate = $enddate = null; $dates = PluginImportLeap::get_leap_dates($entry, $namespaces, $ns); if (!empty($dates['start']['value'])) { $startdate = strtotime($dates['start']['value']); } if (!empty($dates['end']['value'])) { $enddate = strtotime($dates['end']['value']); } $artefact->set('startdate', empty($startdate) ? $artefact->get('mtime') : $startdate); $artefact->set('enddate', $enddate); $location = $entry->xpath($namespaces[$ns] . ':spatial'); if (is_array($location) && count($location) == 1) { $artefact->set('location', $location[0]); } $hours = $entry->xpath($namespaces[PluginImportLeap::NS_MAHARA] . ':hours'); if (is_array($hours) && count($hours) == 1) { $artefact->set('hours', $hours[0]); } } $artefact->commit(); return array($artefact->get('id')); }
/** * Custom hook to import data about the feed author. * * If we have a persondata element for them, we can import lots of * different information about them into Mahara's profile section. * Otherwise, we can only import some very basic information from the * <author> element. * * @param PluginImport $importer The importer */ public static function import_author_data(PluginImport $importer) { if (self::$persondataid) { // Grab all the leap:persondata elements and import them $person = $importer->get_entry_by_id(self::$persondataid); // The introduction comes from the entry content $introduction = new ArtefactTypeIntroduction(0, array('owner' => $importer->get('usr'))); $introduction->set('title', PluginImportLeap::get_entry_content($person, $importer)); $introduction->commit(); // Most of the rest of the profile data comes from leap:persondata elements $persondata = $person->xpath('leap:persondata'); foreach ($persondata as $item) { $leapattributes = array(); foreach ($item->attributes(PluginImportLeap::NS_LEAP) as $key => $value) { $leapattributes[$key] = (string) $value; } if (!isset($leapattributes['field'])) { // 'Field' is required // http://wiki.cetis.ac.uk/2009-03/LEAP2A_personal_data#field $importer->trace('WARNING: persondata element did not have leap:field attribute'); continue; } self::import_persondata($importer, $item, $leapattributes); } // The information about someone's name is much more comprehensive // in LEAP than what Mahara has, so we have to piece it together self::import_namedata($importer, $persondata); // People can have address info associated with them $addressdata = $person->xpath('leap:spatial'); if (count($addressdata) == 1) { self::import_addressdata($importer, $addressdata[0]); } } else { $author = $importer->get('xml')->xpath('//a:feed/a:author[1]'); $author = $author[0]; if (!isset($author->name)) { throw new ImportException($importer, 'TODO: get_string: <author> must include <name> - http://wiki.cetis.ac.uk/2009-03/LEAP2A_relationships#Author'); } $name = (string) $author->name; if (false !== strpos($name, ' ')) { list($firstname, $lastname) = explode(' ', $name, 2); self::create_artefact($importer, 'firstname', trim($firstname)); self::create_artefact($importer, 'lastname', trim($lastname)); } else { // Blatant assumtion that the <name> is a first name self::create_artefact($importer, 'firstname', trim($name)); } if (isset($author->email)) { self::create_artefact($importer, 'email', (string) $author->email); } if (isset($author->uri)) { $uri = (string) $author->uri; if (preg_match('#^https?://#', $uri)) { self::create_artefact($importer, 'officialwebsite', (string) $author->uri); } } } }