Exemplo n.º 1
0
 /**
  * Split a string into a clean array of keywords
  * @param $text string
  * @param $allowWildcards boolean
  * @return array of keywords
  */
 static function filterKeywords($text, $allowWildcards = false)
 {
     $minLength = Config::getVar('search', 'min_word_length');
     $stopwords = self::_loadStopwords();
     // Join multiple lines into a single string
     if (is_array($text)) {
         $text = join("\n", $text);
     }
     $cleanText = Core::cleanVar($text);
     // Remove punctuation
     $cleanText = String::regexp_replace('/[!"\\#\\$%\'\\(\\)\\.\\?@\\[\\]\\^`\\{\\}~]/', '', $cleanText);
     $cleanText = String::regexp_replace('/[\\+,:;&\\/<=>\\|\\\\]/', ' ', $cleanText);
     $cleanText = String::regexp_replace('/[\\*]/', $allowWildcards ? '%' : ' ', $cleanText);
     $cleanText = String::strtolower($cleanText);
     // Split into words
     $words = String::regexp_split('/\\s+/', $cleanText);
     // FIXME Do not perform further filtering for some fields, e.g., author names?
     // Remove stopwords
     $keywords = array();
     foreach ($words as $k) {
         if (!isset($stopwords[$k]) && String::strlen($k) >= $minLength && !is_numeric($k)) {
             $keywords[] = String::substr($k, 0, SEARCH_KEYWORD_MAX_LENGTH);
         }
     }
     return $keywords;
 }
Exemplo n.º 2
0
 function displayPaymentForm($queuedPaymentId, &$queuedPayment)
 {
     if (!$this->isConfigured()) {
         return false;
     }
     $schedConf =& Request::getSchedConf();
     $user =& Request::getUser();
     $params = array('business' => $this->getSetting($schedConf->getConferenceId(), $schedConf->getId(), 'selleraccount'), 'item_name' => $queuedPayment->getDescription(), 'amount' => $queuedPayment->getAmount(), 'quantity' => 1, 'no_note' => 1, 'no_shipping' => 1, 'currency_code' => $queuedPayment->getCurrencyCode(), 'lc' => String::substr(Locale::getLocale(), 3), 'custom' => $queuedPaymentId, 'notify_url' => Request::url(null, null, 'payment', 'plugin', array($this->getName(), 'ipn')), 'return' => $queuedPayment->getRequestUrl(), 'cancel_return' => Request::url(null, null, 'payment', 'plugin', array($this->getName(), 'cancel')), 'first_name' => $user ? $user->getFirstName() : '', 'last_name' => $user ? $user->getLastname() : '', 'item_number' => 1, 'cmd' => '_xclick');
     $templateMgr =& TemplateManager::getManager();
     switch ($queuedPayment->getType()) {
         case QUEUED_PAYMENT_TYPE_REGISTRATION:
             // Provide registration-specific details to template.
             $registrationDao =& DAORegistry::getDAO('RegistrationDAO');
             $registrationOptionDao =& DAORegistry::getDAO('RegistrationOptionDAO');
             $registrationTypeDao =& DAORegistry::getDAO('RegistrationTypeDAO');
             $registration =& $registrationDao->getRegistration($queuedPayment->getAssocId());
             if (!$registration || $registration->getUserId() != $queuedPayment->getUserId() || $registration->getSchedConfId() != $queuedPayment->getSchedConfId()) {
                 break;
             }
             $registrationOptionIterator =& $registrationOptionDao->getRegistrationOptionsBySchedConfId($schedConf->getId());
             $registrationOptionCosts = $registrationTypeDao->getRegistrationOptionCosts($registration->getTypeId());
             $registrationOptionIds = $registrationOptionDao->getRegistrationOptions($registration->getRegistrationId());
             $templateMgr->assign('registration', $registration);
             $templateMgr->assign('registrationType', $registrationTypeDao->getRegistrationType($registration->getTypeId()));
             $templateMgr->assign('registrationOptions', $registrationOptionIterator->toArray());
             $templateMgr->assign('registrationOptionCosts', $registrationOptionCosts);
             $templateMgr->assign('registrationOptionIds', $registrationOptionIds);
     }
     $templateMgr->assign('params', $params);
     $templateMgr->assign('paypalFormUrl', $this->getSetting($schedConf->getConferenceId(), $schedConf->getId(), 'paypalurl'));
     $templateMgr->display($this->getTemplatePath() . 'paymentForm.tpl');
 }
Exemplo n.º 3
0
 function generateImage(&$captcha)
 {
     $width = $this->getWidth();
     $height = $this->getHeight();
     $length = String::strlen($captcha->getValue());
     $value = $captcha->getValue();
     $image = imagecreatetruecolor($width, $height);
     $fg = imagecolorallocate($image, rand(128, 255), rand(128, 255), rand(128, 255));
     $bg = imagecolorallocate($image, rand(0, 64), rand(0, 64), rand(0, 64));
     imagefill($image, $width / 2, $height / 2, $bg);
     $xStart = rand($width / 12, $width / 3);
     $xEnd = rand($width * 2 / 3, $width * 11 / 12);
     for ($i = 0; $i < $length; $i++) {
         imagefttext($image, rand(20, 34), rand(-15, 15), $xStart + ($xEnd - $xStart) * $i / $length + rand(-5, 5), rand(40, 60), $fg, Config::getVar('captcha', 'font_location'), String::substr($value, $i, 1));
     }
     // Add some noise to the image.
     for ($i = 0; $i < 20; $i++) {
         $color = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
         for ($j = 0; $j < 20; $j++) {
             imagesetpixel($image, rand(0, $this->getWidth()), rand(0, $this->getHeight()), $color);
         }
     }
     header('Content-type: ' . $this->getMimeType());
     imagepng($image);
     imagedestroy($image);
 }
