/**
  * DOCUMENT ME
  * @param sfRequest $request
  * @return mixed
  */
 public function executeEdit(sfRequest $request)
 {
     $this->editSetup();
     $value = $this->getRequestParameter('slot-form-' . $this->id);
     $this->options['multiline'] = $this->getOption('multiline', true);
     $this->form = new aTextForm($this->id, $this->slot->value, $this->options);
     $this->form->bind($value);
     if ($this->form->isValid()) {
         // TODO: this might make a nice validator
         $value = $this->form->getValue('value');
         if (!$this->options['multiline']) {
             $value = preg_replace("/\\s/", " ", $value);
         }
         // We store light markup for "plain text" slots. We DO NOT store the mailto: obfuscation though
         $value = aHtml::textToHtml($value);
         $maxlength = $this->getOption('maxlength');
         if ($maxlength !== false) {
             $value = substr(0, $maxlength);
         }
         $this->slot->value = $value;
         $result = $this->editSave();
         return $result;
     } else {
         // Makes $this->form available to the next iteration of the
         // edit view so that validation errors can be seen (although there
         // aren't any in this case)
         return $this->editRetry();
     }
 }
 public function executeNormalView()
 {
     $this->setup();
     // We don't recommend doing this at the FCK level,
     // let it happen here instead so what is stored in the
     // db can be clean markup
     $this->value = aHtml::obfuscateMailto($this->value);
 }
 /**
  * DOCUMENT ME
  */
 public function executeNormalView()
 {
     $this->setup();
     // Yes, we store basic HTML markup for "plaintext" slots.
     // However we obfuscate the mailto links on the fly as a last step
     // (so it's not as fast as we originally intended, but this is an
     // essential feature that makes transformation of the code difficult).
     $this->value = aHtml::obfuscateMailto($this->value);
 }
Example #4
0
 /**
  * @see sfValidatorBase
  */
 protected function doClean($value)
 {
     $clean = (string) $value;
     if ($this->getOption('strip')) {
         $clean = aHtml::simplify($clean, $this->getOptionOrFalse('allowed_tags'), $this->getOptionOrFalse('complete'), $this->getOptionOrFalse('allowed_attributes'), $this->getOptionOrFalse('allowed_styles'));
     } else {
         throw new sfException('That should not happen strip is set in configure in sfValidatorHtml');
     }
     $clean = parent::doClean($clean);
     return $clean;
 }
 public function getSearchText()
 {
     // Convert from HTML to plaintext before indexing by Lucene
     // However first add line breaks after certain tags for better formatting
     // (this method is also used for generating informational diffs between versions).
     // This is a noncritical feature so it doesn't have to be as precise
     // as strip_tags and shouldn't try to substitute for it in the matter of
     // actually removing the tags
     $this->value = preg_replace("/(<p>|<br.*?>|<blockquote>|<li>|<dt>|<dd>|<nl>|<ol>)/i", "\$1\n", $this->value);
     return aHtml::toPlaintext($this->value);
 }
 /**
  * DOCUMENT ME
  * @param mixed $values
  * @return mixed
  */
 public function updateObject($values = null)
 {
     $object = parent::updateObject($values);
     // Do some postvalidation of what parent::updateObject did
     // (it would be nice to turn this into an sfValidator subclass)
     $object->setDescription(aHtml::simplify($object->getDescription(), "<p><br><b><i><strong><em><ul><li><ol><a>"));
     // The tags field is not a native Doctrine field
     // so we can't rely on parent::updateObject to sort out
     // whether to use $values or $this->getValue. So we need
     // to sanitize and figure out what set of values to use
     // (embedded forms get a $values parameter, non-embedded
     // use $this->values)
     if (is_null($values)) {
         $values = $this->values;
     }
     // Slashes break routes in most server configs. Do NOT force case of tags.
     $values['tags'] = str_replace('/', '-', isset($values['tags']) ? $values['tags'] : '');
     $object->setTags($values['tags']);
     return $object;
 }
 public function updateObject($values = null)
 {
     $object = parent::updateObject($values);
     // Do some postvalidation of what parent::updateObject did
     // (it would be nice to turn this into an sfValidator subclass)
     $object->setDescription(aHtml::simplify($object->getDescription(), "<p><br><b><i><strong><em><ul><li><ol><a>"));
     // The tags field is not a native Doctrine field
     // so we can't rely on parent::updateObject to sort out
     // whether to use $values or $this->getValue. So we need
     // to sanitize and figure out what set of values to use
     // (embedded forms get a $values parameter, non-embedded
     // use $this->values)
     if (is_null($values)) {
         $values = $this->values;
     }
     // Now we're ready to play
     // We like all-lowercase tags for consistency
     $values['tags'] = strtolower($values['tags']);
     $object->setTags($values['tags']);
     $object->setOwnerId(sfContext::getInstance()->getUser()->getGuardUser()->getId());
     return $object;
 }
 /**
  *
  * @param string $areas Array of areas to retrieve text for
  * @param int $limit Number of characters to restrict retrieval to
  * @return string
  */
 public function getRichTextForAreas($areas = array(), $limit = null)
 {
     $text = '';
     if (!is_array($areas)) {
         $areas = array($areas);
     }
     foreach ($areas as $area) {
         foreach ($this->Page->getArea($area) as $slot) {
             if ($slot['type'] == 'aRichText' || $slot['type'] == 'aText') {
                 $text .= $slot->getValue();
             }
         }
     }
     if (!is_null($limit)) {
         $text = aHtml::limitWords($text, $limit, array('append_ellipsis' => true));
     }
     return $text;
 }
