/** * Builds a new block instance as a copy of this one, taking into account * the Views being copied from and to. * * Blocktypes can decide whether they want to be copied to the new View. The * return value of this method should indicate whether the blocktype was * copied or not. * * @param View $view The view that this new blockinstance is being created for * @param View $template The view that this (the old) blockinstance comes from * @param array $artefactcopies Correspondence between original artefact IDs and IDs of copies * @return boolean Whether a new blockinstance was made or not. */ public function copy(View $view, View $template, &$artefactcopies) { $blocktypeclass = generate_class_name('blocktype', $this->get('blocktype')); $configdata = $this->get('configdata'); if (isset($configdata['copytype'])) { $copytype = $configdata['copytype']; } else { $copytype = call_static_method($blocktypeclass, 'default_copy_type'); } $viewowner = $view->ownership(); $templateowner = $template->ownership(); $sameowner = $viewowner['type'] == $templateowner['type'] && $viewowner['id'] == $templateowner['id']; // Check to see if the block is allowed to be copied into the new View // // Note for later: this is Blockinstance->allowed_in_view. This // determines whether this blockinstance should be copied into a view. // This could be a different question from BlockType::allowed_in_view! // But for now they use the same method. if (!call_static_method($blocktypeclass, 'allowed_in_view', $view)) { return false; } if ($copytype == 'nocopy' && !$sameowner) { return false; } $newblock = new BlockInstance(0, array('blocktype' => $this->get('blocktype'), 'title' => $this->get('title'), 'view' => $view->get('id'), 'view_obj' => $view, 'row' => $this->get('row'), 'column' => $this->get('column'), 'order' => $this->get('order'))); if ($sameowner || $copytype == 'reference') { $newblock->set('configdata', $configdata); $newblock->commit(); return true; } $artefactids = get_column('view_artefact', 'artefact', 'block', $this->get('id')); if (!empty($artefactids) && $copytype == 'full') { // Copy artefacts & put the new artefact ids into the new block. // Artefacts may have children (defined using the parent column of the artefact table) and attachments (currently // only for blogposts). If we copy an artefact we must copy all its descendents & attachments too. $descendants = artefact_get_descendants($artefactids); // We need the artefact instance before we can get its attachments $tocopy = array(); $attachmentlists = array(); $embedlists = array(); foreach ($descendants as $d) { if (!isset($artefactcopies[$d])) { $tocopy[$d] = artefact_instance_from_id($d); // Get attachments. $attachmentlists[$d] = $tocopy[$d]->attachment_id_list(); foreach ($attachmentlists[$d] as $a) { if (!isset($artefactcopies[$a]) && !isset($tocopy[$a])) { $tocopy[$a] = artefact_instance_from_id($a); } } // Get embedded file artefacts $embedlists[$d] = $tocopy[$d]->embed_id_list(); foreach ($embedlists[$d] as $a) { if (!isset($artefactcopies[$a]) && !isset($tocopy[$a])) { $tocopy[$a] = artefact_instance_from_id($a); } } } } // Copy all the artefacts we haven't copied yet foreach ($tocopy as $aid => $a) { // Save the id of the original artefact's parent $artefactcopies[$aid] = (object) array('oldid' => $aid, 'oldparent' => $a->get('parent')); if (!empty($attachmentlists[$aid])) { $artefactcopies[$aid]->oldattachments = $attachmentlists[$aid]; } if (!empty($embedlists[$aid])) { $artefactcopies[$aid]->oldembeds = $embedlists[$aid]; } $artefactcopies[$aid]->newid = $a->copy_for_new_owner($view->get('owner'), $view->get('group'), $view->get('institution')); } // Record new artefact ids in the new block if (isset($configdata['artefactid'])) { $configdata['artefactid'] = $artefactcopies[$configdata['artefactid']]->newid; } if (isset($configdata['artefactids'])) { foreach ($configdata['artefactids'] as &$oldid) { $oldid = $artefactcopies[$oldid]->newid; } } } else { $configdata = call_static_method($blocktypeclass, 'rewrite_blockinstance_config', $view, $configdata); } // Rewrite the extra configuration of block $configdata = call_static_method($blocktypeclass, 'rewrite_blockinstance_extra_config', $view, $newblock, $configdata, $artefactcopies); $newblock->set('configdata', $configdata); $newblock->commit(); return true; }