Exemplo n.º 4
0
 /**
  * Generate a filename for a library file.
  * @param $type int LIBRARY_FILE_TYPE_...
  * @param $originalFileName string
  * @return string
  */
 function generateFileName($type, $originalFileName)
 {
     $libraryFileDao =& DAORegistry::getDAO('LibraryFileDAO');
     $suffix = $this->getFileSuffixFromType($type);
     $ext = $this->getExtension($originalFileName);
     $truncated = $this->truncateFileName($originalFileName, 127 - String::strlen($suffix) - 1);
     $baseName = String::substr($truncated, 0, String::strpos($originalFileName, $ext) - 1);
     // Try a simple syntax first
     $fileName = $baseName . '-' . $suffix . '.' . $ext;
     if (!$libraryFileDao->filenameExists($this->pressId, $fileName)) {
         return $fileName;
     }
     for ($i = 1;; $i++) {
         $fullSuffix = $suffix . '-' . $i;
         //truncate more if necessary
         $truncated = $this->truncateFileName($originalFileName, 127 - String::strlen($fullSuffix) - 1);
         // get the base name and append the suffix
         $baseName = String::substr($truncated, 0, String::strpos($originalFileName, $ext) - 1);
         //try the following
         $fileName = $baseName . '-' . $fullSuffix . '.' . $ext;
         if (!$libraryFileDao->filenameExists($this->pressId, $fileName)) {
             return $fileName;
         }
     }
 }
 /**
  * Initialize form data.
  */
 function initData()
 {
     $PagSeguroPlugin =& $this->PagSeguroPlugin;
     $user =& Request::getUser();
     $userId = $user ? $user->getUserId() : null;
     $queuedPayment =& $this->queuedPayment;
     $this->_data = array('email_cobranca' => '*****@*****.**', 'item_name' => $queuedPayment->getDescription(), 'a3' => $queuedPayment->getAmount($args), 'quantity' => 1, 'no_note' => 1, 'no_shipping' => 1, 'currency_code' => $queuedPayment->getCurrencyCode(), 'lc' => String::substr(Locale::getLocale(), 3), 'custom' => $this->key, 'notify_url' => Request::url(null, null, 'payment', 'ipn', array($queuedPayment->getQueuedPaymentId())), 'return' => Request::url(null, null, 'payment', 'return', array($queuedPayment->getQueuedPaymentId())), 'cancel_return' => Request::url(null, null, 'payment', 'cancel', array($queuedPayment->getQueuedPaymentId())), 'first_name' => $user ? $user->getFirstName() : '', 'last_name' => $user ? $user->getLastname() : '', 'city' => '', 'zip' => '', 'item_number' => 1);
 }
Exemplo n.º 6
0
 private function filtreTitre($ligneSummary)
 {
     $title = String::substr($ligneSummary, "- ", "\\");
     $new = " " . substr($title, strrpos($title, "/") + 1);
     $titreFinal = str_replace($title, $new, $ligneSummary);
     $posFin = strpos($titreFinal, "\\");
     $posFin = $posFin !== false ? $posFin : strlen($titreFinal);
     $titreFinal = substr($titreFinal, 0, $posFin);
     return $titreFinal;
 }
 /**
  * Extracts variables for a given column from a data element
  * so that they may be assigned to template before rendering.
  * @param $element mixed
  * @param $columnId string
  * @return array
  */
 function getTemplateVarsFromRowColumn(&$row, $column)
 {
     $element =& $row->getData();
     $columnId = $column->getId();
     assert(is_a($element, 'DataObject') && !empty($columnId));
     switch ($columnId) {
         case 'titles':
             $label = String::substr($element->getLocalizedQuestion(), 0, 20);
             return array('label' => $label);
     }
 }
Exemplo n.º 8
0
 /**
  * Hook callback function for TemplateManager::display
  * @param $hookName string
  * @param $args array
  * @return boolean
  */
 function callback($hookName, $args)
 {
     $request =& Registry::get('request');
     $templateManager =& $args[0];
     $allLocales = AppLocale::getAllLocales();
     $localeList = array();
     foreach ($allLocales as $key => $locale) {
         $localeList[] = String::substr($key, 0, 2);
     }
     $templateManager->assign('additionalHeadData', $templateManager->get_template_vars('additionalHeadData') . $templateManager->fetch($this->getTemplatePath() . 'header.tpl'));
     return false;
 }
Exemplo n.º 9
0
 function displayPaymentForm($queuedPaymentId, &$queuedPayment)
 {
     if (!$this->isConfigured()) {
         return false;
     }
     $schedConf =& Request::getSchedConf();
     $user =& Request::getUser();
     $params = array('charset' => Config::getVar('i18n', 'client_charset'), 'business' => $this->getSetting($schedConf->getConferenceId(), $schedConf->getId(), 'selleraccount'), 'item_name' => $queuedPayment->getDescription(), 'amount' => $queuedPayment->getAmount(), 'quantity' => 1, 'no_note' => 1, 'no_shipping' => 1, 'currency_code' => $queuedPayment->getCurrencyCode(), 'lc' => String::substr(AppLocale::getLocale(), 3), 'custom' => $queuedPaymentId, 'notify_url' => Request::url(null, null, 'payment', 'plugin', array($this->getName(), 'ipn')), 'return' => $queuedPayment->getRequestUrl(), 'cancel_return' => Request::url(null, null, 'payment', 'plugin', array($this->getName(), 'cancel')), 'first_name' => $user ? $user->getFirstName() : '', 'last_name' => $user ? $user->getLastname() : '', 'item_number' => 1, 'cmd' => '_xclick');
     $templateMgr =& TemplateManager::getManager();
     $templateMgr->assign('params', $params);
     $templateMgr->assign('paypalFormUrl', $this->getSetting($schedConf->getConferenceId(), $schedConf->getId(), 'paypalurl'));
     $templateMgr->display($this->getTemplatePath() . 'paymentForm.tpl');
 }
Exemplo n.º 10
0
 /**
  * Parse an item and return it as string
  * @param object
  * @param string
  * @param integer
  * @return string
  */
 protected function parseRecipe($objRecipe, $strClass = '', $intCount = 0)
 {
     global $objPage;
     $objTemplate = new \FrontendTemplate($this->item_template);
     $objTemplate->setData($objRecipe->row());
     $objTemplate->class = ($objRecipe->cssClass != '' ? ' ' . $objRecipe->cssClass : '') . $strClass;
     // $objTemplate->distance = $this->getCurrentOpenStatus($objRecipe);
     //Detail-Url
     if ($this->jumpTo) {
         $objDetailPage = \PageModel::findByPk($this->jumpTo);
         $objTemplate->detailUrl = ampersand($this->generateFrontendUrl($objDetailPage->row(), '/' . $objRecipe->alias));
         $objTemplate->teaser = \String::substr($objRecipe->preparation, 100);
     }
     return $objTemplate->parse();
 }