Example #9
0
 /**
  * DOCUMENT ME
  * @param SimpleXMLElement $slot
  * @return mixed
  */
 protected function parseSlotForeignHtml(SimpleXMLElement $slot, $title = null, &$counters = null)
 {
     $n = 1;
     $html = $slot->value->__toString();
     $segments = aString::splitAndCaptureAtEarliestMatch($html, array('/\\<a href=\\"[^\\"]+\\"[^\\>]*>\\s*(?:\\<br \\/\\>|&nbsp;|\\s)*\\<img.*?src="[^\\"]+[^\\>]*\\>(?:\\<br \\/\\>|&nbsp;|\\s)*\\<\\/a\\>/is', '/\\<img.*?src="[^\\"]+".*?\\>/is', '/\\<object.*?\\>.*?\\<\\/object\\>/is', '/\\<iframe.*?\\>.*?\\<\\/iframe\\>/is'));
     foreach ($segments as $segment) {
         $mediaItem = null;
         if (preg_match('/\\<object.*?\\>.*?\\<\\/object\\>|\\<iframe.*?\\>.*?\\<\\/iframe\\>/is', $segment)) {
             $form = new aMediaVideoForm();
             $result = $form->classifyEmbed($segment);
             if ($result['ok']) {
                 $info = array('title' => isset($result['serviceInfo']['title']) ? $result['serviceInfo']['title'] : $title . ' video ' . $n, 'embed' => $result['embed'], 'width' => isset($result['width']) ? $result['width'] : null, 'height' => isset($result['height']) ? $result['height'] : null, 'format' => isset($result['format']) ? $result['format'] : null, 'type' => 'video', 'tags' => isset($result['serviceInfo']['tags']) ? preg_split('/\\s*,\\s*/', $result['serviceInfo']['tags']) : array(), 'service_url' => isset($result['serviceInfo']['url']) ? $result['serviceInfo']['url'] : null);
                 $mediaId = $this->findOrAddVideo($info);
                 $slotInfos[] = array('type' => 'aVideo', 'mediaId' => $mediaId);
                 $n++;
             }
         } elseif (preg_match('/<img.*?src="(.*?)".*?>/is', $segment, $matches)) {
             $src = $matches[1];
             // &amp; won't work if we don't decode it to & before passing it to the server
             $src = html_entity_decode($src);
             $mediaId = $this->findOrAddMediaItem($src, 'id');
             if (preg_match('/href="(.*?)"/', $segment, $matches)) {
                 $url = $matches[1];
             }
             // $mediaItem->save();
             if (!is_null($mediaId)) {
                 $slotInfo = array('type' => 'aImage', 'mediaId' => $mediaId, 'value' => array());
                 if (isset($url)) {
                     $slotInfo = array('type' => 'aButton', 'value' => array('url' => $url, 'title' => ''), 'mediaId' => $mediaId);
                 }
                 $slotInfos[] = $slotInfo;
             }
         } else {
             $slotInfos[] = array('type' => 'aRichText', 'value' => aHtml::simplify($segment));
         }
     }
     return $slotInfos;
 }
