Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 6 | class DMSDocumentAddController extends LeftAndMain |
||
| 7 | { |
||
| 8 | private static $url_segment = 'pages/adddocument'; |
||
|
|
|||
| 9 | private static $url_priority = 60; |
||
| 10 | private static $required_permission_codes = 'CMS_ACCESS_AssetAdmin'; |
||
| 11 | private static $menu_title = 'Edit Page'; |
||
| 12 | private static $tree_class = 'SiteTree'; |
||
| 13 | private static $session_namespace = 'CMSMain'; |
||
| 14 | |||
| 15 | /** |
||
| 16 | * Allowed file upload extensions, will be merged with `$allowed_extensions` from {@link File} |
||
| 17 | * |
||
| 18 | * @config |
||
| 19 | * @var array |
||
| 20 | */ |
||
| 21 | private static $allowed_extensions = array(); |
||
| 22 | |||
| 23 | private static $allowed_actions = array( |
||
| 24 | 'getEditForm', |
||
| 25 | 'documentautocomplete', |
||
| 26 | 'linkdocument', |
||
| 27 | 'documentlist' |
||
| 28 | ); |
||
| 29 | |||
| 30 | /** |
||
| 31 | * Custom currentPage() method to handle opening the 'root' folder |
||
| 32 | * |
||
| 33 | * @return SiteTree |
||
| 34 | */ |
||
| 35 | public function currentPage() |
||
| 36 | { |
||
| 37 | $id = $this->currentPageID(); |
||
| 38 | if ($id === 0) { |
||
| 39 | return SiteTree::singleton(); |
||
| 40 | } |
||
| 41 | return parent::currentPage(); |
||
| 42 | } |
||
| 43 | |||
| 44 | /** |
||
| 45 | * Return fake-ID "root" if no ID is found (needed to upload files into the root-folder). Otherwise the page ID |
||
| 46 | * is passed in from the {@link DMSGridFieldAddNewButton}. |
||
| 47 | * |
||
| 48 | * @return int |
||
| 49 | */ |
||
| 50 | public function currentPageID() |
||
| 51 | { |
||
| 52 | return (int) $this->getRequest()->getVar('page_id'); |
||
| 53 | } |
||
| 54 | |||
| 55 | /** |
||
| 56 | * Get the current document set, if a document set ID was provided |
||
| 57 | * |
||
| 58 | * @return DMSDocumentSet |
||
| 59 | */ |
||
| 60 | public function getCurrentDocumentSet() |
||
| 67 | |||
| 68 | /** |
||
| 69 | * @return Form |
||
| 70 | * @todo what template is used here? AssetAdmin_UploadContent.ss doesn't seem to be used anymore |
||
| 71 | */ |
||
| 72 | public function getEditForm($id = null, $fields = null) |
||
| 73 | { |
||
| 74 | Requirements::javascript(FRAMEWORK_DIR . '/javascript/AssetUploadField.js'); |
||
| 75 | Requirements::css(FRAMEWORK_DIR . '/css/AssetUploadField.css'); |
||
| 76 | Requirements::css(DMS_DIR . '/dist/css/cmsbundle.css'); |
||
| 77 | |||
| 78 | /** @var SiteTree $page */ |
||
| 79 | $page = $this->currentPage(); |
||
| 80 | /** @var DMSDocumentSet $documentSet */ |
||
| 81 | $documentSet = $this->getCurrentDocumentSet(); |
||
| 82 | |||
| 83 | $uploadField = DMSUploadField::create('AssetUploadField', ''); |
||
| 84 | $uploadField->setConfig('previewMaxWidth', 40); |
||
| 85 | $uploadField->setConfig('previewMaxHeight', 30); |
||
| 86 | // Required to avoid Solr reindexing (often used alongside DMS) to |
||
| 87 | // return 503s because of too many concurrent reindex requests |
||
| 88 | $uploadField->setConfig('sequentialUploads', 1); |
||
| 89 | $uploadField->addExtraClass('ss-assetuploadfield'); |
||
| 90 | $uploadField->removeExtraClass('ss-uploadfield'); |
||
| 91 | $uploadField->setTemplate('AssetUploadField'); |
||
| 92 | $uploadField->setRecord($documentSet); |
||
| 93 | |||
| 94 | $uploadField->getValidator()->setAllowedExtensions($this->getAllowedExtensions()); |
||
| 95 | $exts = $uploadField->getValidator()->getAllowedExtensions(); |
||
| 96 | |||
| 97 | asort($exts); |
||
| 98 | $backlink = $this->Backlink(); |
||
| 99 | $done = " |
||
| 100 | <a class=\"ss-ui-button ss-ui-action-constructive cms-panel-link ui-corner-all\" href=\"" . $backlink . "\"> |
||
| 101 | " . _t('UploadField.DONE', 'DONE') . " |
||
| 102 | </a>"; |
||
| 103 | |||
| 104 | $addExistingField = new DMSDocumentAddExistingField( |
||
| 105 | 'AddExisting', |
||
| 106 | _t('DMSDocumentAddExistingField.ADDEXISTING', 'Add Existing') |
||
| 107 | ); |
||
| 108 | $addExistingField->setRecord($documentSet); |
||
| 109 | |||
| 110 | $form = new Form( |
||
| 111 | $this, |
||
| 112 | 'getEditForm', |
||
| 113 | new FieldList( |
||
| 114 | new TabSet( |
||
| 115 | _t('DMSDocumentAddController.MAINTAB', 'Main'), |
||
| 116 | new Tab( |
||
| 117 | _t('UploadField.FROMCOMPUTER', 'From your computer'), |
||
| 118 | $uploadField, |
||
| 119 | new LiteralField( |
||
| 120 | 'AllowedExtensions', |
||
| 121 | sprintf( |
||
| 122 | '<p>%s: %s</p>', |
||
| 123 | _t('AssetAdmin.ALLOWEDEXTS', 'Allowed extensions'), |
||
| 124 | implode('<em>, </em>', $exts) |
||
| 125 | ) |
||
| 126 | ) |
||
| 127 | ), |
||
| 128 | new Tab( |
||
| 129 | _t('UploadField.FROMCMS', 'From the CMS'), |
||
| 130 | $addExistingField |
||
| 131 | ) |
||
| 132 | ) |
||
| 133 | ), |
||
| 134 | new FieldList( |
||
| 135 | new LiteralField('doneButton', $done) |
||
| 136 | ) |
||
| 137 | ); |
||
| 138 | $form->addExtraClass('center cms-edit-form ' . $this->BaseCSSClasses()); |
||
| 139 | $form->Backlink = $backlink; |
||
| 140 | // Don't use AssetAdmin_EditForm, as it assumes a different panel structure |
||
| 141 | $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); |
||
| 142 | $form->Fields()->push(HiddenField::create('ID', false, $documentSet->ID)); |
||
| 143 | $form->Fields()->push(HiddenField::create('DSID', false, $documentSet->ID)); |
||
| 144 | |||
| 145 | return $form; |
||
| 146 | } |
||
| 147 | |||
| 148 | /** |
||
| 149 | * @return ArrayList |
||
| 150 | */ |
||
| 151 | public function Breadcrumbs($unlinked = false) |
||
| 152 | { |
||
| 153 | $items = parent::Breadcrumbs($unlinked); |
||
| 154 | |||
| 155 | // The root element should explicitly point to the root node. |
||
| 156 | $items[0]->Link = Controller::join_links(singleton('CMSPageEditController')->Link('show'), 0); |
||
| 157 | |||
| 158 | // Enforce linkage of hierarchy to AssetAdmin |
||
| 159 | foreach ($items as $item) { |
||
| 160 | $baselink = $this->Link('show'); |
||
| 161 | if (strpos($item->Link, $baselink) !== false) { |
||
| 162 | $item->Link = str_replace($baselink, singleton('CMSPageEditController')->Link('show'), $item->Link); |
||
| 163 | } |
||
| 164 | } |
||
| 165 | |||
| 166 | $items->push(new ArrayData(array( |
||
| 167 | 'Title' => _t('DMSDocumentSet.ADDDOCUMENTBUTTON', 'Add Document'), |
||
| 168 | 'Link' => $this->Link() |
||
| 169 | ))); |
||
| 170 | |||
| 171 | return $items; |
||
| 172 | } |
||
| 173 | |||
| 174 | /** |
||
| 175 | * Returns the link to be used to return the user after uploading a document. Scenarios: |
||
| 176 | * |
||
| 177 | * 1) Page context: page ID and document set ID provided, redirect back to the page and document set |
||
| 178 | * 2) Document set context: no page ID, document set ID provided, redirect back to document set in ModelAdmin |
||
| 179 | * 3) Document context: no page ID and no document set ID provided, redirect back to documents in ModelAdmin |
||
| 180 | * |
||
| 181 | * @return string |
||
| 182 | */ |
||
| 183 | public function Backlink() |
||
| 184 | { |
||
| 185 | if (!$this->getRequest()->getVar('dsid') || !$this->currentPageID()) { |
||
| 186 | $modelAdmin = new DMSDocumentAdmin; |
||
| 187 | $modelAdmin->init(); |
||
| 188 | |||
| 189 | if ($this->getRequest()->getVar('dsid')) { |
||
| 190 | return Controller::join_links( |
||
| 191 | $modelAdmin->Link('DMSDocumentSet'), |
||
| 192 | 'EditForm/field/DMSDocumentSet/item', |
||
| 193 | (int) $this->getRequest()->getVar('dsid'), |
||
| 194 | 'edit' |
||
| 195 | ); |
||
| 196 | } |
||
| 197 | return $modelAdmin->Link(); |
||
| 198 | } |
||
| 199 | |||
| 200 | return $this->getPageEditLink($this->currentPageID(), (int) $this->getRequest()->getVar('dsid')); |
||
| 201 | } |
||
| 202 | |||
| 203 | /** |
||
| 204 | * Return a link to edit a page, deep linking into the document set given |
||
| 205 | * |
||
| 206 | * @param int $pageId |
||
| 207 | * @param int $documentSetId |
||
| 208 | * @return string |
||
| 209 | */ |
||
| 210 | protected function getPageEditLink($pageId, $documentSetId) |
||
| 218 | |||
| 219 | public function documentautocomplete() |
||
| 220 | { |
||
| 221 | $term = (string) $this->getRequest()->getVar('term'); |
||
| 222 | $termSql = Convert::raw2sql($term); |
||
| 223 | $data = DMSDocument::get() |
||
| 224 | ->where( |
||
| 225 | '("ID" LIKE \'%' . $termSql . '%\' OR "Filename" LIKE \'%' . $termSql . '%\'' |
||
| 226 | . ' OR "Title" LIKE \'%' . $termSql . '%\')' |
||
| 227 | ) |
||
| 228 | ->sort('ID ASC') |
||
| 229 | ->limit(20); |
||
| 230 | |||
| 231 | $return = array(); |
||
| 232 | foreach ($data as $doc) { |
||
| 233 | $return[] = array( |
||
| 234 | 'label' => $doc->ID . ' - ' . $doc->Title, |
||
| 235 | 'value' => $doc->ID |
||
| 236 | ); |
||
| 237 | } |
||
| 238 | |||
| 239 | return Convert::raw2json($return); |
||
| 240 | } |
||
| 241 | |||
| 242 | /** |
||
| 243 | * Link an existing document to the given document set ID |
||
| 244 | * @return string JSON |
||
| 245 | */ |
||
| 246 | public function linkdocument() |
||
| 247 | { |
||
| 248 | $return = array('error' => _t('UploadField.FIELDNOTSET', 'Could not add document to page')); |
||
| 249 | $documentSet = $this->getCurrentDocumentSet(); |
||
| 250 | if (!empty($documentSet)) { |
||
| 251 | $document = DMSDocument::get()->byId($this->getRequest()->getVar('documentID')); |
||
| 252 | $documentSet->Documents()->add($document); |
||
| 253 | |||
| 254 | $buttonText = '<button class="ss-uploadfield-item-edit ss-ui-button ui-corner-all"' |
||
| 255 | . ' title="' . _t('DMSDocument.EDITDOCUMENT', 'Edit this document') . '" data-icon="pencil">' |
||
| 256 | . _t('DMSDocument.EDIT', 'Edit') . '<span class="toggle-details">' |
||
| 257 | . '<span class="toggle-details-icon"></span></span></button>'; |
||
| 258 | |||
| 259 | // Collect all output data. |
||
| 260 | $return = array( |
||
| 261 | 'id' => $document->ID, |
||
| 262 | 'name' => $document->getTitle(), |
||
| 263 | 'thumbnail_url' => $document->Icon($document->getExtension()), |
||
| 264 | 'edit_url' => $this->getEditForm()->Fields()->fieldByName('Main.From your computer.AssetUploadField') |
||
| 265 | ->getItemHandler($document->ID)->EditLink(), |
||
| 266 | 'size' => $document->getFileSizeFormatted(), |
||
| 267 | 'buttons' => $buttonText, |
||
| 268 | 'showeditform' => true |
||
| 269 | ); |
||
| 270 | } |
||
| 271 | |||
| 272 | return Convert::raw2json($return); |
||
| 273 | } |
||
| 274 | |||
| 275 | /** |
||
| 276 | * Returns HTML representing a list of documents that are associated with the given page ID, across all document |
||
| 277 | * sets. |
||
| 278 | * |
||
| 279 | * @return string HTML |
||
| 280 | */ |
||
| 281 | public function documentlist() |
||
| 282 | { |
||
| 283 | if (!$this->getRequest()->getVar('pageID')) { |
||
| 284 | return $this->httpError(400); |
||
| 285 | } |
||
| 286 | |||
| 287 | $page = SiteTree::get()->byId($this->getRequest()->getVar('pageID')); |
||
| 288 | |||
| 289 | if ($page && $page->getAllDocuments()->count() > 0) { |
||
| 290 | $list = '<ul>'; |
||
| 291 | |||
| 292 | foreach ($page->getAllDocuments() as $document) { |
||
| 293 | $list .= sprintf( |
||
| 294 | '<li><a class="add-document" data-document-id="%s">%s</a></li>', |
||
| 295 | $document->ID, |
||
| 296 | $document->ID . ' - '. Convert::raw2xml($document->Title) |
||
| 297 | ); |
||
| 298 | } |
||
| 299 | |||
| 300 | $list .= '</ul>'; |
||
| 301 | |||
| 302 | return $list; |
||
| 303 | } |
||
| 304 | |||
| 305 | return sprintf( |
||
| 306 | '<p>%s</p>', |
||
| 307 | _t('DMSDocumentAddController.NODOCUMENTS', 'There are no documents attached to the selected page.') |
||
| 308 | ); |
||
| 309 | } |
||
| 310 | |||
| 311 | /** |
||
| 312 | * Get an array of allowed file upload extensions, merged with {@link File} and extra configuration from this |
||
| 313 | * class |
||
| 314 | * |
||
| 315 | * @return array |
||
| 316 | */ |
||
| 317 | public function getAllowedExtensions() |
||
| 326 | |||
| 327 | /** |
||
| 328 | * Overrides the parent method to allow users with access to DMS admin to access this controller |
||
| 329 | * |
||
| 330 | * @param Member $member |
||
| 331 | * @return bool |
||
| 332 | */ |
||
| 333 | public function canView($member = null) |
||
| 351 | } |
||
| 352 |