/** * Erzeugt ein PDF auf Basis der übergebenen Funktion. * @param $module * @param $action * @param $param * @param null $filename falls kein Dateiname angegeben wird, wird das PDF direkt im Browser ausgegeben * @throws \Exception */ public static function generate($module, $action, $param, $filename = null, $template = true, $margin = 0) { $druckinhalt = new WrapperControl(null, 'druck'); $druckinhalt->setModule($module)->setAction($action)->addParams($param); $pdf = new \mPDF('de-DE', 'A4'); $pdf->SetDisplayMode('fullpage'); // Zeigt eine ganze Seite an, wenn das PDF in Acrobat geöffnet wird if ($margin > 0) { $pdf->SetTopMargin($margin); } $pdf->SetFooter('Seite {PAGENO} / {nb}'); //file_get_contents('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css') . $stylesheet = file_get_contents('templates/print/css/default.css'); $pdf->WriteHTML($stylesheet, 1); if ($template && file_exists('site/Print.template.html')) { $vars = ['heading' => Application::getCurrentResponse()->getMetadata()->getHeading()]; $header = Parser::parse(null, null, $vars, file_get_contents('site/Print.template.html')); $pdf->WriteHTML($header, 2); } $pdf->WriteHTML($druckinhalt->toHtml(), 2); if ($filename === null) { $pdf->Output($module . $action . '.pdf', 'I'); } else { //$filename = Files::validateFilename($filename); $pdf->Output($filename, 'F'); } unset($pdf); }
protected function createControls() { // Regions auslesen $regions = Application::currentPage()->getRegions(); $inhalte = array(); foreach ($regions as $region) { $temp = $region->toHtml(); if ($temp == null) { continue; } if (isset($this->request->permalink)) { $temp->addParam('permalink', $this->request->permalink); } if (isset($this->request->innerPanel)) { $temp->addParam('innerPanel', $this->request->innerPanel); } $inhalte[$region->re_name][] = $temp; } foreach ($inhalte as $name => $region) { $html = ''; foreach ($region as $aktRegion) { $html .= $aktRegion->toHtml(); } $this->controls->setVar($name, $html); } }
protected function createControls() { $panel = new CaptionedPanelControl($this, 'panel'); $panel->setCaption('Teilen von Dateien'); $upload = new UploaderControl($panel); $upload->setAction('uploadShare'); $upload->setNotify('medien'); $size = "<?php echo round({me_groesse}/1024/1024,1); ?> MB"; $sendLink = Configuration::get('site.url') . '/index.php/medien/get?token={me_token}'; $send = "<a class='btn-xs btn-default' href='mailto:?body=" . $sendLink . "'><span class='glyphicon glyphicon-envelope'></span></a>"; $editLink = Application::routing()->appLink('medien', 'editShare', array('id' => '{me_id}')); $edit = "<a class='btn-xs btn-default' href=" . $editLink . "><span class='glyphicon glyphicon-edit'></span></a>"; $buttons = $send . $edit; $token = new InputTextboxControl(null); $token->setValue($sendLink)->addCssClass('input-sm'); $valid = "<?php echo ((strtotime('{me_valid_until}')) < strtotime(date('d.m.Y'))) ? '<span style=\"color: red;\">Abgelaufen</span>' : '{me_valid_until}'; ?>"; $downloads = "<?php echo '{me_downloads}' == '' ? 0 : {me_downloads}?>"; $medien = new GridControl($panel, 'medien'); $medien->setEntity(new Medien(), array('share' => 1)); $medien->setDeleteAction('deleteMedien'); $medien->createColumn(GridColumn::LINK, 'me_titel')->setAppLink('medien', 'editShare', array('id' => '{me_id}')); $medien->createColumn(GridColumn::FIELD, 'me_erweiterung')->setHeader('Typ'); $medien->createColumn(GridColumn::FIELD, 'me_groesse', $size); $medien->createColumn(GridColumn::FIELD, 'me_token', $token->toHtml())->setHeader('Download-Link'); $medien->createColumn(GridColumn::FIELD, 'me_downloads', $downloads); $medien->createColumn(GridColumn::FIELD, 'me_valid_until', $valid); $medien->createColumn(GridColumn::FIELD, 'me_titel', $buttons)->setHeader(''); $medien->createColumn(GridColumn::DELETELINK); $hinweis = new CoreControls\HtmlControl($this); $hinweis->setInnerHtml("<span style='color: #AAA;'><b>Hinweis:</b> Abgelaufene Dateien werden nach 14 Tagen automatisch gelöscht.</span>"); }
public function explainQuery() { if (!Debug::isEnabled()) { FlashMessage::danger('Zugriff verweigert'); Application::getCurrentResponse()->redirectToFrontpage(); } // TODO }
/** * @inheritdoc */ public function init() { Javascript::requireLibrary('froala'); return; Javascript::requireLibrary('ckeditor'); Javascript::requireLibrary('ckfinder'); if (Application::getCurrentRequest()->admin) { $this->toolbar = self::TOOLBAR_LARGE; } }
protected function createControls() { $rootRegions = Region::loadByPageAndParent(Application::currentPage()->id, 0); foreach ($rootRegions as $region) { $control = $region->getBlock(); if ($control !== null) { $this->add($control); } } }
public function toHtml() { $name = $this->id; $this->setVar('css', $this->getCssString()); $this->setVar('id', $this->id); $this->setVar('placeholder', $this->placeholder); if (isset(Application::getCurrentRequest()->{$name})) { $this->setVar('value', Application::getCurrentRequest()->{$name}); } return $this->renderBySkin(); }
protected function createControls() { if (!isset($this->request->page)) { $page = Application::currentPage()->id; } else { $page = new Page($this->request->page); } $panel = new StdControls\CaptionedPanelControl($this, 'panel'); $panel->setCaption($page->pa_bezeichnung); $menu = new SiteMenuControl($this, 'submenu'); $menu->setRootPage($page); }
public function showPage() { if (!isset($this->page)) { $this->site = new Site($this->request->site); } else { $this->site = new Site($this->page->pa_site); } Routing::resetBreadcrumbs(); Routing::addBreadcrumb('Struktur'); Routing::addBreadcrumb($this->site->si_bezeichnung, '/site/showPage/site' . $this->site->id); Application::getCurrentResponse()->heading = 'Seiten'; }
/** * Führt einen 301 HTTP Redirect aus und beendet das Script sofort * @param string $newUrl */ public static function redirect($newUrl) { // FlashMessages in Session an neue Seite übertragen übertragen if (count(Application::getInstance()->flashMessages) > 0) { $_SESSION['flashMessages'] = Application::getInstance()->flashMessages; } if (!headers_sent()) { header('Location: ' . $newUrl); die; } else { throw new \RuntimeException("Redirect nach {$newUrl} kann nicht ausgeführt werden, da die Header bereits\n gesendet wurden."); } }
/** * Füllt das Request-Objekt auf Basis des Pathinfo. * @param $request * @param string $pathinfo */ public function fillRequestByPathinfo(&$request, $pathinfo) { Profiler::startSection('SiteRouting.fillRequestByPathInfo'); $page = null; if ($pathinfo !== '') { $page = Page::loadByLink(Application::currentSiteId(), $pathinfo); } if ($page !== null) { $this->setCurrentPage($request, $page); } else { parent::fillRequestByPathinfo($request, $pathinfo); } Profiler::endSection('SiteRouting.fillRequestByPathInfo'); }
public function init() { Javascript::requireLibrary('bootstrap'); $this->defaultSkinFile = __DIR__ . '/TabControl.skin'; if (isset(Application::getInstance()->getRequest()->initPanel)) { $this->initPanel = Application::getInstance()->getRequest()->initPanel; } $key = 'tab_active_' . $this->id; if (isset(Application::getInstance()->getRequest()->{$key}) && Application::getInstance()->getRequest()->{$key} != '') { $this->activePanel = Application::getInstance()->getRequest()->{$key}; } else { if ($this->initPanel < 0) { $this->initPanel = 0; } } }
/** * @covers \NewFrontiers\Framework\Output\FlashMessage::__construct * @covers \NewFrontiers\Framework\Output\FlashMessage::toHtml * @covers \NewFrontiers\Framework\Output\FlashMessage::danger * @covers \NewFrontiers\Framework\Output\FlashMessage::info * @covers \NewFrontiers\Framework\Output\FlashMessage::success * @covers \NewFrontiers\Framework\Output\FlashMessage::warning */ public function testDefaultMessages() { Application::getInstance()->flashMessages = []; FlashMessage::danger("danger-Meldung"); $danger = end(Application::getInstance()->flashMessages); FlashMessage::info("info-Meldung"); $info = end(Application::getInstance()->flashMessages); FlashMessage::success("success-Meldung"); $success = end(Application::getInstance()->flashMessages); FlashMessage::warning("warning-Meldung"); $warning = end(Application::getInstance()->flashMessages); //At least the message should appear in the result $this->assertContains("danger-Meldung", $danger->toHtml()); $this->assertContains("info-Meldung", $info->toHtml()); $this->assertContains("success-Meldung", $success->toHtml()); $this->assertContains("warning-Meldung", $warning->toHtml()); }
protected function createControls() { $button = new ButtonControl($this, 'button'); $button->setCaption('Neuen Artikel anlegen')->setIcon('plus')->setButtonClass(ButtonControl::BUTTON_PRIMARY)->setLink('cms', 'newArtikel', array('kategorie' => $this->controller->kategorie->id)); $button = new ButtonControl($this, 'btnSort'); $button->setCaption('Artikel neu sortieren')->setLink('cms', 'sortArtikel', array('kategorie' => $this->controller->kategorie->id)); $template = ' {ca_pos} <a href="' . Application::link('cms', 'posUp') . '/id/{ca_id}">' . Template::img('icons/arrow_up.png', true) . '</a> <a href="' . Application::link('cms', 'posDown') . '/id/{ca_id}">' . Template::img('icons/arrow_down.png', true) . '</a> '; $grid = new GridControl($this, 'grid'); $grid->setEntity(new Model\CmsArtikel(), $this->request); $grid->setDeleteAction('deleteArtikel'); $grid->setSortable(true); $grid->createColumn(GridColumn::LINK, 'ca_bezeichnung')->setAppLink('cms', 'editArtikel', array('id' => '{ca_id}')); $grid->createColumn(GridColumn::FIELD, 'ca_aktiv'); $grid->createColumn(GridColumn::FIELD, 'autor'); $grid->createColumn(GridColumn::FIELD, 'ca_geschrieben_am'); $grid->createColumn(GridColumn::FIELD, 'ca_lastedit'); $grid->createColumn(GridColumn::FIELD, 'ca_pos', $template); $grid->createColumn(GridColumn::LINK, null, Template::img('icons/sitemap_color.png', true))->setAppLink('site', 'newPage', array('site' => 2, 'mi_module' => 'cms', 'mi_action' => 'show', 'mi_id' => '{ca_id}', 'text' => '{ca_bezeichnung}'), null, 'Zu Sitemap hinzufügen'); $grid->createColumn(GridColumn::DELETELINK); }
protected function createControls() { $grp = new ButtonGroupControl($this, 'btngrp'); $button = new ButtonControl($grp, 'button'); $button->setButtonClass(ButtonControl::BUTTON_PRIMARY)->setCaption('Neue Seite anlegen')->setIcon('plus')->setLink('site', 'newPage', array('site' => $this->controller->site->id)); $button = new ButtonControl($grp, 'btnSort'); $button->setCaption('Seiten neu sortieren')->setLink('site', 'sortPages', array('site' => $this->controller->site->id)); $button = new ButtonControl($grp, 'btnFlush'); $button->setCaption('Cache leeren')->setLink('site', 'flushCache', array('site' => $this->controller->site->id)); $grid = new GridControl($this, 'grid'); $grid->setEntity(new Page(), $this->request); $grid->setDeleteAction('deletePage'); $grid->setSortable(false); $template = ' {pa_pos} <a href="' . Application::link('site', 'pageUp') . '/id/{pa_id}">' . Template::img('icons/arrow_up.png', true) . '</a> <a href="' . Application::link('site', 'pageDown') . '/id/{pa_id}">' . Template::img('icons/arrow_down.png', true) . '</a> '; $grid->createColumn(GridColumn::LINK, 'pa_bezeichnung')->setAppLink('site', 'editPage', array('id' => '{pa_id}')); $grid->createColumn(GridColumn::FIELD, 'parent'); $grid->createColumn(GridColumn::FIELD, 'pa_pos', $template); $grid->createColumn(GridColumn::DELETELINK); $grid->groupColumn = 1; }
protected function createControls() { /** * @var CmsArtikel $artikel */ $artikel = $this->controller->artikel; $titel = Text::get($artikel->getElementId() . '.titel', $_SESSION['sp_id'])->te_text; $text = Text::get($artikel->getElementId() . '.intro', $_SESSION['sp_id'])->te_text; $wiki = new CmsArtikelWikiLinks(); $wiki->setKategorieId(2); // TODO $wiki->setText($text); $text = $wiki->getText(); if (Application::isAdmin()) { $editButton = new ButtonControl($this, 'btnEdit' . $artikel->id); $editButton->setCaption('Bearbeiten')->setIcon('pencil')->setLink('Cms', 'editArtikel', ['id' => $artikel->id])->setButtonClass(ButtonControl::BUTTON_WARNING)->setSize(ButtonControl::SIZE_EXTRASMALL)->addCssClass('pull-right'); } // TODO if (false) { // ($titel != '') { $artikelPanel = new CaptionedPanelControl($this, 'artikel_' . $artikel->id); $artikelPanel->setCaption($titel); if ($artikel->ca_hauptbild == '') { $artikelText = new HtmlControl($artikelPanel, 'text_' . $artikel->id); $artikelText->setInnerHtml($text); } else { $artikelText = new HtmlControl($artikelPanel, 'text_' . $artikel->id); $artikelText->setInnerHtml(' <img src="' . $artikel->ca_hauptbild . '" class="blogimage" /> ' . $text); } } else { $artikelText = new HtmlControl($this, 'text_' . $artikel->id); $artikelText->setInnerHtml($text); } }
protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, $index = null, $content_range = null) { // TODO: Refactor! if (isset(Application::getCurrentRequest()->target) && Application::getCurrentRequest()->target != '') { $name = Application::getCurrentRequest()->target; } $file = parent::handle_file_upload($uploaded_file, $name, $size, $type, $error, $index, $content_range); if (empty($file->error) && $this->kollektionId > 0) { $medium = new Medien(); $medium->me_kollektion = $this->kollektionId; $medium->me_titel = $file->name; $medium->me_dateiname = $file->name; $medium->me_erweiterung = strtolower(substr(strrchr($name, '.'), 1)); $medium->me_groesse = $file->size; $medium->me_upload_am = date('d.m.Y'); $medium->me_upload_von = Security::getUserId(); if (isset(Application::getCurrentRequest()->token) && Application::getCurrentRequest()->token != '') { $medium->me_token = Application::getCurrentRequest()->token; } $medium->save(); $file->id = $medium->id; } return $file; }
/** * Fügt dem Container für die anzuzeigenden FlashMessages eine Message hinzu * * @param $message FlashMessage */ public static function addFlashMessage(FlashMessage $message) { Application::getInstance()->flashMessages[] = $message; }
/** * Rahmen zum Ausführen einer Funktion. Konkrete Ausführeung wird * von abstrakter Methode executeAction ausgeführt * @param $request * @return Response * @throws Exception */ public function execute($request) { // Der Response wird direkt am Anfang erzeugt und auch in der Application-Klasse // hinterlegt. Das muss aus Gründen der Abwärtskompatibilität sein. In den Controller // Methiden wird oft auf Application::currentResponse zurückgegriffen. Das muss an // dieser Stelle also gefüllt sein. Logging::info("Ausführen von [{$this->request->module}:{$this->request->action}]"); Profiler::startSection($this->request->module . '.' . $this->request->action); $this->request = $request; $this->response = new Response(); Application::getInstance()->setResponse($this->response); $this->currentAction = $this->module->getAction($this->request->action); // Abbrechen, wenn Aktion nicht gefunden werden konnte if ($this->currentAction === null) { throw new \DomainException("Aktion '{$this->request->action}' in Modul '{$this->request->module}' nicht gefunden"); } else { // Verhindern, dass von einem Angreifer eine beliebige Seite aufgerufen werden // kann $this->request->view = null; // Response mit den Standard-Daten füllen $this->response->setContent($this->currentAction->getDefaultNext($this)); $result = $this->innerExecute(); if ($result !== null) { $this->response = $result; } // Jetzt kann sich unter Umständen der View geändert haben if ($this->request->view !== null) { Logging::warning('anderen View laden'); $this->response->setContent($this->module->loadView($this->request->view, $this)); } // Überschreiben der eigentlichen Aktion durch eine, die bei der Ausführung der Funktion // gesetzt wurde if ($this->request->action !== $this->currentAction->name) { Logging::warning('Andere Action ausführen'); $this->response->setContent($this->module->getAction($this->request->action)); } Profiler::endSection($this->request->module . '.' . $this->request->action); return $this->response; } }
/** * Gibt den Inhalt des aktullen App-Requests aus * @return Control */ public function showNfsRequest() { $i = 0; $panel = new SimplePanelControl(null, 'debugNfsReq'); $this->addRequest($panel, Application::getCurrentRequest(), $i); return $panel; }
/** * Singleton-Funktion * @return Database aktuelle Instanz */ public static function getInstance() { if (self::$instance === null) { self::$instance = Application::resolve('default_database'); } return self::$instance; }
<?php /** * Copyright (c) new frontiers Software GmbH */ use NewFrontiers\Framework\Core\Application; // Setzen des Working-Dir für die PHPUnit Tests // und registrieren des Autoloaders chdir(__DIR__ . '/../src'); require __DIR__ . '/../vendor/autoload.php'; // PHP Einstellungen anpassen setlocale(LC_ALL, 'german', 'de_DE', 'de', 'deu'); date_default_timezone_set('Europe/Berlin'); mb_internal_encoding('UTF-8'); // Minimale Menge der Services instanziieren Application::register('logging', new \NewFrontiers\Provider\Logging\MemoryLoggingProvider()); Application::register('dispatcher', new Symfony\Component\EventDispatcher\EventDispatcher());
public function indexUser() { Application::getCurrentResponse()->heading = 'Benutzer'; }
/** * Gibt das HTML Markup aus. Die Funktion hinter dem Wrapper wird jetzt erst aufgerufen! * @return string * @throws Exception */ public function toHtml() { // Erzeugen des neuen Requests $request = Application::getCurrentRequest()->createSubRequest(); $request->module = $this->module; $request->action = $this->action; $request->embedded = true; $request->setViaArray($this->param); $module = Modules::getModule($this->module); if ($module == null) { throw new Exception("[Wrapper] Modul {$this->module} konnte nicht geladen werden"); } $controller = $module->createController($request); if ($controller->hatBerechtigung()) { $response = $controller->execute($request); Logging::warning((string) $response->getContent()); if ($response->getContent() instanceof View) { $result = '<div id="' . $this->id . '" class="wrapper">' . $response->getContent()->render() . '</div>'; } else { $result = 'NO VIEW'; } } else { $result = '<div class="alert alert-danger">Für diese Funktion haben Sie keine ausreichende Berechtigung</div>'; } // Ergebnis in einem Panel verpacken if ($this->showInPanel) { $panel = new CaptionedPanelControl(null, 'panel-' . $this->id); $panel->setCaption($this->panelCaption); $panel->setCollapsed($this->panelCollapsed); $html = new HtmlControl($panel); $html->setInnerHtml($result); $result = $panel->toHtml(); } return $result; }
/** * Magische Methode, die von PHP beim Deserialisieren des Objekts aufgerufen wird */ public function __wakeup() { // Verbindung zud DB wieder herstellen $this->db = Application::resolve($this->getDatabaseServiceName()); }
/** * Daten anzeigen * @return string HTML-String der Datenzeilen */ private function getDaten() { $tbody = Html::create('tbody'); $i = 0; $groupValue = null; $addedRow = false; $summe = 0; Logging::debug('Verwende DB-Service: ' . $this->entity->getDatabaseServiceName()); $db = Application::resolve($this->entity->getDatabaseServiceName()); while ($row = $db->fetch()) { $addedRow = true; // Daten in Entität laden, damit die formatierten Feldwerte zur Verfügung stehen $this->entity->loadFromRow($row); // Gruppieren if ($this->groupColumn > -1 && $groupValue != $this->columns[$this->groupColumn]->getData($row)) { $colcount = count($this->columns); if (!$this->renderGrouped) { $colcount--; } $i = 0; $groupValue = $this->columns[$this->groupColumn]->getData($row); $th = Html::create('th')->addAttribute('colspan', $colcount)->text($groupValue); $tr = Html::create('tr')->css('groupHeader')->text($th); $tbody->text($tr); } if ($this->sum > -1) { $summe += $this->columns[$this->sum]->getRawData($row); } $tr = Html::create('tr')->addAttribute('data-id', $this->entity->id); // Callable aufrufen um Klasse der Zeile zu ermitteln if (isset($this->rowClassCallable)) { $callable = $this->rowClassCallable; $tr->css($callable($this->entity)); } $j = 0; foreach ($this->columns as $column) { if ($this->renderGrouped || $j != $this->groupColumn) { $td = Html::create('td')->css($column->getCssClass())->text($column->getData($row)); if ($column->getNoWrap()) { $td->css('nowrap'); } $tr->text($td); } $j++; } // spalten $tbody->text($tr); $i++; } // zeilen // Summe rendern if ($this->sum > -1) { $tr = Html::create('tr'); $j = 0; foreach ($this->columns as $column) { if ($this->renderGrouped || $j != $this->groupColumn) { if ($j == $this->sum) { $td = Html::create('td')->css($column->getCssClass())->text('<strong>' . number_format($summe, 2, ',', '.') . '</strong>'); } else { $td = Html::create('td')->css($column->getCssClass())->text(' '); } if ($column->getNoWrap()) { $td->css('nowrap'); } $tr->create($td); } $j++; } // spalten $tbody->text($tr); } if ($addedRow) { return $tbody; } else { return null; } }
echo Application::getInstance()->response->getMetadata()->getHeading(); ?> </h2> <?php $bc = new BreadcrumbControl(null, 'bc'); echo $bc->toHtml(); ?> </div> </div> <!-- Content --> <div class="wrapper wrapper-content animated fadeInRight"> <?php Application::getInstance()->displayMain(); ?> </div> <!-- Footer --> <div class="footer"> <div class="pull-right"> <!--<a href="http://www.apiida.de" target="_blank">www.apiida.de</a>--> </div> <div> <!--Made with love by <strong>Apiida</strong>--> </div> </div>
<?php use NewFrontiers\Framework\Core\ConfigurationProvider; use NewFrontiers\Framework\Database\Database; use Nostromo\Contracts\Facades\Configuration; use NewFrontiers\Framework\Core\Application; use Symfony\Component\EventDispatcher\EventDispatcher; // Registrieren der benötigten Services Application::register('configuration', ConfigurationProvider::getInstance()); Application::register('module', new \NewFrontiers\Provider\Module\XmlModuleProvider()); Application::register('logging', new \NewFrontiers\Provider\Logging\MemoryLoggingProvider()); Application::register('routing', new \NewFrontiers\Provider\Routing\SitemapRoutingProvider()); Application::register('security', new \NewFrontiers\Provider\Security\SqlSecurityProvider()); Application::register('cache', new NewFrontiers\Provider\Cache\SessionCacheProvider()); Application::register('dispatcher', new EventDispatcher()); Application::register('default_database', new Database()); // Datenbank-Engine auf MySQL setzen Database::getInstance()->setEngine(Configuration::get('database.engine', Database::DB_MYSQL));
/** * Runtime errors that do not require immediate action but should typically * be logged and monitored. * * @param string $message * @param array|string $context */ public function error($message, array $context = array()) { $context = ''; if (Application::getCurrentRequest() !== null) { $context = print_r(Application::getCurrentRequest()->getFullArray(), true); } error_log($message . "\r\n" . $context); $this->log(LoggingProvider::LOG_ERROR, $message . "\r\n" . $context); }
public function search() { // TODO: Was macht das denn hier? Application::getInstance()->setCurrentPage(new Page(98)); $sql = "select\n pa_bezeichnung, pa_link, te_text \n from cmsartikel\n join texte on te_element = CONCAT('cmsartikel.', ca_id, '.intro') and te_sprache = 1\n join pages on pa_parameter = CONCAT('id=', ca_id)\n \n where upper(te_text) like upper(:suchbegriff)"; $db = Database::getInstance(); $db->query($sql, array('suchbegriff' => '%' . $this->request->suchbegriff . '%')); $this->hits = array(); while ($row = $db->fetch()) { $this->hits[] = array('page' => $row['pa_bezeichnung'], 'link' => $row['pa_link'], 'text' => $this->getShortText($row['te_text'])); } }