Exemplo n.º 11
0
    /**
     * Hook callback function for TemplateManager::display
     * @param $hookName string
     * @param $args array
     * @return boolean
     */
    function callback($hookName, $args)
    {
        $templateManager =& $args[0];
        $request =& $this->getRequest();
        $page = $request->getRequestedPage();
        $op = $request->getRequestedOp();
        $baseUrl = $templateManager->get_template_vars('baseUrl');
        $additionalHeadData = $templateManager->get_template_vars('additionalHeadData');
        $allLocales = AppLocale::getAllLocales();
        $localeList = array();
        foreach ($allLocales as $key => $locale) {
            $localeList[] = String::substr($key, 0, 2);
        }
        $tinymceScript = '
		<script language="javascript" type="text/javascript" src="' . $baseUrl . '/' . TINYMCE_JS_PATH . '/tiny_mce_gzip.js"></script>
		<script language="javascript" type="text/javascript">
			tinyMCE_GZ.init({
				relative_urls : "false",
				plugins : "paste,jbimages,fullscreen",
				themes : "advanced",
				languages : "' . join(',', $localeList) . '",
				disk_cache : true
			});
		</script>
		<script language="javascript" type="text/javascript">
			tinyMCE.init({
				entity_encoding : "raw",
				plugins : "paste,jbimages,fullscreen",
				mode: "specific_textareas",
				editor_selector: "richContent",
				language : "' . String::substr(AppLocale::getLocale(), 0, 2) . '",
				relative_urls : false,
				forced_root_block : false,
				apply_source_formatting : false,
				theme : "advanced",
				theme_advanced_buttons1 : "cut,copy,paste,pastetext,pasteword,|,bold,italic,underline,bullist,numlist,|,link,unlink,help,code,fullscreen,jbimages",
				theme_advanced_buttons2 : "",
				theme_advanced_buttons3 : ""
			});
		</script>';
        $templateManager->assign('additionalHeadData', $additionalHeadData . "\n" . $tinymceScript);
        return false;
    }
Exemplo n.º 12
0
 private function getAllVarsFromURL()
 {
     if (!empty($_GET['url'])) {
         $vars = explode('/', $_GET['url']);
         $args = array(0 => 'controller', 1 => 'action', 2 => 'id');
         $i = 0;
         foreach ($vars as $var) {
             if (!empty($var)) {
                 if ($i < count($args) && !strpos($var, ':')) {
                     $this->vars[$args[$i]] = $var;
                 } else {
                     $key = String::strstr($var, ':', true);
                     $value = String::substr(String::strstr($var, ':'), 1);
                     if (!empty($key) && !empty($value)) {
                         $this->vars[$key] = $value;
                     }
                 }
                 ++$i;
             }
         }
     }
 }
Exemplo n.º 13
0
 /**
  * Truncate a filename to fit in the specified length.
  */
 function truncateFileName($fileName, $length = 127)
 {
     if (String::strlen($fileName) <= $length) {
         return $fileName;
     }
     $ext = $this->getExtension($fileName);
     $truncated = String::substr($fileName, 0, $length - 1 - String::strlen($ext)) . '.' . $ext;
     return String::substr($truncated, 0, $length);
 }
Exemplo n.º 14
0
    /**
     * Hook callback function for TemplateManager::display
     * @param $hookName string
     * @param $args array
     * @return boolean
     */
    function callback($hookName, $args)
    {
        $templateManager =& $args[0];
        $page = Request::getRequestedPage();
        $op = Request::getRequestedOp();
        $enableFields = $this->getEnableFields($templateManager, $page, $op);
        if (!empty($enableFields)) {
            $baseUrl = $templateManager->get_template_vars('baseUrl');
            $additionalHeadData = $templateManager->get_template_vars('additionalHeadData');
            $enableFields = join(',', $enableFields);
            $allLocales = Locale::getAllLocales();
            $localeList = array();
            foreach ($allLocales as $key => $locale) {
                $localeList[] = String::substr($key, 0, 2);
            }
            $tinymceScript = '
			<script language="javascript" type="text/javascript" src="' . $baseUrl . '/' . TINYMCE_JS_PATH . '/tiny_mce_gzip.js"></script>
			<script language="javascript" type="text/javascript">
				tinyMCE_GZ.init({
					relative_urls : "false",
					plugins : "paste",
					themes : "advanced",
					languages : "' . join(',', $localeList) . '",
					disk_cache : true
				});
			</script>
			<script language="javascript" type="text/javascript">
				tinyMCE.init({
					plugins : "paste",
					mode : "exact",
					language : "' . String::substr(Locale::getLocale(), 0, 2) . '",
					elements : "' . $enableFields . '",
					relative_urls : false,
					forced_root_block : false,
					apply_source_formatting : false,
					theme : "advanced",
					theme_advanced_buttons1 : "pasteword,bold,italic,underline,bullist,numlist,link,unlink,help,code",
					theme_advanced_buttons2 : "",
					theme_advanced_buttons3 : ""
				});
			</script>';
            $templateManager->assign('additionalHeadData', $additionalHeadData . "\n" . $tinymceScript);
        }
        return false;
    }
 public function getAllArticles()
 {
     $arrPids = array();
     $arrAlias = array();
     if (!$this->User->isAdmin) {
         foreach ($this->User->pagemounts as $id) {
             $arrPids[] = $id;
             $arrPids = array_merge($arrPids, $this->Database->getChildRecords($id, 'tl_page'));
         }
         if (empty($arrPids)) {
             return $arrAlias;
         }
         $objAlias = $this->Database->prepare("SELECT c.id, c.pid, c.type, (CASE c.type WHEN 'module' THEN m.name WHEN 'form' THEN f.title WHEN 'table' THEN c.summary ELSE c.headline END) AS headline, c.text, a.title FROM tl_content c LEFT JOIN tl_article a ON a.id=c.pid LEFT JOIN tl_module m ON m.id=c.module LEFT JOIN tl_form f on f.id=c.form WHERE a.pid IN(" . implode(',', array_map('intval', array_unique($arrPids))) . ") AND (c.ptable='tl_article' OR c.ptable='') AND c.id!=? ORDER BY a.title, c.sorting")->execute($this->Input->get('id'));
     } else {
         $objAlias = $this->Database->prepare("SELECT c.id, c.pid, c.type, (CASE c.type WHEN 'module' THEN m.name WHEN 'form' THEN f.title WHEN 'table' THEN c.summary ELSE c.headline END) AS headline, c.text, a.title FROM tl_content c LEFT JOIN tl_article a ON a.id=c.pid LEFT JOIN tl_module m ON m.id=c.module LEFT JOIN tl_form f on f.id=c.form WHERE (c.ptable='tl_article' OR c.ptable='') AND c.id!=? ORDER BY a.title, c.sorting")->execute($this->Input->get('id'));
     }
     while ($objAlias->next()) {
         $arrHeadline = deserialize($objAlias->headline, true);
         if (isset($arrHeadline['value'])) {
             $headline = \String::substr($arrHeadline['value'], 32);
         } else {
             $headline = \String::substr(preg_replace('/[\\n\\r\\t]+/', ' ', $arrHeadline[0]), 32);
         }
         $text = \String::substr(strip_tags(preg_replace('/[\\n\\r\\t]+/', ' ', $objAlias->text)), 32);
         $strText = $GLOBALS['TL_LANG']['CTE'][$objAlias->type][0] . ' (';
         if ($headline != '') {
             $strText .= $headline . ', ';
         } elseif ($text != '') {
             $strText .= $text . ', ';
         }
         $key = $objAlias->title . ' (ID ' . $objAlias->pid . ')';
         $arrAlias[$key][$objAlias->id] = $strText . 'ID ' . $objAlias->id . ')';
     }
     return $arrAlias;
 }
 /**
  * Set the submission data from the form.
  * @param $submission Submission
  */
 function setSubmissionData($submission)
 {
     $this->submission->setLanguage(String::substr($this->submission->getLocale(), 0, 2));
     $this->submission->setCommentsToEditor($this->getData('commentsToEditor'));
     $this->submission->setLocale($this->getData('locale'));
 }
