Пример #1
0
 /**
  * Compile buttons from the table configuration array and return them as HTML
  *
  * @param InterfaceGeneralModel $objModelRow
  * @param string $strTable
  * @param array $arrRootIds
  * @param boolean $blnCircularReference
  * @param array $arrChildRecordIds
  * @param int $strPrevious
  * @param int $strNext
  * @return string
  */
 protected function generateButtons(InterfaceGeneralModel $objModelRow, $strTable, $arrRootIds = array(), $blnCircularReference = false, $arrChildRecordIds = null, $strPrevious = null, $strNext = null)
 {
     $arrDCA = $this->getDC()->getDCA();
     if (!count($arrDCA['list']['operations'])) {
         return '';
     }
     $return = '';
     foreach ($arrDCA['list']['operations'] as $k => $v) {
         // Check if we have a array
         if (!is_array($v)) {
             $v = array($v);
         }
         // Set basic informations
         $label = strlen($v['label'][0]) ? $v['label'][0] : $k;
         $title = sprintf(strlen($v['label'][1]) ? $v['label'][1] : $k, $objModelRow->getID());
         $attributes = strlen($v['attributes']) ? ' ' . ltrim(sprintf($v['attributes'], $objModelRow->getID(), $objModelRow->getID())) : '';
         // Call a custom function instead of using the default button
         $strButtonCallback = $this->getDC()->getCallbackClass()->buttonCallback($objModelRow, $v, $label, $title, $attributes, $strTable, $arrRootIds, $arrChildRecordIds, $blnCircularReference, $strPrevious, $strNext);
         if (!is_null($strButtonCallback)) {
             $return .= ' ' . trim($strButtonCallback);
             continue;
         }
         // Generate all buttons except "move up" and "move down" buttons
         if ($k != 'move' && $v != 'move') {
             switch ($k) {
                 // Cute needs some special informations
                 case 'cut':
                     // Get dataprovider from current and parent
                     $strCDP = $objModelRow->getProviderName();
                     $strPDP = $objModelRow->getMeta(DCGE::MODEL_PTABLE);
                     $strAdd2Url = "";
                     // Add url + id + currentDataProvider
                     $strAdd2Url .= $v['href'] . '&cdp=' . $strCDP;
                     // Add parent provider if exsists
                     if ($strPDP != null) {
                         $strPDP = $strPDP;
                         $strAdd2Url .= '&pdp=' . $strPDP;
                     }
                     // If we have a id add it, used for mode 4 and all parent -> current views
                     if (strlen($this->Input->get('id')) != 0) {
                         $strAdd2Url .= '&id=' . $this->Input->get('id');
                     }
                     // Source is the id of the element which should move
                     $strAdd2Url .= '&source=' . $objModelRow->getID();
                     // Build whole button mark up
                     $return .= ' <a href="' . $this->addToUrl($strAdd2Url) . '" title="' . specialchars($title) . '"' . $attributes . '>' . $this->generateImage($v['icon'], $label) . '</a>';
                     break;
                 default:
                     $idParam = $v['idparam'] ? 'id=&amp;' . $v['idparam'] : 'id';
                     $strUrl = $this->addToUrl($v['href'] . '&amp;' . $idParam . '=' . $objModelRow->getID());
                     $return .= ' <a href="' . $strUrl . '" title="' . specialchars($title) . '"' . $attributes . '>' . $this->generateImage($v['icon'], $label) . '</a>';
                     break;
             }
             continue;
         }
         $arrRootIds = is_array($arrRootIds) ? $arrRootIds : array($arrRootIds);
         foreach (array('up', 'down') as $dir) {
             $label = strlen($GLOBALS['TL_LANG'][$strTable][$dir][0]) ? $GLOBALS['TL_LANG'][$strTable][$dir][0] : $dir;
             $title = strlen($GLOBALS['TL_LANG'][$strTable][$dir][1]) ? $GLOBALS['TL_LANG'][$strTable][$dir][1] : $dir;
             $label = $this->generateImage($dir . '.gif', $label);
             $href = strlen($v['href']) ? $v['href'] : '&amp;act=move';
             if ($dir == 'up') {
                 $return .= (is_numeric($strPrevious) && (!in_array($objModelRow->getID(), $arrRootIds) || !count($GLOBALS['TL_DCA'][$strTable]['list']['sorting']['root'])) ? ' <a href="' . $this->addToUrl($href . '&amp;id=' . $objModelRow->getID()) . '&amp;sid=' . intval($strPrevious) . '" title="' . specialchars($title) . '"' . $attributes . '>' . $label . '</a> ' : $this->generateImage('up_.gif')) . ' ';
                 continue;
             }
             $return .= (is_numeric($strNext) && (!in_array($objModelRow->getID(), $arrRootIds) || !count($GLOBALS['TL_DCA'][$strTable]['list']['sorting']['root'])) ? ' <a href="' . $this->addToUrl($href . '&amp;id=' . $objModelRow->getID()) . '&amp;sid=' . intval($strNext) . '" title="' . specialchars($title) . '"' . $attributes . '>' . $label . '</a> ' : $this->generateImage('down_.gif')) . ' ';
         }
     }
     // Add paste into/after icons
     if ($this->getDC()->isClipboard()) {
         $arrClipboard = $this->getDC()->getClipboard();
         // Check if the id is in the ignore list
         if ($arrClipboard['mode'] == 'cut' && in_array($objModelRow->getID(), $arrClipboard['ignoredIDs'])) {
             switch ($this->getDC()->arrDCA['list']['sorting']['mode']) {
                 default:
                 case 4:
                     $return .= ' ';
                     $return .= $imagePasteAfter = $this->generateImage('pasteafter_.gif', $GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteafter'][0], 'class="blink"');
                     break;
                 case 5:
                     $return .= ' ';
                     $return .= $imagePasteAfter = $this->generateImage('pasteafter_.gif', $GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteafter'][0], 'class="blink"');
                     $return .= ' ';
                     $return .= $imagePasteInto = $this->generateImage('pasteinto_.gif', $GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteinto'][0], 'class="blink"');
                     break;
             }
         } else {
             //                $strAdd2Url = "";
             //                $strAdd2Url .= 'act=' . $arrClipboard['mode'];
             //                $strAdd2Url .= 'act=' . $arrClipboard['mode'];
             //
             // Switch mode
             // Add ext. information
             $strAdd2UrlAfter = 'act=' . $arrClipboard['mode'] . '&amp;mode=1&amp;pid=' . $arrClipboard['id'] . '&amp;after=' . $objModelRow->getID() . '&amp;source=' . $arrClipboard['source'] . '&amp;childs=' . $arrClipboard['childs'];
             $strAdd2UrlInto = 'act=' . $arrClipboard['mode'] . '&amp;mode=2&amp;pid=' . $arrClipboard['id'] . '&amp;after=' . $objModelRow->getID() . '&amp;source=' . $arrClipboard['source'] . '&amp;childs=' . $arrClipboard['childs'];
             if ($arrClipboard['pdp'] != '') {
                 $strAdd2UrlAfter .= '&amp;pdp=' . $arrClipboard['pdp'];
                 $strAdd2UrlInto .= '&amp;pdp=' . $arrClipboard['pdp'];
             }
             if ($arrClipboard['cdp'] != '') {
                 $strAdd2UrlAfter .= '&amp;cdp=' . $arrClipboard['cdp'];
                 $strAdd2UrlInto .= '&amp;cdp=' . $arrClipboard['cdp'];
             }
             switch ($this->getDC()->arrDCA['list']['sorting']['mode']) {
                 default:
                 case 4:
                     $imagePasteAfter = $this->generateImage('pasteafter.gif', $GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteafter'][0], 'class="blink"');
                     $strPasteBtt = ' <a href="' . $this->addToUrl($strAdd2UrlAfter) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteafter'][0]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a> ';
                     // Callback for paste btt
                     $strButtonCallback = $this->getDC()->getCallbackClass()->pasteButtonCallback($this->objDC, $objModelRow->getPropertiesAsArray(), $strTable, false, $arrClipboard, null, null);
                     if ($strButtonCallback === false) {
                         $return .= $strPasteBtt;
                     } else {
                         $return .= $strButtonCallback;
                     }
                     break;
                 case 5:
                     // Btn paste after.
                     $imagePasteAfter = $this->generateImage('pasteafter.gif', $GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteafter'][0], 'class="blink"');
                     $strPasteBtt = ' <a href="' . $this->addToUrl($strAdd2UrlAfter) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteafter'][0]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteAfter . '</a> ';
                     // Btn paste into.
                     $imagePasteInto = $this->generateImage('pasteinto.gif', $GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteinto'][0], 'class="blink"');
                     $strPasteBtt .= ' <a href="' . $this->addToUrl($strAdd2UrlInto) . '" title="' . specialchars($GLOBALS['TL_LANG'][$this->getDC()->getTable()]['pasteinto'][0]) . '" onclick="Backend.getScrollOffset()">' . $imagePasteInto . '</a> ';
                     // Callback for paste btn.
                     $strButtonCallback = $this->getDC()->getCallbackClass()->pasteButtonCallback($this->objDC, $objModelRow->getPropertiesAsArray(), $strTable, false, $arrClipboard, null, null);
                     if ($strButtonCallback === false) {
                         $return .= $strPasteBtt;
                     } else {
                         $return .= $strButtonCallback;
                     }
                     break;
             }
         }
     }
     return trim($return);
 }
Пример #2
0
 /**
  * Parse|Check|Validate each field and save it.
  *
  * @param string $strField Name of current field
  * @return void
  */
 public function processInput($strField)
 {
     if (in_array($strField, $this->arrProcessedNames)) {
         return $this->arrProcessed[$strField];
     }
     $this->arrProcessedNames[] = $strField;
     $strInputName = $strField . '_' . $this->mixWidgetID;
     // Return if no submit, field is not editable or not in input
     if (!($this->blnSubmitted && isset($this->arrInputs[$strInputName]) && $this->isEditableField($strField) && !(isset($this->arrDCA['fields'][$strField]['eval']['readonly']) && $this->arrDCA['fields'][$strField]['eval']['readonly']))) {
         return $this->arrProcessed[$strField] = null;
     }
     // Build widget
     $objWidget = $this->getWidget($strField);
     if (!$objWidget instanceof Widget) {
         return $this->arrProcessed[$strField] = null;
     }
     // Validate
     $objWidget->validate();
     if (Input::getInstance()->post('SUBMIT_TYPE') == 'auto') {
         // HACK: we would need a Widget::clearErrors() here but something like this does not exist, hence we have a class that does this for us.
         WidgetAccessor::resetErrors($objWidget);
     }
     // Check
     if ($objWidget->hasErrors()) {
         $this->blnNoReload = true;
         return $this->arrProcessed[$strField] = null;
     }
     if (!$objWidget->submitInput()) {
         return $this->arrProcessed[$strField] = $this->objCurrentModel->getProperty($strField);
     }
     // Get value and config
     $varNew = $objWidget->value;
     $arrConfig = $this->getFieldDefinition($strField);
     // If array sort
     if (is_array($varNew)) {
         ksort($varNew);
     } else {
         if ($varNew != '' && isset(self::$arrDates[$arrConfig['eval']['rgxp']])) {
             // OH: this should be a widget feature
             $objDate = new Date($varNew, $GLOBALS['TL_CONFIG'][$arrConfig['eval']['rgxp'] . 'Format']);
             $varNew = $objDate->tstamp;
         }
     }
     $this->import('Input');
     //Handle multi-select fields in "override all" mode
     // OH: this should be a widget feature
     if (($arrConfig['inputType'] == 'checkbox' || $arrConfig['inputType'] == 'checkboxWizard') && $arrConfig['eval']['multiple'] && $this->Input->get('act') == 'overrideAll') {
         if ($arrNew == null || !is_array($arrNew)) {
             $arrNew = array();
         }
         // FIXME: this will NOT work, as it still uses activeRecord - otoh, what is this intended for? wizards?
         switch ($this->Input->post($objWidget->name . '_update')) {
             case 'add':
                 $varNew = array_values(array_unique(array_merge(deserialize($this->objActiveRecord->{$strField}, true), $arrNew)));
                 break;
             case 'remove':
                 $varNew = array_values(array_diff(deserialize($this->objActiveRecord->{$strField}, true), $arrNew));
                 break;
             case 'replace':
                 $varNew = $arrNew;
                 break;
         }
         if (!$varNew) {
             $varNew = '';
         }
     }
     // Call the save callbacks
     try {
         $varNew = $this->objCallbackClass->saveCallback($arrConfig, $varNew);
     } catch (Exception $e) {
         $this->blnNoReload = true;
         $objWidget->addError($e->getMessage());
         return $this->arrProcessed[$strField] = null;
     }
     // Check on value empty
     if ($varNew == '' && $arrConfig['eval']['doNotSaveEmpty']) {
         $this->blnNoReload = true;
         $objWidget->addError($GLOBALS['TL_LANG']['ERR']['mdtryNoLabel']);
         return $this->arrProcessed[$strField] = null;
     }
     if ($varNew != '') {
         if ($arrConfig['eval']['encrypt']) {
             $varNew = $this->Encryption->encrypt(is_array($varNew) ? serialize($varNew) : $varNew);
         } else {
             if ($arrConfig['eval']['unique'] && !$this->getDataProvider($this->objCurrentModel->getProviderName())->isUniqueValue($strField, $varNew, $this->objCurrentModel->getID())) {
                 $this->blnNoReload = true;
                 $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $objWidget->label));
                 return $this->arrProcessed[$strField] = null;
             } else {
                 if ($arrConfig['eval']['fallback']) {
                     $this->getDataProvider($this->objCurrentModel->getProviderName())->resetFallback($strField);
                 }
             }
         }
     }
     $this->arrProcessed[$strField] = $varNew;
     return $varNew;
 }
Пример #3
0
 /**
  * Save a new version of a row.
  *
  * @param InterfaceGeneralModel $objModel    The model for which a new version shall be created.
  *
  * @param string                $strUsername The username to attach to the version as creator.
  *
  * @return void
  */
 public function saveVersion(InterfaceGeneralModel $objModel, $strUsername)
 {
     $objCount = $this->objDatabase->prepare("SELECT count(*) as mycount FROM tl_version WHERE pid=? AND fromTable = ?")->execute($objModel->getID(), $this->strSource);
     $mixNewVersion = intval($objCount->mycount) + 1;
     $mixData = $objModel->getPropertiesAsArray();
     $mixData["id"] = $objModel->getID();
     $mixData = serialize($mixData);
     $arrInsert = array();
     $arrInsert['pid'] = $objModel->getID();
     $arrInsert['tstamp'] = time();
     $arrInsert['version'] = $mixNewVersion;
     $arrInsert['fromTable'] = $this->strSource;
     $arrInsert['username'] = $strUsername;
     $arrInsert['data'] = $mixData;
     $this->objDatabase->prepare('INSERT INTO tl_version %s')->set($arrInsert)->execute();
     $this->setVersionActive($objModel->getID(), $mixNewVersion);
 }
 /**
  * Save a model to the database.
  *
  * In general, this method fetches the solely property "rows" from the model and updates the local table against
  * these contents.
  *
  * The parent id (id of the model) will get checked and reflected also for new items.
  *
  * When rows with duplicate ids are encountered (like from MCW for example), the dupes are inserted as new rows.
  *
  * @param InterfaceGeneralModel $objItem   The model to save.
  *
  * @param bool                  $recursive Ignored as not relevant in this data provider.
  *
  * @return InterfaceGeneralModel The passed Model.
  *
  * @throws Exception When the passed model does not contain a property named "rows", an Exception is thrown.
  */
 public function save(InterfaceGeneralModel $objItem, $recursive = false)
 {
     $arrData = $objItem->getProperty('rows');
     if (!($objItem->getID() && $arrData)) {
         throw new Exception('invalid input data in model.', 1);
     }
     $arrKeep = array();
     foreach ($arrData as $i => $arrRow) {
         // TODO: add an option to restrict this to some allowed fields?
         $arrSQL = $arrRow;
         // update all.
         $intId = intval($arrRow['id']);
         // Work around the fact that multicolumnwizard does not clear any hidden fields when copying a dataset.
         // therefore we do consider any dupe as new dataset and save it accordingly.
         if (in_array($intId, $arrKeep)) {
             $intId = 0;
             unset($arrSQL['id']);
         }
         if ($intId > 0) {
             $this->objDatabase->prepare(sprintf('UPDATE tl_metamodel_dca_combine %%s WHERE id=? AND %s=?', $this->strGroupCol))->set($arrSQL)->execute($intId, $objItem->getId());
             $arrKeep[] = $intId;
         } else {
             // force group col value:
             $arrSQL[$this->strGroupCol] = $objItem->getId();
             $arrKeep[] = $this->objDatabase->prepare('INSERT INTO tl_metamodel_dca_combine %s')->set($arrSQL)->execute()->insertId;
         }
     }
     // house keeping, kill the rest.
     $this->objDatabase->prepare(sprintf('DELETE FROM  tl_metamodel_dca_combine WHERE %s=? AND id NOT IN (%s)', $this->strGroupCol, implode(',', $arrKeep)))->execute($objItem->getId());
     return $objItem;
 }