Example #10
0
 /**
  * 
  * This function returns a basic HTML representation of your slot's comments
  * (passing the default settings of aHtml::simplify, for instance). Used for Google Calendar
  * buttons, RSS feeds and similar
  * @return string
  */
 public function getBasicHtml()
 {
     return aHtml::simplify($this->value);
 }
Example #11
0
 /**
  * This is a quick and dirty implementation based on calling limitWords
  * with an optimistic guess and then backing off a few times if necessary
  * until we get under the byte limit. Note that limitBytes is designed
  * to fit things in buffers, not save screen space, so it does have to
  * make sure the result is not too big
  * @param mixed $string
  * @param mixed $byte_limit
  * @param mixed $options
  * @return mixed
  */
 public static function limitBytes($string, $byte_limit, $options = array())
 {
     $word_limit = (int) ($byte_limit / 8);
     while (true) {
         $s = aHtml::limitWords($string, $word_limit, $options);
         if (strlen($s) <= $byte_limit) {
             break;
         }
         $word_limit = (int) ($word_limit * 0.75);
     }
     return $s;
 }
    public function executeIcalFeed(sfWebRequest $request)
    {
        $this->buildParams();
        $this->dateRange = '';
        $this->aEvent = $this->getRoute()->getObject();
        $this->categories = aCategoryTable::getCategoriesForPage($this->page);
        $this->forward404Unless($this->aEvent);
        $this->forward404Unless($this->aEvent['status'] == 'published' || $this->getUser()->isAuthenticated());
        aBlogItemTable::populatePages(array($this->aEvent));
        header("Content-type: text/calendar");
        header('Content-disposition: attachment; filename=' . str_replace('.', '-', $this->getRequest()->getHost() . '-' . $this->aEvent->id) . '.ics');
        $start = $this->aEvent->getVcalStartDateTime();
        $end = $this->aEvent->getVcalEndDateTime();
        $title = aString::toVcal(aHtml::toPlaintext($this->aEvent->getTitle()));
        $body = aString::toVcal(aHtml::toPlaintext($this->aEvent->Page->getAreaText('blog-body')));
        echo <<<EOM
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
CATEGORIES:MEETING
DTSTART:{$start}
DTEND:{$end}
SUMMARY:{$title}
DESCRIPTION:{$body}
CLASS:PRIVATE
END:VEVENT
END:VCALENDAR
EOM;
        exit(0);
    }
Example #13
0
 /**
  * DOCUMENT ME
  * @param mixed $areaname
  * @param mixed $word_limit
  * @return mixed
  */
 public function getAreaBasicHtml($areaname, $word_limit = false)
 {
     $slots = $this->getSlotsByAreaName($areaname);
     $text = '';
     foreach ($slots as $slot) {
         if (strlen($text)) {
             // div might not be permitted in a lot of 'basic html'
             // contexts, but we do need some vertical break between
             // two slots to reasonably reproduce what
             // Apostrophe does with them
             $text .= '<br />';
         }
         $text .= $slot->getBasicHtml();
     }
     if ($word_limit) {
         return aHtml::limitWords($text, $word_limit, array('append_ellipsis' => true));
     } else {
         return $text;
     }
 }
<?php

// Google says they accept HTML in descriptions but they seem not to use it for anything.
// You never see descriptions anyway except when editing them. So send the plaintext.
// The byte limit was chosen to avoid creating a URL that the browser won't accept,
// even when Google double-encodes it in some situations
$aEvent = $sf_data->getRaw('aEvent');
echo a_button(a_('Add to Google Calendar'), url_for('http://www.google.com/calendar/event?' . http_build_query(array('action' => 'TEMPLATE', 'text' => $aEvent->getTitle(), 'dates' => $aEvent->getUTCDateRange(), 'location' => preg_replace('/\\s+/', ' ', $aEvent['location']), 'sprop' => 'website:' . $sf_request->getHost(), 'details' => aHtml::toPlaintext($aEvent->getTextForArea('blog-body', 500, array('characters' => true, 'append_ellipsis' => a_('...'))))))), array('icon', 'no-bg', 'alt', 'a-events'));
Example #15
0
</a>
			<?php 
} else {
    ?>
				<?php 
    echo $feedItem->getTitle();
    ?>
			<?php 
}
?>
		</li>
    <?php 
$date = $feedItem->getPubDate();
?>
    <?php 