Exemplo n.º 17
0
 /**
  * Calculate the differences between two strings and
  * produce an array with three types of entries: added
  * substrings, deleted substrings and unchanged substrings.
  *
  * The calculation is optimized to identify the common
  * largest substring.
  *
  * The return value is an array of the following format:
  *
  * array(
  *   array( diff-type => substring ),
  *   array(...)
  * )
  *
  * whereby diff-type can be one of:
  *   -1 = deletion
  *    0 = common substring
  *    1 = addition
  *
  * @param $originalString string
  * @param $editedString string
  * @return array
  */
 static function diff($originalString, $editedString)
 {
     // Split strings into character arrays (multi-byte compatible).
     foreach (array('originalStringCharacters' => $originalString, 'editedStringCharacters' => $editedString) as $characterArrayName => $string) {
         ${$characterArrayName} = array();
         String::regexp_match_all('/./', $string, ${$characterArrayName});
         if (isset(${$characterArrayName}[0])) {
             ${$characterArrayName} = ${$characterArrayName}[0];
         }
     }
     // Determine the length of the strings.
     $originalStringLength = count($originalStringCharacters);
     $editedStringLength = count($editedStringCharacters);
     // Is there anything to compare?
     if ($originalStringLength == 0 && $editedStringLength == 0) {
         return array();
     }
     // Is the original string empty?
     if ($originalStringLength == 0) {
         // Return the edited string as addition.
         return array(array(1 => $editedString));
     }
     // Is the edited string empty?
     if ($editedStringLength == 0) {
         // Return the original string as deletion.
         return array(array(-1 => $originalString));
     }
     // Initialize the local indices:
     // 1) Create a character index for the edited string.
     $characterIndex = array();
     for ($characterPosition = 0; $characterPosition < $editedStringLength; $characterPosition++) {
         $characterIndex[$editedStringCharacters[$characterPosition]][] = $characterPosition;
     }
     // 2) Initialize the substring and the length index.
     $substringIndex = $lengthIndex = array();
     // Iterate over the original string to identify
     // the largest common string.
     for ($originalPosition = 0; $originalPosition < $originalStringLength; $originalPosition++) {
         // Find all occurrences of the original character
         // in the target string.
         $comparedCharacter = $originalStringCharacters[$originalPosition];
         // Do we have a commonality between the original string
         // and the edited string?
         if (isset($characterIndex[$comparedCharacter])) {
             // Loop over all commonalities.
             foreach ($characterIndex[$comparedCharacter] as $editedPosition) {
                 // Calculate the current and the preceding position
                 // ids for indexation.
                 $currentPosition = $originalPosition . '-' . $editedPosition;
                 $previousPosition = $originalPosition - 1 . '-' . ($editedPosition - 1);
                 // Does the occurrence in the target string continue
                 // an existing common substring or does it start
                 // a new one?
                 if (isset($substringIndex[$previousPosition])) {
                     // This is a continuation of an existing common
                     // substring...
                     $newSubstring = $substringIndex[$previousPosition] . $comparedCharacter;
                     $newSubstringLength = String::strlen($newSubstring);
                     // Move the substring in the substring index.
                     $substringIndex[$currentPosition] = $newSubstring;
                     unset($substringIndex[$previousPosition]);
                     // Move the substring in the length index.
                     $lengthIndex[$newSubstringLength][$currentPosition] = $newSubstring;
                     unset($lengthIndex[$newSubstringLength - 1][$previousPosition]);
                 } else {
                     // Start a new common substring...
                     // Add the substring to the substring index.
                     $substringIndex[$currentPosition] = $comparedCharacter;
                     // Add the substring to the length index.
                     $lengthIndex[1][$currentPosition] = $comparedCharacter;
                 }
             }
         }
     }
     // If we have no commonalities at all then mark the original
     // string as deleted and the edited string as added and
     // return.
     if (empty($lengthIndex)) {
         return array(array(-1 => $originalString), array(1 => $editedString));
     }
     // Pop the largest common substrings from the length index.
     end($lengthIndex);
     $largestSubstringLength = key($lengthIndex);
     // Take the first common substring if we have more than
     // one substring with the same length.
     // FIXME: Find a better heuristic for this decision.
     reset($lengthIndex[$largestSubstringLength]);
     $largestSubstringPosition = key($lengthIndex[$largestSubstringLength]);
     list($largestSubstringEndOriginal, $largestSubstringEndEdited) = explode('-', $largestSubstringPosition);
     $largestSubstring = $lengthIndex[$largestSubstringLength][$largestSubstringPosition];
     // Add the largest common substring to the result set
     $diffResult = array(array(0 => $largestSubstring));
     // Prepend the diff of the substrings before the common substring
     // to the result diff (by recursion).
     $precedingSubstringOriginal = String::substr($originalString, 0, $largestSubstringEndOriginal - $largestSubstringLength + 1);
     $precedingSubstringEdited = String::substr($editedString, 0, $largestSubstringEndEdited - $largestSubstringLength + 1);
     $diffResult = array_merge(String::diff($precedingSubstringOriginal, $precedingSubstringEdited), $diffResult);
     // Append the diff of the substrings after thr common substring
     // to the result diff (by recursion).
     $succeedingSubstringOriginal = String::substr($originalString, $largestSubstringEndOriginal + 1);
     $succeedingSubstringEdited = String::substr($editedString, $largestSubstringEndEdited + 1);
     $diffResult = array_merge($diffResult, String::diff($succeedingSubstringOriginal, $succeedingSubstringEdited));
     // Return the array representing the diff.
     return $diffResult;
 }
 /**
  * Save changes to article.
  * @return int the article ID
  */
 function execute()
 {
     $articleDao =& DAORegistry::getDAO('ArticleDAO');
     if (isset($this->article)) {
         // Update existing article
         $this->article->setSectionId($this->getData('sectionId'));
         $this->article->setLocale($this->getData('locale'));
         $this->article->setCommentsToEditor($this->getData('commentsToEditor'));
         if ($this->article->getSubmissionProgress() <= $this->step) {
             $this->article->stampStatusModified();
             $this->article->setSubmissionProgress($this->step + 1);
         }
         $articleDao->updateArticle($this->article);
     } else {
         // Insert new article
         $journal =& $this->request->getJournal();
         $user =& $this->request->getUser();
         $this->article = new Article();
         $this->article->setLocale($this->getData('locale'));
         $this->article->setUserId($user->getId());
         $this->article->setJournalId($journal->getId());
         $this->article->setSectionId($this->getData('sectionId'));
         $this->article->stampStatusModified();
         $this->article->setSubmissionProgress($this->step + 1);
         $this->article->setLanguage(String::substr($this->article->getLocale(), 0, 2));
         $this->article->setCommentsToEditor($this->getData('commentsToEditor'));
         $articleDao->insertArticle($this->article);
         $this->articleId = $this->article->getId();
         // Set user to initial author
         $authorDao =& DAORegistry::getDAO('AuthorDAO');
         /* @var $authorDao AuthorDAO */
         $user =& $this->request->getUser();
         $author = new Author();
         $author->setSubmissionId($this->articleId);
         $author->setFirstName($user->getFirstName());
         $author->setMiddleName($user->getMiddleName());
         $author->setLastName($user->getLastName());
         $author->setAffiliation($user->getAffiliation(null), null);
         $author->setCountry($user->getCountry());
         $author->setEmail($user->getEmail());
         $author->setData('orcid', $user->getData('orcid'));
         $author->setUrl($user->getUrl());
         $author->setBiography($user->getBiography(null), null);
         $author->setPrimaryContact(1);
         $authorDao->insertAuthor($author);
     }
     return $this->articleId;
 }
