/** * Register settings templates */ public function registerSettings() { $container = $this->getContainer(); $backendService = $container->query('OCA\\Files_External\\Service\\BackendService'); \OCP\App::registerAdmin('files_external', 'settings'); \OCP\App::registerPersonal('files_external', 'personal'); }
/** * @brief clean up user specific settings if user gets deleted * @param array with uid * * This function is connected to the pre_deleteUser signal of OC_Users * to remove the used space for the trash bin stored in the database */ public static function deleteUser_hook($params) { if (\OCP\App::isEnabled('files_trashbin')) { $uid = $params['uid']; Trashbin::deleteUser($uid); } }
/** * Returns a list of calendars for a principal. * * Every project is an array with the following keys: * * id, a unique id that will be used by other functions to modify the * calendar. This can be the same as the uri or a database key. * * uri, which the basename of the uri with which the calendar is * accessed. * * principalUri. The owner of the calendar. Almost always the same as * principalUri passed to this method. * * Furthermore it can contain webdav properties in clark notation. A very * common one is '{DAV:}displayname'. * * @param string $principalUri * @return array */ public function getCalendarsForUser($principalUri) { $raw = OC_Calendar_Calendar::allCalendarsWherePrincipalURIIs($principalUri); $calendars = array(); foreach ($raw as $row) { $components = explode(',', $row['components']); if ($row['userid'] != OCP\USER::getUser()) { $row['uri'] = $row['uri'] . '_shared_by_' . $row['userid']; } $calendar = array('id' => $row['id'], 'uri' => $row['uri'], 'principaluri' => 'principals/' . $row['userid'], '{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => $row['ctag'] ? $row['ctag'] : '0', '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new \Sabre\CalDAV\Property\SupportedCalendarComponentSet($components)); foreach ($this->propertyMap as $xmlName => $dbName) { $calendar[$xmlName] = isset($row[$dbName]) ? $row[$dbName] : ''; } $calendars[] = $calendar; } if (\OCP\App::isEnabled('contacts')) { $ctag = 0; $app = new \OCA\Contacts\App(); $addressBooks = $app->getAddressBooksForUser(); foreach ($addressBooks as $addressBook) { $tmp = $addressBook->lastModified(); if (!is_null($tmp)) { $ctag = max($ctag, $tmp); } } $ctag++; $calendars[] = array('id' => 'contact_birthdays', 'uri' => 'contact_birthdays', '{DAV:}displayname' => (string) OC_Calendar_App::$l10n->t('Contact birthdays'), 'principaluri' => 'principals/contact_birthdays', '{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => $ctag, '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new \Sabre\CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT')), '{http://apple.com/ns/ical/}calendar-color' => '#CCCCCC'); } return $calendars; }
/** * Tells ownCloud to include a template in the personal overview * @param string $mainPath the path to the main php file without the php * suffix, relative to your apps directory! not the template directory * @param string $appName the name of the app, defaults to the current one */ public function registerPersonal($mainPath, $appName = null) { if ($appName === null) { $appName = $this->appName; } \OCP\App::registerPersonal($appName, $mainPath); }
/** * @param array $arguments */ public function run($arguments) { if (!App::isEnabled('search_lucene')) { return; } $app = new Application(); $container = $app->getContainer(); /** @var Logger $logger */ $logger = $container->query('Logger'); if (empty($arguments['user'])) { $logger->debug('indexer job did not receive user in arguments: ' . json_encode($arguments)); return; } $userId = $arguments['user']; $logger->debug('background job optimizing index for ' . $userId); $container->query('FileUtility')->setUpIndexFolder($userId); /** @var Index $index */ $index = $container->query('Index'); /** @var StatusMapper $mapper */ $mapper = $container->query('StatusMapper'); $deletedIds = $mapper->getDeleted(); $count = 0; foreach ($deletedIds as $fileId) { $logger->debug('deleting status for (' . $fileId . ') '); //delete status $status = new Status($fileId); $mapper->delete($status); //delete from lucene $count += $index->deleteFile($fileId); } $logger->debug('removed ' . $count . ' files from index'); }
/** * Asynchronously scan data that are written to the file * @param string $path * @param string $mode * @return resource | bool */ public function fopen($path, $mode) { $stream = $this->storage->fopen($path, $mode); if (is_resource($stream) && $this->isWritingMode($mode)) { try { $scanner = $this->scannerFactory->getScanner(); $scanner->initAsyncScan(); return CallBackWrapper::wrap($stream, null, function ($data) use($scanner) { $scanner->onAsyncData($data); }, function () use($scanner, $path) { $status = $scanner->completeAsyncScan(); if (intval($status->getNumericStatus()) === \OCA\Files_Antivirus\Status::SCANRESULT_INFECTED) { //prevent from going to trashbin if (App::isEnabled('files_trashbin')) { \OCA\Files_Trashbin\Storage::preRenameHook([]); } $owner = $this->getOwner($path); $this->unlink($path); if (App::isEnabled('files_trashbin')) { \OCA\Files_Trashbin\Storage::postRenameHook([]); } \OC::$server->getActivityManager()->publishActivity('files_antivirus', Activity::SUBJECT_VIRUS_DETECTED, [$path, $status->getDetails()], Activity::MESSAGE_FILE_DELETED, [], $path, '', $owner, Activity::TYPE_VIRUS_DETECTED, Activity::PRIORITY_HIGH); throw new InvalidContentException($this->l10n->t('Virus %s is detected in the file. Upload cannot be completed.', $status->getDetails())); } }); } catch (\Exception $e) { $message = implode(' ', [__CLASS__, __METHOD__, $e->getMessage()]); $this->logger->warning($message); } } return $stream; }
/** * get list of users with access to the file * * @param string $path to the file * @return array */ public function getAccessList($path) { // Make sure that a share key is generated for the owner too list($owner, $ownerPath) = $this->util->getUidAndFilename($path); // always add owner to the list of users with access to the file $userIds = array($owner); if (!$this->util->isFile($ownerPath)) { return array('users' => $userIds, 'public' => false); } $ownerPath = substr($ownerPath, strlen('/files')); $ownerPath = $this->util->stripPartialFileExtension($ownerPath); // Find out who, if anyone, is sharing the file $result = \OCP\Share::getUsersSharingFile($ownerPath, $owner); $userIds = \array_merge($userIds, $result['users']); $public = $result['public'] || $result['remote']; // check if it is a group mount if (\OCP\App::isEnabled("files_external")) { $mounts = \OC_Mount_Config::getSystemMountPoints(); foreach ($mounts as $mount) { if ($mount['mountpoint'] == substr($ownerPath, 1, strlen($mount['mountpoint']))) { $mountedFor = $this->util->getUserWithAccessToMountPoint($mount['applicable']['users'], $mount['applicable']['groups']); $userIds = array_merge($userIds, $mountedFor); } } } // Remove duplicate UIDs $uniqueUserIds = array_unique($userIds); return array('users' => $uniqueUserIds, 'public' => $public); }
/** * Search for query in calendar events * * @param string $query * @return array list of \OCA\Calendar\Search\Event */ function search($query) { $calendars = \OC_Calendar_Calendar::allCalendars(\OCP\USER::getUser(), true); // check if the calenar is enabled if (count($calendars) == 0 || !\OCP\App::isEnabled('calendar')) { return array(); } $results = array(); foreach ($calendars as $calendar) { $objects = \OC_Calendar_Object::all($calendar['id']); $date = strtotime($query); // search all calendar objects, one by one foreach ($objects as $object) { // skip non-events if ($object['objecttype'] != 'VEVENT') { continue; } // check the event summary string if (stripos($object['summary'], $query) !== false) { $results[] = new \OCA\Calendar\Search\Event($object); continue; } // check if the event is happening on a queried date $range = $this->getDateRange($object); if ($date && $this->fallsWithin($date, $range)) { $results[] = new \OCA\Calendar\Search\Event($object); continue; } } } return $results; }
public function __construct(array $urlParams = []) { parent::__construct('updater', $urlParams); $container = $this->getContainer(); /** * Controllers */ $container->registerService('UpdateController', function ($c) { return new UpdateController($c->query('AppName'), $c->query('Request'), $c->query('L10N')); }); $container->registerService('BackupController', function ($c) { return new BackupController($c->query('AppName'), $c->query('Request'), $c->query('Config'), $c->query('L10N')); }); $container->registerService('AdminController', function ($c) { return new AdminController($c->query('AppName'), $c->query('Request'), $c->query('Config'), $c->query('L10N')); }); $container->registerService('L10N', function ($c) { return $c->query('ServerContainer')->getL10N($c->query('AppName')); }); $container->registerService('Config', function ($c) { return new Config($c->query('ServerContainer')->getConfig()); }); $container->registerService('Channel', function ($c) { return new Channel($c->query('L10N')); }); //Startup if (\OC_Util::getEditionString() === '') { \OCP\App::registerAdmin('updater', 'admin'); $appPath = $container->query('Config')->getBackupBase(); if (!@file_exists($appPath)) { Helper::mkdir($appPath); } } }
/** * @brief clean up user specific settings if user gets deleted * @param array with uid * * This function is connected to the pre_deleteUser signal of OC_Users * to remove the used space for versions stored in the database */ public static function deleteUser_hook($params) { if (\OCP\App::isEnabled('files_versions')) { $uid = $params['uid']; Storage::deleteUser($uid); } }
/** * Registers all config options */ public function registerAll() { $this->registerNavigation(); $this->registerHooks(); // F**k it lets just do this quick and dirty until core supports this Backgroundjob::addRegularTask($this->config['cron']['job'], 'run'); App::registerAdmin($this->config['id'], $this->config['admin']); }
public static function run() { if (!\OCP\App::isEnabled('files_antivirus')) { return; } $application = new Application(); $container = $application->getContainer(); $container->query('BackgroundScanner')->run(); }
/** * rename/move versions of renamed/moved files * @param array $params array with oldpath and newpath * * This function is connected to the rename signal of OC_Filesystem and adjust the name and location * of the stored versions along the actual file */ public static function rename_hook($params) { if (\OCP\App::isEnabled('files_versions')) { $oldpath = $params['oldpath']; $newpath = $params['newpath']; if ($oldpath != '' && $newpath != '') { Storage::rename($oldpath, $newpath); } } }
/** * @param array $parameters * @return OC_OCS_Result */ public function getAppInfo($parameters) { $app = $parameters['appid']; $info = \OCP\App::getAppInfo($app); if (!is_null($info)) { return new OC_OCS_Result(OC_App::getAppInfo($app)); } else { return new OC_OCS_Result(null, \OCP\API::RESPOND_NOT_FOUND, 'The request app was not found'); } }
/** * Get an layer * @NoAdminRequired * @NoCSRFRequired */ public function getlayer() { $layer = $this->params('layer') ? $this->params('layer') : null; if ($layer === "contacts") { if (\OCP\App::isEnabled('contacts')) { } else { OCP\Util::writeLog('maps', "App contacts missing for Maps", \OCP\Util::WARN); } } }
/** * @param array $arguments */ public function run($arguments) { if ((\OCP\App::isEnabled('contacts') || \OCP\App::isEnabled('contactsplus')) && \OCP\App::isEnabled('fbsync')) { $cache = \OC::$server->getCache(); $cache->set("test", "test"); } else { \OCP\Util::writeLog('fbsync', "App not enabled", \OCP\Util::INFO); return; } }
public function setup() { App::checkAppEnabled('files_locking'); OC_User::clearBackends(); OC_User::useBackend(new OC_User_Dummy()); // Login OC_User::createUser('test', 'test'); $this->user = OC_User::getUser(); OC_User::setUserId('test'); $this->storage = $this->getTestStorage(); }
private static function getUidAndFilename($filename) { if (\OCP\App::isEnabled('files_sharing') && substr($filename, 0, 7) == '/Shared' && ($source = \OCP\Share::getItemSharedWith('file', substr($filename, 7), \OC_Share_Backend_File::FORMAT_SHARED_STORAGE))) { $filename = $source['path']; $pos = strpos($filename, '/files', 1); $uid = substr($filename, 1, $pos - 1); $filename = substr($filename, $pos + 6); } else { $uid = \OCP\User::getUser(); } return array($uid, $filename); }
public static function init() { self::$l10n = \OCP\Util::getL10N(self::APP_ID); \OC::$CLASSPATH['OCA\\Updater\\Backup'] = self::APP_ID . '/lib/backup.php'; \OC::$CLASSPATH['OCA\\Updater\\Downloader'] = self::APP_ID . '/lib/downloader.php'; \OC::$CLASSPATH['OCA\\Updater\\Updater'] = self::APP_ID . '/lib/updater.php'; \OC::$CLASSPATH['OCA\\Updater\\Helper'] = self::APP_ID . '/lib/helper.php'; \OC::$CLASSPATH['OCA\\Updater\\Location'] = self::APP_ID . '/lib/location.php'; \OC::$CLASSPATH['OCA\\Updater\\Location_3rdparty'] = self::APP_ID . '/lib/location/3rdparty.php'; \OC::$CLASSPATH['OCA\\Updater\\Location_Apps'] = self::APP_ID . '/lib/location/apps.php'; \OC::$CLASSPATH['OCA\\Updater\\Location_Core'] = self::APP_ID . '/lib/location/core.php'; //Allow config page \OCP\App::registerAdmin(self::APP_ID, 'admin'); }
public static function check() { if (!\OCP\App::isEnabled('files_antivirus')) { return; } // get mimetype code for directory $query = \OCP\DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'); $result = $query->execute(array('httpd/unix-directory')); if ($row = $result->fetchRow()) { $dir_mimetype = $row['id']; } else { $dir_mimetype = 0; } // locate files that are not checked yet $sql = 'SELECT `*PREFIX*filecache`.`fileid`, `path`, `*PREFIX*storages`.`id`' . ' FROM `*PREFIX*filecache`' . ' LEFT JOIN `*PREFIX*files_antivirus` ON `*PREFIX*files_antivirus`.`fileid` = `*PREFIX*filecache`.`fileid`' . ' JOIN `*PREFIX*storages` ON `*PREFIX*storages`.`numeric_id` = `*PREFIX*filecache`.`storage`' . ' WHERE `mimetype` != ?' . ' AND (`*PREFIX*storages`.`id` LIKE ? OR `*PREFIX*storages`.`id` LIKE ?)' . ' AND (`*PREFIX*files_antivirus`.`fileid` IS NULL OR `mtime` > `check_time`)' . ' AND `path` LIKE ?'; $stmt = \OCP\DB::prepare($sql, 5); try { $result = $stmt->execute(array($dir_mimetype, 'local::%', 'home::%', 'files/%')); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return; } } catch (\Exception $e) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); return; } $serverContainer = \OC::$server; /** @var $serverContainer \OCP\IServerContainer */ $root = $serverContainer->getRootFolder(); // scan the found files while ($row = $result->fetchRow()) { $file = $root->getById($row['fileid']); // this should always work ... if (!empty($file)) { $file = $file[0]; $storage = $file->getStorage(); $path = $file->getInternalPath(); self::scan($file->getId(), $path, $storage); } else { // ... but sometimes it doesn't, try to get the storage $storage = self::getStorage($serverContainer, $row['id']); if ($storage !== null && $storage->is_dir('')) { self::scan($row['fileid'], $row['path'], $storage); } else { \OCP\Util::writeLog('files_antivirus', 'Can\'t get \\OCP\\Files\\File for id "' . $row['fileid'] . '"', \OCP\Util::ERROR); } } } }
/** * Search for query in tasks * * @param string $query * @return array list of \OCA\Tasks\Controller\Task */ function search($query) { $calendars = \OC_Calendar_Calendar::allCalendars(\OC::$server->getUserSession()->getUser()->getUID(), true); $user_timezone = \OC_Calendar_App::getTimezone(); // check if the calenar is enabled if (count($calendars) == 0 || !\OCP\App::isEnabled('tasks')) { return array(); } $results = array(); foreach ($calendars as $calendar) { // $calendar_entries = \OC_Calendar_Object::all($calendar['id']); $objects = \OC_Calendar_Object::all($calendar['id']); // $date = strtotime($query); // // search all calendar objects, one by one foreach ($objects as $object) { // skip non-todos if ($object['objecttype'] != 'VTODO') { continue; } if (!($vtodo = Helper::parseVTODO($object))) { continue; } $id = $object['id']; $calendarId = $object['calendarid']; // check these properties $properties = array('SUMMARY', 'DESCRIPTION', 'LOCATION', 'CATEGORIES'); foreach ($properties as $property) { $string = $vtodo->{$property}; if (stripos($string, $query) !== false) { // $results[] = new \OCA\Tasks\Controller\Task($id,$calendarId,$vtodo,$property,$query,$user_timezone); $results[] = Helper::arrayForJSON($id, $vtodo, $user_timezone, $calendarId); continue 2; } } $comments = $vtodo->COMMENT; if ($comments) { foreach ($comments as $com) { if (stripos($com->getValue(), $query) !== false) { // $results[] = new \OCA\Tasks\Controller\Task($id,$calendarId,$vtodo,'COMMENTS',$query,$user_timezone); $results[] = Helper::arrayForJSON($id, $vtodo, $user_timezone, $calendarId); continue 2; } } } } } usort($results, array($this, 'sort_completed')); return $results; }
/** * @NoAdminRequired * @NoCSRFRequired * * Shows the albums and pictures at the root folder or a message if * there are no pictures. * * This is the entry page for logged-in users accessing the app from * within ownCloud. * A TemplateResponse response uses a template from the templates folder * and parameters provided here to build the page users will see * * @return TemplateResponse */ public function index() { $appName = $this->appName; if (\OCP\App::isEnabled('gallery')) { $url = $this->urlGenerator->linkToRoute($appName . '.page.error_page', ['message' => "You need to disable the Pictures app before being able to use the Gallery+ app", 'code' => Http::STATUS_INTERNAL_SERVER_ERROR]); return new RedirectResponse($url); } else { // Parameters sent to the template $params = ['appName' => $appName]; // Will render the page using the template found in templates/index.php $response = new TemplateResponse($appName, 'index', $params); $this->addContentSecurityToResponse($response); return $response; } }
/** * @AdminRequired * @NoCSRFRequired */ public function Check() { \OCP\JSON::setContentTypeHeader('application/json'); if ($this->Allow) { try { $LastVersionNumber = Tools::GetLastVersionNumber(); $AppVersion = \OCP\App::getAppVersion('ocdownloader'); $Response = array('ERROR' => false, 'RESULT' => version_compare($AppVersion, $LastVersionNumber, '<')); } catch (Exception $E) { $Response = array('ERROR' => true, 'MESSAGE' => (string) $this->L10N->t('Error while checking application version on GitHub')); } } else { $Response = array('ERROR' => true, 'MESSAGE' => (string) $this->L10N->t('You are not allowed to check for application updates')); } return new JSONResponse($Response); }
/** * @param array $arguments */ public function run($arguments) { if (!App::isEnabled('ownbackup')) { return; } $app = new Application(); $container = $app->getContainer(); /** @var BackupService $backupService */ $backupService = $container->query('OCA\\OwnBackup\\Service\\BackupService'); // check if we need a new backup if ($backupService->needNewBackup()) { // create new backup $backupService->createDBBackup(); // expiring old backups $backupService->expireOldBackups(); } }
/** * Format file infos for JSON * @param \OCP\Files\FileInfo[] $fileInfos file infos */ public static function formatFileInfos($fileInfos) { $files = array(); $id = 0; foreach ($fileInfos as $i) { $entry = \OCA\Files\Helper::formatFileInfo($i); $entry['id'] = $id++; $entry['etag'] = $entry['mtime']; // add fake etag, it is only needed to identify the preview image $entry['permissions'] = \OCP\Constants::PERMISSION_READ; if (\OCP\App::isEnabled('files_encryption')) { $entry['isPreviewAvailable'] = false; } $files[] = $entry; } return $files; }
public static function init() { //check if curl extension installed if (!in_array('curl', get_loaded_extensions())) { \OCP\Util::writeLog(self::APP_ID, 'This app needs cUrl PHP extension', \OCP\Util::DEBUG); return false; } \OC::$CLASSPATH['OCA\\User_persona\\Policy'] = self::APP_PATH . 'lib/policy.php'; \OCP\App::registerAdmin(self::APP_ID, 'settings'); if (!\OCP\User::isLoggedIn()) { \OC::$CLASSPATH['OCA\\User_persona\\Validator'] = self::APP_PATH . 'lib/validator.php'; \OC::$CLASSPATH['OC_USER_PERSONA'] = self::APP_PATH . 'user_persona.php'; \OC_User::useBackend('persona'); \OCP\Util::connectHook('OC_User', 'post_login', "OCA\\User_persona\\Validator", "postlogin_hook"); \OCP\Util::addScript(self::APP_ID, 'utils'); } }
/** * @param array $arguments */ public function run($arguments) { if (!App::isEnabled('search_lucene')) { return; } $app = new Application(); $container = $app->getContainer(); /** @var Logger $logger */ $logger = $container->query('Logger'); if (!empty($arguments['user'])) { $userId = $arguments['user']; $logger->debug('background job optimizing index for ' . $userId); $container->query('FileUtility')->setUpIndexFolder($userId); $container->query('Index')->optimizeIndex(); } else { $logger->debug('indexer job did not receive user in arguments: ' . json_encode($arguments)); } }
protected function execute(InputInterface $input, OutputInterface $output) { $username = $input->getArgument('user'); /** @var $user \OCP\IUser */ $user = $this->userManager->get($username); if (is_null($user)) { $output->writeln('<error>User does not exist</error>'); return 1; } if ($input->getOption('password-from-env')) { $password = getenv('OC_PASS'); if (!$password) { $output->writeln('<error>--password-from-env given, but OC_PASS is empty!</error>'); return 1; } } elseif ($input->isInteractive()) { /** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */ $dialog = $this->getHelperSet()->get('dialog'); if (\OCP\App::isEnabled('encryption')) { $output->writeln('<error>Warning: Resetting the password when using encryption will result in data loss!</error>'); if (!$dialog->askConfirmation($output, '<question>Do you want to continue?</question>', true)) { return 1; } } $password = $dialog->askHiddenResponse($output, '<question>Enter a new password: </question>', false); $confirm = $dialog->askHiddenResponse($output, '<question>Confirm the new password: </question>', false); if ($password !== $confirm) { $output->writeln("<error>Passwords did not match!</error>"); return 1; } } else { $output->writeln("<error>Interactive input or --password-from-env is needed for entering a new password!</error>"); return 1; } $success = $user->setPassword($password); if ($success) { $output->writeln("<info>Successfully reset password for " . $username . "</info>"); } else { $output->writeln("<error>Error while resetting password!</error>"); return 1; } }
/** * @param array $arguments */ public function run($arguments) { if (!App::isEnabled('search_lucene')) { return; } $app = new Application(); $container = $app->getContainer(); /** @var Logger $logger */ $logger = $container->query('Logger'); if (isset($arguments['user'])) { $userId = $arguments['user']; $folder = $container->query('FileUtility')->setUpUserFolder($userId); if ($folder) { $fileIds = $container->query('StatusMapper')->getUnindexed(); $logger->debug('background job indexing ' . count($fileIds) . ' files for ' . $userId); $container->query('Indexer')->indexFiles($fileIds); } } else { $logger->debug('indexer job did not receive user in arguments: ' . json_encode($arguments)); } }
function search($query) { $addressbooks = Addressbook::all(\OCP\USER::getUser(), 1); if (count($addressbooks) == 0 || !\OCP\App::isEnabled('contacts')) { return array(); } $results = array(); $l = new \OC_l10n('contacts'); foreach ($addressbooks as $addressbook) { $vcards = VCard::all($addressbook['id']); foreach ($vcards as $vcard) { if (substr_count(strtolower($vcard['fullname']), strtolower($query)) > 0) { //$link = \OCP\Util::linkTo('contacts', 'index.php').'?id='.urlencode($vcard['id']); $link = 'javascript:openContact(' . $vcard['id'] . ')'; $results[] = new \OC_Search_Result($vcard['fullname'], '', $link, (string) $l->t('Contact')); //$name,$text,$link,$type } } } return $results; }