if ($date) {
    ?>
      <li class="date"><?php 
    echo $dateFormat ? date($dateFormat, $date) : aDate::pretty($date) . ' ' . aDate::time($date);
    ?>
</li>
    <?php 
}
?>
    <li class="description"><?php 
echo auto_link_text(aHtml::simplify($feedItem->getDescription(), $markup, false, isset($attributes) ? $attributes : false, isset($styles) ? $styles : false));
?>
</li>
  </ul>
</li>
 /**
  * DOCUMENT ME
  * @param mixed $arguments
  * @param mixed $options
  */
 protected function execute($arguments = array(), $options = array())
 {
     // We need a basic context so we can call helpers to format text
     $context = sfContext::createInstance($this->configuration);
     // initialize the database connection
     $databaseManager = new sfDatabaseManager($this->configuration);
     $connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection();
     // PDO connection not so useful, get the doctrine one
     $conn = Doctrine_Manager::connection();
     $accounts = Doctrine::getTable('aEmbedMediaAccount')->findAll();
     foreach ($accounts as $a) {
         $perPage = 50;
         $service = aMediaTools::getEmbedService($a->service);
         if (!$service) {
             // An account for a service that has been deconfigured
             continue;
         }
         $total = null;
         $page = 1;
         $serviceUrls = array();
         while (true) {
             $results = $service->browseUser($a->username, $page, $perPage);
             if ($results === false) {
                 // We hit the rate limit, the account is bad, etc. Just
                 // be tolerant and retry later. Would be nice to distinguish
                 // these cases but it's not that hard to figure out an
                 // account is gone
                 break;
             }
             foreach ($results['results'] as $result) {
                 $serviceUrls[] = $result['url'];
             }
             // We hit the end of the results for this user
             if (!count($results['results'])) {
                 break;
             }
             $page++;
         }
         if (count($serviceUrls)) {
             $existingServiceUrls = Doctrine::getTable('aMediaItem')->createQuery('m')->select('m.service_url')->andWhereIn('m.service_url', $serviceUrls)->execute(array(), Doctrine::HYDRATE_SINGLE_SCALAR);
         } else {
             $existingServiceUrls = array();
         }
         $existingServiceUrls = array_flip($existingServiceUrls);
         foreach ($serviceUrls as $serviceUrl) {
             if (!isset($existingServiceUrls[$serviceUrl])) {
                 // If Doctrine becomes a performance problem I could use PDO
                 // and set lucene_dirty to let that clean itself up later
                 $id = $service->getIdFromUrl($serviceUrl);
                 $info = $service->getInfo($id);
                 if (!$info) {
                     // We are not actually allowed meaningful access to this video. Password protected for example
                     continue;
                 }
                 $item = new aMediaItem();
                 $item->setTitle($info['title']);
                 // We want tags to be lower case, and slashes break routes in most server configs.
                 $info['tags'] = str_replace('/', '-', aString::strtolower($info['tags']));
                 $item->setTags($info['tags']);
                 $item->setDescription(aHtml::textToHtml($info['description']));
                 $item->setCredit($info['credit']);
                 $item->setServiceUrl($info['url']);
                 $item->setType($service->getType());
                 // The dance is this: get the thumbnail if there is one;
                 // call preSaveFile to learn the width, height and format
                 // before saving; save; and then saveFile to copy it to a
                 // filename based on the slug, which is unknown until after save
                 $thumbnail = $service->getThumbnail($id);
                 if ($thumbnail) {
                     // Grab a local copy of the thumbnail, and get the pain
                     // over with all at once in a predictable way if
                     // the service provider fails to give it to us.
                     $thumbnailCopy = aFiles::getTemporaryFilename();
                     if (copy($thumbnail, $thumbnailCopy)) {
                         $item->preSaveFile($thumbnailCopy);
                     }
                 }
                 $item->save();
                 if ($thumbnail) {
                     $item->saveFile($thumbnailCopy);
                 }
                 $item->free();
             }
         }
     }
 }