Exemplo n.º 19
0
 /**
  * Display the payment form
  * @param $queuedPaymentId int
  * @param $queuedPayment QueuedPayment
  */
 function displayPaymentForm($queuedPaymentId, &$queuedPayment)
 {
     if (!$this->isConfigured()) {
         return false;
     }
     $journal =& Request::getJournal();
     $user =& Request::getUser();
     $params = array('business' => $this->getSetting($journal->getId(), 'selleraccount'), 'item_name' => $queuedPayment->getName(), 'item_description' => $queuedPayment->getDescription(), 'amount' => $queuedPayment->getAmount(), 'quantity' => 1, 'no_note' => 1, 'no_shipping' => 1, 'currency_code' => $queuedPayment->getCurrencyCode(), 'lc' => String::substr(Locale::getLocale(), 3), 'custom' => $queuedPaymentId, 'notify_url' => Request::url(null, 'payment', 'plugin', array($this->getName(), 'ipn')), 'return' => $queuedPayment->getRequestUrl(), 'cancel_return' => Request::url(null, 'payment', 'plugin', array($this->getName(), 'cancel')), 'first_name' => $user ? $user->getFirstName() : '', 'last_name' => $user ? $user->getLastname() : '', 'item_number' => $queuedPayment->getAssocId(), 'cmd' => '_xclick');
     Locale::requireComponents(array(LOCALE_COMPONENT_APPLICATION_COMMON));
     $templateMgr =& TemplateManager::getManager();
     $templateMgr->assign('params', $params);
     $templateMgr->assign('paypalFormUrl', $this->getSetting($journal->getId(), 'paypalurl'));
     $templateMgr->display($this->getTemplatePath() . 'paymentForm.tpl');
 }