Example #17
0
 /**
  * DOCUMENT ME
  * @param sfWebRequest $request
  * @return mixed
  */
 public function executeEditVideo(sfWebRequest $request)
 {
     $this->forward404Unless(aMediaTools::userHasUploadPrivilege());
     $item = null;
     $this->slug = false;
     $this->popularTags = PluginTagTable::getPopulars(null, array('sort_by_popularity' => true), false, 10);
     if (sfConfig::get('app_a_all_tags', true)) {
         $this->allTags = PluginTagTable::getAllTagNameWithCount();
     } else {
         $this->allTags = array();
     }
     if ($request->hasParameter('slug')) {
         $item = $this->getItem();
         $this->slug = $item->getSlug();
     }
     if ($item) {
         $this->forward404Unless($item->userHasPrivilege('edit'));
     }
     $this->item = $item;
     $embed = false;
     $parameters = $request->getParameter('a_media_item');
     if ($parameters) {
         $files = $request->getFiles('a_media_item');
         $this->form = new aMediaVideoForm($item);
         if (isset($parameters['embed'])) {
             // We need to do some prevalidation of the embed code so we can prestuff the
             // file, title, tags and description widgets
             $result = $this->form->classifyEmbed($parameters['embed']);
             if (isset($result['thumbnail'])) {
                 $thumbnail = $result['thumbnail'];
                 if (!isset($parameters['title']) && !isset($parameters['tags']) && !isset($parameters['description']) && !isset($parameters['credit'])) {
                     $parameters['title'] = $result['serviceInfo']['title'];
                     // We want tags to be lower case, and slashes break routes in most server configs.
                     $parameters['tags'] = str_replace('/', '-', aString::strtolower($result['serviceInfo']['tags']));
                     $parameters['description'] = aHtml::textToHtml($result['serviceInfo']['description']);
                     $parameters['credit'] = $result['serviceInfo']['credit'];
                 }
             }
         }
         // On the first pass with a youtube video we just make the service's thumbnail the
         // default thumbnail. We don't force them to use it. This allows more code reuse
         // (Moving this after the bind is necessary to keep it from being overwritten)
         if (isset($thumbnail)) {
             // OMG file widgets can't have defaults! Ah, but our persistent file widget can
             $tmpFile = aFiles::getTemporaryFilename();
             file_put_contents($tmpFile, file_get_contents($thumbnail));
             $vfp = new aValidatorFilePersistent();
             $guid = aGuid::generate();
             $vfp->clean(array('newfile' => array('tmp_name' => $tmpFile), 'persistid' => $guid));
             // You can't mess about with widget defaults after a bind, but you
             // *can* tweak the array you're about to bind with
             $parameters['file']['persistid'] = $guid;
         }
         $this->form->bind($parameters, $files);
         do {
             // first_pass forces the user to interact with the form
             // at least once. Used when we're coming from a
             // YouTube search and we already technically have a
             // valid form but want the user to think about whether
             // the title is adequate and perhaps add a description,
             // tags, etc.
             if ($this->hasRequestParameter('first_pass') || !$this->form->isValid()) {
                 break;
             }
             $thumbnail = $this->form->getValue('file');
             // The base implementation for saving files gets confused when
             // $file is not set, a situation that our code tolerates as useful
             // because if you're updating a record containing an image you
             // often don't need to submit a new one.
             unset($this->form['file']);
             $object = $this->form->getObject();
             if ($thumbnail) {
                 $object->preSaveFile($thumbnail->getTempName());
             }
             $this->form->save();
             if ($thumbnail) {
                 $object->saveFile($thumbnail->getTempName());
             }
             return $this->redirect("aMedia/resumeWithPage");
         } while (false);
     }
 }
Example #18
0
<li class="a-feed-item">
  <ul>
    <li class="title"><?php 
echo link_to_if($feedItem->getLink() && $links, $feedItem->getTitle(), $feedItem->getLink());
?>
</li>
    <?php 
$date = $feedItem->getPubDate();
?>
    <li class="date"><?php 
echo $dateFormat ? date($dateFormat, $date) : aDate::pretty($date) . ' ' . aDate::time($date);
?>
</li>
    <li class="description"><?php 
echo aHtml::simplify($feedItem->getDescription(), $markup);
?>
</li>
  </ul>
</li>
Example #19
0
 /**
  *
  * @param string $areas Array of areas to retrieve text for
  * @param int $limit Number of characters to restrict retrieval to
  * @return string
  */
 public function getRichTextForAreas($areas = array(), $limit = null)
 {
     $text = '';
     if (!is_array($areas)) {
         $areas = array($areas);
     }
     foreach ($areas as $area) {
         $text .= $this->Page->getAreaBasicHtml($area);
     }
     if (!is_null($limit)) {
         $text = aHtml::limitWords($text, $limit, array('append_ellipsis' => true));
     }
     return $text;
 }