Exemplo n.º 20
0
    /**
     * updates a comment
     * @param Comment object
     */
    function updateComment(&$comment)
    {
        $comment->setDateModified(Core::getCurrentDate());
        $user = $comment->getUser();
        $this->update(sprintf('UPDATE comments
				SET
					submission_id = ?,
					num_children = ?,
					parent_comment_id = ?,
					user_id = ?,
					poster_ip = ?,
					date_posted = %s,
					date_modified = %s,
					title = ?,
					body = ?,
					poster_name = ?,
					poster_email = ?
				WHERE	comment_id = ?', $this->datetimeToDB($comment->getDatePosted()), $this->datetimeToDB($comment->getDateModified())), array($comment->getSubmissionId(), $comment->getChildCommentCount(), $comment->getParentCommentId(), isset($user) ? $user->getId() : null, $comment->getPosterIP(), String::substr($comment->getTitle(), 0, 255), $comment->getBody(), String::substr($comment->getPosterName(), 0, 90), String::substr($comment->getPosterEmail(), 0, 90), $comment->getId()));
    }
 /**
  * Get the localized, truncated description of the book for review.
  * @return string
  */
 function getLocalizedDescriptionShort()
 {
     $end = '';
     if (String::strlen($this->getLocalizedData('description'))) {
         $end = ' ...';
     }
     return String::substr($this->getLocalizedData('description'), 0, 250) . $end;
 }
Exemplo n.º 22
0
 /**
  * Helper function: Recursive function called by _removeTags
  * Removes tags from the back of the string and keeps a record of their position from the back
  * @author Matt Crider
  * @param string
  * @param int loc Keeps track of position from the back of original string
  * @param array
  * @param int
  * @return string
  */
 function _removeTagsAuxReverse($string, $loc, &$tags, $length)
 {
     $backLoc = String::strlen($string) - 1;
     if ($backLoc >= 0 && $length > 0) {
         $length--;
         if (String::substr($string, $backLoc, 1) == '>') {
             $tag = '>';
             $openBrack = 1;
             while (String::substr($string, $backLoc - $openBrack, 1) != '<') {
                 $tag = String::substr($string, $backLoc - $openBrack, 1) . $tag;
                 $openBrack++;
             }
             $tag = '<' . $tag;
             $openBrack++;
             $tags[] = array($tag, $loc);
             return $this->_removeTagsAuxReverse(String::substr($string, 0, -$openBrack), $loc + $openBrack, $tags, $length);
         }
         return $this->_removeTagsAuxReverse(String::substr($string, 0, -1), $loc + 1, $tags, $length) . String::substr($string, $backLoc, 1);
     }
 }
Exemplo n.º 23
0
 /**
  * Register a new user.
  */
 function execute()
 {
     $requireValidation = Config::getVar('email', 'require_validation');
     if ($this->existingUser) {
         // If using implicit auth - we hardwire that we are working on an existing user
         // Existing user in the system
         $userDao =& DAORegistry::getDAO('UserDAO');
         if ($this->implicitAuth) {
             // If we are using implicit auth - then use the session username variable - rather than data from the form
             $sessionManager =& SessionManager::getManager();
             $session =& $sessionManager->getUserSession();
             $user =& $userDao->getUserByUsername($session->getSessionVar('username'));
         } else {
             $user =& $userDao->getUserByUsername($this->getData('username'));
         }
         if ($user == null) {
             return false;
         }
         $userId = $user->getId();
     } else {
         // New user
         $user = new User();
         $user->setUsername($this->getData('username'));
         $user->setSalutation($this->getData('salutation'));
         $user->setFirstName($this->getData('firstName'));
         $user->setMiddleName($this->getData('middleName'));
         $user->setInitials($this->getData('initials'));
         $user->setLastName($this->getData('lastName'));
         $user->setGender($this->getData('gender'));
         $user->setAffiliation($this->getData('affiliation'), null);
         // Localized
         $user->setSignature($this->getData('signature'), null);
         // Localized
         $user->setEmail($this->getData('email'));
         $user->setUrl($this->getData('userUrl'));
         $user->setPhone($this->getData('phone'));
         $user->setFax($this->getData('fax'));
         $user->setMailingAddress($this->getData('mailingAddress'));
         $user->setBiography($this->getData('biography'), null);
         // Localized
         $user->setDateRegistered(Core::getCurrentDate());
         $user->setCountry($this->getData('country'));
         $site =& Request::getSite();
         $availableLocales = $site->getSupportedLocales();
         $locales = array();
         foreach ($this->getData('userLocales') as $locale) {
             if (Locale::isLocaleValid($locale) && in_array($locale, $availableLocales)) {
                 array_push($locales, $locale);
             }
         }
         $user->setLocales($locales);
         if (isset($this->defaultAuth)) {
             $user->setPassword($this->getData('password'));
             // FIXME Check result and handle failures
             $this->defaultAuth->doCreateUser($user);
             $user->setAuthId($this->defaultAuth->authId);
         }
         $user->setPassword(Validation::encryptCredentials($this->getData('username'), $this->getData('password')));
         if ($requireValidation) {
             // The account should be created in a disabled
             // state.
             $user->setDisabled(true);
             $user->setDisabledReason(Locale::translate('user.login.accountNotValidated'));
         }
         $userDao =& DAORegistry::getDAO('UserDAO');
         $userDao->insertUser($user);
         $userId = $user->getId();
         if (!$userId) {
             return false;
         }
         // Add reviewing interests to interests table
         import('lib.pkp.classes.user.InterestManager');
         $interestManager = new InterestManager();
         $interestManager->insertInterests($userId, $this->getData('interestsKeywords'), $this->getData('interests'));
         $sessionManager =& SessionManager::getManager();
         $session =& $sessionManager->getUserSession();
         $session->setSessionVar('username', $user->getUsername());
     }
     $press =& Request::getPress();
     $roleDao =& DAORegistry::getDAO('RoleDAO');
     // Roles users are allowed to register themselves in
     $allowedRoles = array('reader' => 'registerAsReader', 'author' => 'registerAsAuthor', 'reviewer' => 'registerAsReviewer');
     $pressSettingsDao =& DAORegistry::getDAO('PressSettingsDAO');
     if (!$pressSettingsDao->getSetting($press->getId(), 'allowRegReader')) {
         unset($allowedRoles['reader']);
     }
     if (!$pressSettingsDao->getSetting($press->getId(), 'allowRegAuthor')) {
         unset($allowedRoles['author']);
     }
     if (!$pressSettingsDao->getSetting($press->getId(), 'allowRegReviewer')) {
         unset($allowedRoles['reviewer']);
     }
     foreach ($allowedRoles as $k => $v) {
         $roleId = $roleDao->getRoleIdFromPath($k);
         if ($this->getData($v) && !$roleDao->userHasRole($press->getId(), $userId, $roleId)) {
             $role = new Role();
             $role->setPressId($press->getId());
             $role->setUserId($userId);
             $role->setRoleId($roleId);
             $roleDao->insertRole($role);
         }
     }
     if (!$this->existingUser) {
         import('classes.mail.MailTemplate');
         if ($requireValidation) {
             // Create an access key
             import('lib.pkp.classes.security.AccessKeyManager');
             $accessKeyManager = new AccessKeyManager();
             $accessKey = $accessKeyManager->createKey('RegisterContext', $user->getId(), null, Config::getVar('email', 'validation_timeout'));
             // Send email validation request to user
             $mail = new MailTemplate('USER_VALIDATE');
             $mail->setFrom($press->getSetting('contactEmail'), $press->getSetting('contactName'));
             $mail->assignParams(array('userFullName' => $user->getFullName(), 'activateUrl' => Request::url($press->getPath(), 'user', 'activateUser', array($this->getData('username'), $accessKey))));
             $mail->addRecipient($user->getEmail(), $user->getFullName());
             $mail->send();
             unset($mail);
         }
         if ($this->getData('sendPassword')) {
             // Send welcome email to user
             $mail = new MailTemplate('USER_REGISTER');
             $mail->setFrom($press->getSetting('contactEmail'), $press->getSetting('contactName'));
             $mail->assignParams(array('username' => $this->getData('username'), 'password' => String::substr($this->getData('password'), 0, 30), 'userFullName' => $user->getFullName()));
             $mail->addRecipient($user->getEmail(), $user->getFullName());
             $mail->send();
             unset($mail);
         }
     }
     // By default, self-registering readers will receive
     // press updates. (The double set is here to prevent a
     // duplicate insert error msg if there was a notification entry
     // left over from a previous role.)
     if (isset($allowedRoles['reader']) && $this->getData($allowedRoles['reader'])) {
         $notificationStatusDao =& DAORegistry::getDAO('NotificationStatusDAO');
         $notificationStatusDao->setPressNotifications($press->getId(), $userId, false);
         $notificationStatusDao->setPressNotifications($press->getId(), $userId, true);
     }
 }
Exemplo n.º 24
0
 /**
  * Retrieve auto-suggestions from the faceting service.
  * @param $url string
  * @param $searchRequest SolrSearchRequest
  * @param $userInput string
  * @param $fieldName string
  * @return array The generated suggestions.
  */
 function _getFacetingAutosuggestions($url, $searchRequest, $userInput, $fieldName)
 {
     // Remove special characters from the user input.
     $searchTerms = strtr($userInput, '"()+-|&!', '        ');
     // Cut off the last search term.
     $searchTerms = explode(' ', $searchTerms);
     $facetPrefix = array_pop($searchTerms);
     if (empty($facetPrefix)) {
         return array();
     }
     // Use the remaining search query to pre-filter
     // facet results. This may be an invalid query
     // but edismax will deal gracefully with syntax
     // errors.
     $userInput = String::substr($userInput, 0, -String::strlen($facetPrefix));
     switch ($fieldName) {
         case 'query':
             // The 'query' filter goes agains all fields.
             $articleSearch = new ArticleSearch();
             $solrFields = array_values($articleSearch->getIndexFieldMap());
             break;
         case 'indexTerms':
             // The 'index terms' filter goes against keyword index fields.
             $solrFields = array('discipline', 'subject', 'type', 'coverage');
             break;
         default:
             // All other filters can be used directly.
             $solrFields = array($fieldName);
     }
     $solrFieldString = implode('|', $solrFields);
     $searchRequest->addQueryFieldPhrase($solrFieldString, $userInput);
     // Construct the main query.
     $params = $this->_getSearchQueryParameters($searchRequest);
     if (!isset($params['q'])) {
         // Use a catch-all query in case we have no limiting
         // search.
         $params['q'] = '*:*';
     }
     if ($fieldName == 'query') {
         $params['facet.field'] = 'default_spell';
     } else {
         $params['facet.field'] = $fieldName . '_spell';
     }
     $facetPrefixLc = String::strtolower($facetPrefix);
     $params['facet.prefix'] = $facetPrefixLc;
     // Make the request.
     $response = $this->_makeRequest($url, $params);
     if (!is_a($response, 'DOMXPath')) {
         return array();
     }
     // Extract term suggestions.
     $nodeList = $response->query('//lst[@name="facet_fields"]/lst/int/@name');
     if ($nodeList->length == 0) {
         return array();
     }
     $termSuggestions = array();
     foreach ($nodeList as $childNode) {
         $termSuggestions[] = $childNode->value;
     }
     // Add the term suggestion to the remaining user input.
     $suggestions = array();
     foreach ($termSuggestions as $termSuggestion) {
         // Restore case if possible.
         if (strpos($termSuggestion, $facetPrefixLc) === 0) {
             $termSuggestion = $facetPrefix . String::substr($termSuggestion, String::strlen($facetPrefix));
         }
         $suggestions[] = $userInput . $termSuggestion;
     }
     return $suggestions;
 }
 /**
  * Parse an XML file using the specified handler.
  * If no handler has been specified, XMLParserDOMHandler is used by default, returning a tree structure representing the document.
  * @param $file string full path to the XML file
  * @return object actual return type depends on the handler
  */
 function &parse($file)
 {
     $parser =& $this->createParser();
     if (!isset($this->handler)) {
         // Use default handler for parsing
         $handler = new XMLParserDOMHandler();
         $this->setHandler($handler);
     }
     xml_set_object($parser, $this->handler);
     xml_set_element_handler($parser, "startElement", "endElement");
     xml_set_character_data_handler($parser, "characterData");
     import('lib.pkp.classes.file.FileWrapper');
     $wrapper =& FileWrapper::wrapper($file);
     // Handle responses of various types
     while (true) {
         $newWrapper = $wrapper->open();
         if (is_object($newWrapper)) {
             // Follow a redirect
             unset($wrapper);
             $wrapper =& $newWrapper;
             unset($newWrapper);
         } elseif (!$newWrapper) {
             // Could not open resource -- error
             $returner = false;
             return $returner;
         } else {
             // OK, we've found the end result
             break;
         }
     }
     if (!$wrapper) {
         $result = false;
         return $result;
     }
     while (!$wrapper->eof() && ($data = $wrapper->read()) !== false) {
         // if the string contains non-UTF8 characters, convert it to UTF-8 for parsing
         if (Config::getVar('i18n', 'charset_normalization') == 'On' && !String::utf8_compliant($data)) {
             $utf8_last = String::substr($data, String::strlen($data) - 1);
             // if the string ends in a "bad" UTF-8 character, maybe it's truncated
             while (!$wrapper->eof() && String::utf8_bad_find($utf8_last) === 0) {
                 // read another chunk of data
                 $data .= $wrapper->read();
                 $utf8_last = String::substr($data, String::strlen($data) - 1);
             }
             $data = String::utf8_normalize($data);
             // strip any invalid UTF-8 sequences
             $data = String::utf8_bad_strip($data);
             // convert named entities to numeric entities
             $data = strtr($data, String::getHTMLEntities());
         }
         // strip any invalid ASCII control characters
         $data = String::utf8_strip_ascii_ctrl($data);
         if (!xml_parse($parser, $data, $wrapper->eof())) {
             $this->addError(xml_error_string(xml_get_error_code($parser)));
         }
     }
     $wrapper->close();
     $result =& $this->handler->getResult();
     $this->destroyParser($parser);
     if (isset($handler)) {
         $handler->destroy();
         unset($handler);
     }
     return $result;
 }
Exemplo n.º 26
0
 /**
  * Helper function: Recursive function called by _removeTags
  * Removes tags from the back of the string and keeps a record of their position from the back
  * @author Matt Crider
  * @param string
  * @param int loc Keeps track of position from the back of original string
  * @param array
  * @param int
  * @return string
  */
 function _removeTagsAuxReverse($string, $loc, &$tags, $length)
 {
     $newString = '';
     for ($i = String::strlen($string); $i > 0; $i--) {
         if (String::substr($string, $backLoc, 1) == '>') {
             $tag = '>';
             $openBrack = 1;
             while (String::substr($string, $backLoc - $openBrack, 1) != '<') {
                 $tag = String::substr($string, $backLoc - $openBrack, 1) . $tag;
                 $openBrack++;
             }
             $tag = '<' . $tag;
             $openBrack++;
             $tags[] = array($tag, $loc);
             $i -= $openBrack + 1;
             continue;
         }
         $length--;
         $newString = $newString . String::substr($string, $i, 1);
     }
     return $newString;
 }
Exemplo n.º 27
0
    /**
     * updates a paper comment
     * @param paperComment object
     */
    function updatePaperComment($paperComment)
    {
        $this->update(sprintf('UPDATE paper_comments
				SET
					comment_type = ?,
					role_id = ?,
					paper_id = ?,
					assoc_id = ?,
					author_id = ?,
					date_posted = %s,
					date_modified = %s,
					comment_title = ?,
					comments = ?,
					viewable = ?
				WHERE comment_id = ?', $this->datetimeToDB($paperComment->getDatePosted()), $this->datetimeToDB($paperComment->getDateModified())), array($paperComment->getCommentType(), $paperComment->getRoleId(), $paperComment->getPaperId(), $paperComment->getAssocId(), $paperComment->getAuthorId(), String::substr($paperComment->getCommentTitle(), 0, 255), $paperComment->getComments(), $paperComment->getViewable() === null ? 1 : $paperComment->getViewable(), $paperComment->getId()));
    }
Exemplo n.º 28
0
 /**
  * Suggest a username given the first and last names.
  * @return string
  */
 function suggestUsername($firstName, $lastName)
 {
     $initial = String::substr($firstName, 0, 1);
     $suggestion = String::regexp_replace('/[^a-zA-Z0-9_-]/', '', String::strtolower($initial . $lastName));
     $userDao =& DAORegistry::getDAO('UserDAO');
     for ($i = ''; $userDao->userExistsByUsername($suggestion . $i); $i++) {
     }
     return $suggestion . $i;
 }
Exemplo n.º 29
0
 /**
  * Prepare a text to be used in the meta description tag
  * @param string
  * @return string
  */
 protected function prepareMetaDescription($strText)
 {
     $strText = $this->replaceInsertTags($strText);
     $strText = strip_tags($strText);
     $strText = str_replace("\n", ' ', $strText);
     $strText = \String::substr($strText, 180);
     return trim($strText);
 }
Exemplo n.º 30
0
 /**
  * Generate the DOM tree for a given article.
  * @param $doc object DOM object
  * @param $journal object Journal
  * @param $issue object Issue
  * @param $section object Section
  * @param $article object Article
  */
 function &generateArticleDom(&$doc, &$journal, &$issue, &$section, &$article)
 {
     $root =& XMLCustomWriter::createElement($doc, 'record');
     /* --- Article Language --- */
     XMLCustomWriter::createChildWithText($doc, $root, 'language', DOAJExportDom::mapLang($article->getLanguage()), false);
     /* --- Publisher name (i.e. institution name) --- */
     XMLCustomWriter::createChildWithText($doc, $root, 'publisher', $journal->getSetting('publisherInstitution'), false);
     /* --- Journal's title --- */
     XMLCustomWriter::createChildWithText($doc, $root, 'journalTitle', $journal->getLocalizedTitle(), false);
     /* --- Identification Numbers --- */
     XMLCustomWriter::createChildWithText($doc, $root, 'issn', $journal->getSetting('printIssn'), false);
     XMLCustomWriter::createChildWithText($doc, $root, 'eissn', $journal->getSetting('onlineIssn'), false);
     /* --- Article's publication date, volume, issue, DOI --- */
     XMLCustomWriter::createChildWithText($doc, $root, 'publicationDate', DOAJExportDom::formatDate($issue->getDatePublished()), false);
     XMLCustomWriter::createChildWithText($doc, $root, 'volume', $issue->getVolume(), false);
     XMLCustomWriter::createChildWithText($doc, $root, 'issue', $issue->getNumber(), false);
     /** --- FirstPage / LastPage (from PubMed plugin)---
      * there is some ambiguity for online journals as to what
      * "page numbers" are; for example, some journals (eg. JMIR)
      * use the "e-location ID" as the "page numbers" in PubMed
      */
     $pages = $article->getPages();
     if (preg_match("/([0-9]+)\\s*-\\s*([0-9]+)/i", $pages, $matches)) {
         // simple pagination (eg. "pp. 3-8")
         XMLCustomWriter::createChildWithText($doc, $root, 'startPage', $matches[1]);
         XMLCustomWriter::createChildWithText($doc, $root, 'endPage', $matches[2]);
     } elseif (preg_match("/(e[0-9]+)/i", $pages, $matches)) {
         // elocation-id (eg. "e12")
         XMLCustomWriter::createChildWithText($doc, $root, 'startPage', $matches[1]);
         XMLCustomWriter::createChildWithText($doc, $root, 'endPage', $matches[1]);
     }
     XMLCustomWriter::createChildWithText($doc, $root, 'doi', $article->getPubId('doi'), false);
     /* --- Article's publication date, volume, issue, DOI --- */
     XMLCustomWriter::createChildWithText($doc, $root, 'publisherRecordId', $article->getPublishedArticleId(), false);
     XMLCustomWriter::createChildWithText($doc, $root, 'documentType', $article->getLocalizedType(), false);
     /* --- Article title --- */
     foreach ((array) $article->getTitle(null) as $locale => $title) {
         if (empty($title)) {
             continue;
         }
         $titleNode =& XMLCustomWriter::createChildWithText($doc, $root, 'title', $title);
         if (strlen($locale) == 5) {
             XMLCustomWriter::setAttribute($titleNode, 'language', DOAJExportDom::mapLang(String::substr($locale, 0, 2)));
         }
     }
     /* --- Authors and affiliations --- */
     $authors =& XMLCustomWriter::createElement($doc, 'authors');
     XMLCustomWriter::appendChild($root, $authors);
     $affilList = DOAJExportDom::generateAffiliationsList($article->getAuthors());
     foreach ($article->getAuthors() as $author) {
         $authorNode =& DOAJExportDom::generateAuthorDom($doc, $root, $issue, $article, $author, $affilList);
         XMLCustomWriter::appendChild($authors, $authorNode);
         unset($authorNode);
     }
     if (!empty($affilList[0])) {
         $affils =& XMLCustomWriter::createElement($doc, 'affiliationsList');
         XMLCustomWriter::appendChild($root, $affils);
         for ($i = 0; $i < count($affilList); $i++) {
             $affilNode =& XMLCustomWriter::createChildWithText($doc, $affils, 'affiliationName', $affilList[$i]);
             XMLCustomWriter::setAttribute($affilNode, 'affiliationId', $i);
             unset($affilNode);
         }
     }
     /* --- Abstract --- */
     foreach ((array) $article->getAbstract(null) as $locale => $abstract) {
         if (empty($abstract)) {
             continue;
         }
         $abstractNode =& XMLCustomWriter::createChildWithText($doc, $root, 'abstract', $abstract);
         if (strlen($locale) == 5) {
             XMLCustomWriter::setAttribute($abstractNode, 'language', DOAJExportDom::mapLang(String::substr($locale, 0, 2)));
         }
     }
     /* --- FullText URL --- */
     $fullTextUrl =& XMLCustomWriter::createChildWithText($doc, $root, 'fullTextUrl', Request::url(null, 'article', 'view', $article->getId()));
     XMLCustomWriter::setAttribute($fullTextUrl, 'format', 'html');
     /* --- Keywords --- */
     $keywords =& XMLCustomWriter::createElement($doc, 'keywords');
     XMLCustomWriter::appendChild($root, $keywords);
     $subjects = array_map('trim', explode(';', $article->getLocalizedSubject()));
     foreach ($subjects as $keyword) {
         XMLCustomWriter::createChildWithText($doc, $keywords, 'keyword', $keyword, false);
     }
     return $root;
 }