Example #1
0
 /**
  * beforeCallback.
  *
  * This callback adds the CSS/JS for the localeswitcher on the backend
  * and checks that we are on a valid locale when on the frontend
  */
 public function beforeCallback(Request $request)
 {
     $routeParams = $request->get('_route_params');
     if ($this->app['config']->getWhichEnd() == 'backend') {
         if (array_key_exists('contenttypeslug', $routeParams)) {
             $this->addCss('assets/css/field_locale.css');
             if (!empty($routeParams['id'])) {
                 $this->addJavascript('assets/js/field_locale.js', array('late' => true));
             }
         }
     } else {
         if (isset($routeParams['_locale'])) {
             $this->app['menu'] = $this->app->share(function ($app) {
                 $builder = new Menu\LocalizedMenuBuilder($app);
                 return $builder;
             });
             $locales = $this->app['config']->get('general/locales');
             foreach ($locales as $isolocale => $locale) {
                 if ($locale['slug'] == $routeParams['_locale']) {
                     $foundLocale = $isolocale;
                 }
             }
             if (isset($foundLocale)) {
                 setlocale(LC_ALL, $foundLocale);
                 $this->app['config']->set('general/locale', $foundLocale);
             } else {
                 $routeParams['_locale'] = reset($locales)['slug'];
                 return $this->app->redirect(Lib::path($request->get('_route'), $routeParams));
             }
         }
     }
 }
 /**
  * Adds all resources that belong to a locale.
  *
  * @param Application $app
  * @param string      $locale
  */
 public static function addResources(Application $app, $locale)
 {
     // Directories to look for translation file(s)
     $transDirs = array_unique([$app['resources']->getPath("app/resources/translations/{$locale}"), $app['resources']->getPath("root/app/resources/translations/{$locale}")]);
     $needsSecondPass = true;
     foreach ($transDirs as $transDir) {
         if (!is_dir($transDir) || !is_readable($transDir)) {
             continue;
         }
         $iterator = new \DirectoryIterator($transDir);
         /**
          * @var \SplFileInfo $fileInfo
          */
         foreach ($iterator as $fileInfo) {
             $ext = Lib::getExtension((string) $fileInfo);
             if (!$fileInfo->isFile() || !in_array($ext, ['yml', 'xlf'], true)) {
                 continue;
             }
             list($domain) = explode('.', $fileInfo->getFilename());
             $app['translator']->addResource($ext, $fileInfo->getRealPath(), $locale, $domain);
             $needsSecondPass = false;
         }
     }
     if ($needsSecondPass && strlen($locale) === 5) {
         static::addResources($app, substr($locale, 0, 2));
     }
 }
 public function patchTranslationPath()
 {
     # workaround for Bolt 2.2 - fix in master (3.0), see #3553 and #3800
     //        $app->before(function() use ($app) {
     //            $path = $app['resources']->getPath('root/app/resources/translations');
     //            $app['translator']->addResource('yml', $path.'/contenttypes.de_DE.yml', 'de_DE', 'contenttypes');
     //        });
     if ("Bolt\\Configuration\\Composer" != get_class($this->app['resources'])) {
         return;
     }
     //        $versionParser = new \Composer\Package\Version\VersionParser();
     //        $version = $versionParser->parseConstraints($app['bolt_version']);
     //        print_r($version);
     // Directory to look for translation file(s)
     $transDir = $this->app['resources']->getPath('root/app/resources/translations/' . $this->app['locale']);
     if (is_dir($transDir)) {
         $iterator = new \DirectoryIterator($transDir);
         /**
          * @var \SplFileInfo $fileInfo
          */
         foreach ($iterator as $fileInfo) {
             $ext = Lib::getExtension((string) $fileInfo);
             if (!$fileInfo->isFile() || !in_array($ext, array('yml', 'xlf'))) {
                 continue;
             }
             list($domain) = explode('.', $fileInfo->getFilename());
             $this->app['translator']->addResource($ext, $transDir . '/' . $fileInfo->getFilename(), $this->app['locale'], $domain);
         }
     }
 }
Example #4
0
 public function handle($path)
 {
     $files = [];
     $folders = [];
     $list = $this->filesystem->listContents($path);
     $ignored = ['.', '..', '.DS_Store', '.gitignore', '.htaccess'];
     foreach ($list as $entry) {
         if (in_array($entry['basename'], $ignored)) {
             continue;
         }
         if (!$this->filesystem->authorized($entry['path'])) {
             continue;
         }
         if ($entry['type'] === 'file') {
             try {
                 $url = $this->filesystem->url($entry['path']);
             } catch (\Exception $e) {
                 $url = $entry['path'];
             }
             // Ugh, for some reason the foldername for the theme is included twice. Why?
             // For now we 'fix' this with an ugly hack, replacing it. :-/
             // TODO: dig into Filesystem and figure out why this happens.
             $pathsegments = explode('/', $entry['path']);
             if (!empty($pathsegments[0])) {
                 $url = str_replace('/' . $pathsegments[0] . '/' . $pathsegments[0] . '/', '/' . $pathsegments[0] . '/', $url);
             }
             $files[$entry['path']] = ['path' => $entry['dirname'], 'filename' => $entry['basename'], 'newpath' => $entry['path'], 'relativepath' => $entry['path'], 'writable' => true, 'readable' => false, 'type' => isset($entry['extension']) ? $entry['extension'] : '', 'filesize' => Lib::formatFilesize($entry['size']), 'modified' => date("Y/m/d H:i:s", $entry['timestamp']), 'permissions' => 'public', 'url' => $url];
             /* **** Extra checks for files that can be resolved via PHP urlopen functions **** */
             try {
                 $files[$entry['path']]['permissions'] = $this->filesystem->getVisibility($entry['path']);
             } catch (\Exception $e) {
                 // Computer says "No!"
             }
             $fullfilename = $this->filesystem->getAdapter()->applyPathPrefix($entry['path']);
             if (is_readable($fullfilename)) {
                 $files[$entry['path']]['readable'] = true;
                 if (!empty($entry['extension']) && in_array($entry['extension'], ['gif', 'jpg', 'png', 'jpeg'])) {
                     $size = getimagesize($fullfilename);
                     $files[$entry['path']]['imagesize'] = sprintf("%s × %s", $size[0], $size[1]);
                 }
                 $files[$entry['path']]['permissions'] = util::full_permissions($fullfilename);
             }
         }
         if ($entry['type'] == 'dir') {
             $folders[$entry['path']] = ['path' => $entry['dirname'], 'foldername' => $entry['basename'], 'newpath' => $entry['path'], 'modified' => date("Y/m/d H:i:s", $entry['timestamp']), 'writable' => true];
             $fullfilename = $this->filesystem->getAdapter()->applyPathPrefix($entry['path']);
             /* **** Extra checks for files that can be resolved via PHP urlopen functions **** */
             if (is_readable($fullfilename)) {
                 if (!is_writable($fullfilename)) {
                     $folders[$entry['path']]['writable'] = false;
                 }
             }
         }
     }
     ksort($files);
     ksort($folders);
     return [$files, $folders];
 }
Example #5
0
 /**
  * Collect the date for the Toolbar item.
  *
  * @param Request    $request
  * @param Response   $response
  * @param \Exception $exception
  */
 public function collect(Request $request, Response $response, \Exception $exception = null)
 {
     $this->data = array('version' => $this->app->getVersion(false), 'name' => $this->app['bolt_name'], 'fullversion' => 'Version: ' . $this->app->getVersion(true), 'payoff' => 'Sophisticated, lightweight & simple CMS', 'aboutlink' => sprintf("<a href=\"%s\">%s</a>", Lib::path('about'), 'About'), 'branding' => null, 'editlink' => null, 'edittitle' => null);
     if ($this->app['config']->get('general/branding/provided_by/0')) {
         $this->data['branding'] = sprintf("%s <a href=\"mailto:%s\">%s</a>", Trans::__('Provided by:'), $this->app['config']->get('general/branding/provided_by/0'), $this->app['config']->get('general/branding/provided_by/1'));
     }
     if (!empty($this->app['editlink'])) {
         $this->data['editlink'] = $this->app['editlink'];
         $this->data['edittitle'] = $this->app['edittitle'];
     }
 }
Example #6
0
 /**
  * Checks if a given file is acceptable for upload.
  */
 public function allowedUpload($originalFilename)
 {
     // no UNIX-hidden files
     if ($originalFilename[0] === '.') {
         return false;
     }
     // only whitelisted extensions
     $extension = strtolower(Lib::getExtension($originalFilename));
     $allowedExtensions = $this->getAllowedUploadExtensions();
     return in_array($extension, $allowedExtensions);
 }
Example #7
0
 /**
  * Helper function to make a path to an image.
  *
  * @param string         $filename Target filename
  * @param string|integer $width    Target width
  * @param string|integer $height   Target height
  * @param string         $crop     String identifier for cropped images
  *
  * @return string Image path
  */
 public function image($filename, $width = '', $height = '', $crop = '')
 {
     if ($width != '' || $height != '') {
         // You don't want the image, you just want a thumbnail.
         return $this->thumbnail($filename, $width, $height, $crop);
     }
     // After v1.5.1 we store image data as an array
     if (is_array($filename)) {
         $filename = isset($filename['filename']) ? $filename['filename'] : $filename['file'];
     }
     $image = sprintf('%sfiles/%s', $this->app['paths']['root'], Lib::safeFilename($filename));
     return $image;
 }
Example #8
0
 /**
  * Helper function to make a path to an image.
  *
  * @param string         $filename Target filename
  * @param string|integer $width    Target width
  * @param string|integer $height   Target height
  * @param string         $crop     String identifier for cropped images
  *
  * @return string Image path
  */
 public function image($filename, $width = null, $height = null, $crop = null)
 {
     if ($width || $height) {
         // You don't want the image, you just want a thumbnail.
         return $this->thumbnail($filename, $width, $height, $crop);
     }
     // After v1.5.1 we store image data as an array
     if (is_array($filename)) {
         $filename = isset($filename['filename']) ? $filename['filename'] : $filename['file'];
     }
     $image = sprintf('%s%s', $this->app['resources']->getUrl('files'), Lib::safeFilename($filename));
     return $image;
 }
 public function record(\Silex\Application $app, $contenttypeslug, $slug = '')
 {
     $contenttype = $app['storage']->getContentType($contenttypeslug);
     // If the contenttype is 'viewless', don't show the record page.
     if (isset($contenttype['viewless']) && $contenttype['viewless'] === true) {
         return $app->abort(Response::HTTP_NOT_FOUND, "Page {$contenttypeslug}/{$slug} not found.");
     }
     // Perhaps we don't have a slug. Let's see if we can pick up the 'id', instead.
     if (empty($slug)) {
         $slug = $app['request']->get('id');
     }
     $slug = $app['slugify']->slugify($slug);
     // First, try to get it by slug.
     $content = $app['storage']->getContent($contenttype['slug'], array('slug' => $slug, 'returnsingle' => true, 'log_not_found' => !is_numeric($slug)));
     if (!$content && !is_numeric($slug)) {
         // And otherwise try getting it by translated slugs
         $match = $this->matchTranslatedSlug($app, $contenttype['slug'], $slug);
         if (!empty($match)) {
             $content = $app['storage']->getContent($contenttype['slug'], array('id' => $match['content_type_id'], 'returnsingle' => true));
         }
     }
     if (!$content && is_numeric($slug)) {
         // And otherwise try getting it by ID
         $content = $app['storage']->getContent($contenttype['slug'], array('id' => $slug, 'returnsingle' => true));
     }
     // No content, no page!
     if (!$content) {
         return $app->abort(Response::HTTP_NOT_FOUND, "Page {$contenttypeslug}/{$slug} not found.");
     }
     // Then, select which template to use, based on our 'cascading templates rules'
     $template = $app['templatechooser']->record($content);
     $paths = $app['resources']->getPaths();
     // Setting the canonical URL.
     if ($content->isHome() && $template == $app['config']->get('general/homepage_template')) {
         $app['resources']->setUrl('canonicalurl', $paths['rooturl']);
     } else {
         $url = $paths['canonical'] . $content->link();
         $app['resources']->setUrl('canonicalurl', $url);
     }
     // Setting the editlink
     $app['editlink'] = Lib::path('editcontent', array('contenttypeslug' => $contenttype['slug'], 'id' => $content->id));
     $app['edittitle'] = $content->getTitle();
     // Make sure we can also access it as {{ page.title }} for pages, etc. We set these in the global scope,
     // So that they're also available in menu's and templates rendered by extensions.
     $app['twig']->addGlobal('record', $content);
     $app['twig']->addGlobal($contenttype['singular_slug'], $content);
     // Render the template and return.
     return $this->render($app, $template, $content->getTitle());
 }
Example #10
0
 /**
  * Updates a menu item to have at least a 'link' key.
  *
  * @param array $item
  *
  * @return array Keys 'link' and possibly 'label', 'title' and 'path'
  */
 private function menuHelper($item)
 {
     // recurse into submenu's
     if (isset($item['submenu']) && is_array($item['submenu'])) {
         $item['submenu'] = $this->menuHelper($item['submenu']);
     }
     if (isset($item['route'])) {
         $param = !empty($item['param']) ?: array();
         $add = !empty($item['add']) ?: '';
         $item['link'] = Lib::path($item['route'], $param, $add);
     } elseif (isset($item['path'])) {
         $item = $this->resolvePathToContent($item);
     }
     return $item;
 }
Example #11
0
 /**
  * Middleware function to check whether a user is logged on.
  *
  * @param Request            $request
  * @param \Silex\Application $app
  *
  * @return null|\Symfony\Component\HttpFoundation\RedirectResponse
  */
 public function before(Request $request, Silex\Application $app)
 {
     // This disallows extensions from adding any extra snippets to the output
     if ($request->get("_route") !== 'extend') {
         $app['htmlsnippets'] = false;
     }
     // Start the 'stopwatch' for the profiler.
     $app['stopwatch']->start('bolt.backend.before');
     // Most of the 'check if user is allowed' happens here: match the current route to the 'allowed' settings.
     if (!$app['users']->isAllowed('extensions')) {
         $app['session']->getFlashBag()->add('error', Trans::__('You do not have the right privileges to view that page.'));
         return Lib::redirect('dashboard');
     }
     // Stop the 'stopwatch' for the profiler.
     $app['stopwatch']->stop('bolt.backend.before');
     return null;
 }
Example #12
0
 /**
  * Collect information from Twig.
  *
  * @param Request    $request   The Request Object
  * @param Response   $response  The Response Object
  * @param \Exception $exception The Exception
  */
 public function collect(Request $request, Response $response, \Exception $exception = null)
 {
     $filters = array();
     $tests = array();
     $extensions = array();
     $functions = array();
     foreach ($this->getTwig()->getExtensions() as $extensionName => $extension) {
         /** @var $extension \Twig_ExtensionInterface */
         $extensions[] = array('name' => $extensionName, 'class' => get_class($extension));
         foreach ($extension->getFilters() as $filterName => $filter) {
             if ($filter instanceof \Twig_FilterInterface) {
                 $call = $filter->compile();
                 if (is_array($call) && is_callable($call)) {
                     $call = 'Method ' . $call[1] . ' of an object ' . get_class($call[0]);
                 }
             } elseif ($filter instanceof \Twig_SimpleFilter) {
                 $call = $filter->getName();
             } else {
                 continue;
             }
             $filters[] = array('name' => $filterName, 'extension' => $extensionName, 'call' => $call);
         }
         foreach ($extension->getTests() as $testName => $test) {
             if ($test instanceof \Twig_TestInterface) {
                 $call = $test->compile();
             } elseif ($test instanceof \Twig_SimpleTest) {
                 $call = $test->getName();
             } else {
                 continue;
             }
             $tests[] = array('name' => $testName, 'extension' => $extensionName, 'call' => $call);
         }
         foreach ($extension->getFunctions() as $functionName => $function) {
             if ($function instanceof \Twig_FunctionInterface) {
                 $call = $function->compile();
             } elseif ($function instanceof \Twig_SimpleFunction) {
                 $call = $function->getName();
             } else {
                 continue;
             }
             $functions[] = array('name' => $functionName, 'extension' => $extensionName, 'call' => $call);
         }
     }
     $this->data = array('extensions' => $extensions, 'tests' => $tests, 'filters' => $filters, 'functions' => $functions, 'templates' => Lib::parseTwigTemplates($this->app['twig.loader']), 'templatechosen' => $this->getTrackedValue('templatechosen'), 'templateerror' => $this->getTrackedValue('templateerror'));
 }
 /**
  * Adds all resources that belong to a locale.
  *
  * @param Application $app
  * @param string      $locale
  */
 public static function addResources(Application $app, $locale)
 {
     // Directory to look for translation file(s)
     $transDir = $app['resources']->getPath('app/resources/translations/' . $locale);
     if (is_dir($transDir)) {
         $iterator = new \DirectoryIterator($transDir);
         /**
          * @var \SplFileInfo $fileInfo
          */
         foreach ($iterator as $fileInfo) {
             $ext = Lib::getExtension((string) $fileInfo);
             if (!$fileInfo->isFile() || !in_array($ext, ['yml', 'xlf'])) {
                 continue;
             }
             list($domain) = explode('.', $fileInfo->getFilename());
             $app['translator']->addResource($ext, $fileInfo->getRealPath(), $locale, $domain);
         }
     } elseif (strlen($locale) == 5) {
         static::addResources($app, substr($locale, 0, 2));
     }
 }
Example #14
0
 /**
  * File editor.
  *
  * @param Request $request   The Symfony Request
  * @param string  $namespace The filesystem namespace
  * @param string  $file      The file path
  *
  * @return \Bolt\Response\BoltResponse|\Symfony\Component\HttpFoundation\RedirectResponse
  */
 public function edit(Request $request, $namespace, $file)
 {
     if ($namespace === 'app' && dirname($file) === 'config') {
         // Special case: If requesting one of the major config files, like contenttypes.yml, set the path to the
         // correct dir, which might be 'app/config', but it might be something else.
         $namespace = 'config';
     }
     /** @var FilesystemInterface $filesystem */
     $filesystem = $this->filesystem()->getFilesystem($namespace);
     if (!$filesystem->authorized($file)) {
         $error = Trans::__('general.phrase.access-denied-permissions-edit-file', ['%s' => $file]);
         $this->abort(Response::HTTP_FORBIDDEN, $error);
     }
     try {
         /** @var File $file */
         $file = $filesystem->get($file);
         $type = Lib::getExtension($file->getPath());
         $data = ['contents' => $file->read()];
     } catch (FileNotFoundException $e) {
         $error = Trans::__('general.phrase.file-not-exist', ['%s' => $file->getPath()]);
         $this->abort(Response::HTTP_NOT_FOUND, $error);
     } catch (IOException $e) {
         $error = Trans::__('general.phrase.file-not-readable', ['%s' => $file->getPath()]);
         $this->abort(Response::HTTP_NOT_FOUND, $error);
     }
     /** @var Form $form */
     $form = $this->createFormBuilder(FormType::class, $data)->add('contents', TextareaType::class)->getForm();
     // Handle the POST and check if it's valid.
     if ($request->isMethod('POST')) {
         return $this->handleEdit($request, $form, $file, $type);
     }
     // For 'related' files we might need to keep track of the current dirname on top of the namespace.
     if (dirname($file->getPath()) !== '') {
         $additionalpath = dirname($file->getPath()) . '/';
     } else {
         $additionalpath = '';
     }
     $context = ['form' => $form->createView(), 'filetype' => $type, 'file' => $file->getPath(), 'basename' => basename($file->getPath()), 'pathsegments' => $this->getPathSegments(dirname($file->getPath())), 'additionalpath' => $additionalpath, 'namespace' => $namespace, 'write_allowed' => true, 'filegroup' => $this->getFileGroup($filesystem, $file), 'datechanged' => date_format(new \DateTime('@' . $file->getTimestamp()), 'c')];
     return $this->render('@bolt/editfile/editfile.twig', $context);
 }
Example #15
0
 /**
  * Show the password form. If the visitor gives the correct password, they
  * are redirected to the page they came from, if any.
  *
  * @return \Twig_Markup
  */
 public function passwordForm()
 {
     // Set up the form.
     $form = $this->app['form.factory']->createBuilder('form');
     if ($this->config['password_only'] == false) {
         $form->add('username', 'text');
     }
     $form->add('password', 'password');
     $form = $form->getForm();
     if ($this->app['request']->getMethod() == 'POST') {
         $form->bind($this->app['request']);
         $data = $form->getData();
         if ($form->isValid() && $this->checkLogin($data)) {
             // Set the session var, so we're authenticated..
             $this->app['session']->set('passwordprotect', 1);
             $this->app['session']->set('passwordprotect_name', $this->checkLogin($data));
             // Print a friendly message..
             printf("<p class='message-correct'>%s</p>", $this->config['message_correct']);
             $returnto = $this->app['request']->get('returnto');
             // And back we go, to the page we originally came from..
             if (!empty($returnto)) {
                 Lib::simpleredirect($returnto);
                 die;
             }
         } else {
             // Remove the session var, so we can test 'logging off'..
             $this->app['session']->remove('passwordprotect');
             $this->app['session']->remove('passwordprotect_name');
             // Print a friendly message..
             if (!empty($data['password'])) {
                 printf("<p class='message-wrong'>%s</p>", $this->config['message_wrong']);
             }
         }
     }
     // Render the form, and show it it the visitor.
     $this->app['twig.loader.filesystem']->addPath(__DIR__);
     $html = $this->app['twig']->render('assets/passwordform.twig', array('form' => $form->createView()));
     return new \Twig_Markup($html, 'UTF-8');
 }
Example #16
0
 /**
  * File editor.
  *
  * @param Request $request   The Symfony Request
  * @param string  $namespace The filesystem namespace
  * @param string  $file      The file path
  *
  * @return \Bolt\Response\BoltResponse|\Symfony\Component\HttpFoundation\RedirectResponse
  */
 public function edit(Request $request, $namespace, $file)
 {
     if ($namespace === 'app' && dirname($file) === 'config') {
         // Special case: If requesting one of the major config files, like contenttypes.yml, set the path to the
         // correct dir, which might be 'app/config', but it might be something else.
         $namespace = 'config';
     }
     /** @var FilesystemInterface $filesystem */
     $filesystem = $this->filesystem()->getFilesystem($namespace);
     if (!$filesystem->authorized($file)) {
         $error = Trans::__("You don't have correct permissions to edit the file '%s'.", ['%s' => $file]);
         $this->abort(Response::HTTP_FORBIDDEN, $error);
     }
     /** @var File $file */
     $file = $filesystem->get($file);
     $type = Lib::getExtension($file->getPath());
     $contents = null;
     if (!$file->exists() || !($contents = $file->read())) {
         $error = Trans::__("The file '%s' doesn't exist, or is not readable.", ['%s' => $file->getPath()]);
         $this->abort(Response::HTTP_NOT_FOUND, $error);
     }
     $writeallowed = $this->isWriteable($file);
     $data = ['contents' => $contents];
     /** @var Form $form */
     $form = $this->createFormBuilder('form', $data)->add('contents', 'textarea')->getForm();
     // Handle the POST and check if it's valid.
     if ($request->isMethod('POST')) {
         return $this->handleEdit($request, $form, $file, $type);
     }
     // For 'related' files we might need to keep track of the current dirname on top of the namespace.
     if (dirname($file->getPath()) !== '') {
         $additionalpath = dirname($file->getPath()) . '/';
     } else {
         $additionalpath = '';
     }
     $context = ['form' => $form->createView(), 'filetype' => $type, 'file' => $file->getPath(), 'basename' => basename($file->getPath()), 'pathsegments' => $this->getPathSegments(dirname($file->getPath())), 'additionalpath' => $additionalpath, 'namespace' => $namespace, 'write_allowed' => $writeallowed, 'filegroup' => $this->getFileGroup($filesystem, $file), 'datechanged' => date_format(new \DateTime('@' . $file->getTimestamp()), 'c')];
     return $this->render('@bolt/editfile/editfile.twig', $context);
 }
Example #17
0
 /**
  * Set a Contenttype record's values.
  *
  * @param array $values
  */
 public function setValues(array $values)
 {
     // Since Bolt 1.4, we use 'ownerid' instead of 'username' in the DB tables. If we get an array that has an
     // empty 'ownerid', attempt to set it from the 'username'. In $this->setValue the user will be set, regardless
     // of ownerid is an 'id' or a 'username'.
     if (empty($values['ownerid']) && !empty($values['username'])) {
         $values['ownerid'] = $values['username'];
         unset($values['username']);
     }
     foreach ($values as $key => $value) {
         if ($key !== 'templatefields') {
             $this->setValue($key, $value);
         }
     }
     // If default status is set in contentttype.
     if (empty($this->values['status']) && isset($this->contenttype['default_status'])) {
         $this->values['status'] = $this->contenttype['default_status'];
     }
     $serializedFieldTypes = ['geolocation', 'imagelist', 'image', 'file', 'filelist', 'video', 'select', 'templateselect', 'checkbox'];
     // Check if the values need to be unserialized, and pre-processed.
     foreach ($this->values as $key => $value) {
         if (in_array($this->fieldtype($key), $serializedFieldTypes) || $key == 'templatefields') {
             if (!empty($value) && is_string($value) && (substr($value, 0, 2) == "a:" || $value[0] === '[' || $value[0] === '{')) {
                 try {
                     $unserdata = Lib::smartUnserialize($value);
                 } catch (\Exception $e) {
                     $unserdata = false;
                 }
                 if ($unserdata !== false) {
                     $this->values[$key] = $unserdata;
                 }
             }
         }
         if ($this->fieldtype($key) == "video" && is_array($this->values[$key]) && !empty($this->values[$key]['url'])) {
             $video = $this->values[$key];
             // update the HTML, according to given width and height
             if (!empty($video['width']) && !empty($video['height'])) {
                 $video['html'] = preg_replace("/width=(['\"])([0-9]+)(['\"])/i", 'width=${1}' . $video['width'] . '${3}', $video['html']);
                 $video['html'] = preg_replace("/height=(['\"])([0-9]+)(['\"])/i", 'height=${1}' . $video['height'] . '${3}', $video['html']);
             }
             $responsiveclass = "responsive-video";
             // See if it's widescreen or not.
             if (!empty($video['height']) && $video['width'] / $video['height'] > 1.76) {
                 $responsiveclass .= " widescreen";
             }
             if (strpos($video['url'], "vimeo") !== false) {
                 $responsiveclass .= " vimeo";
             }
             $video['responsive'] = sprintf('<div class="%s">%s</div>', $responsiveclass, $video['html']);
             // Mark them up as Twig_Markup.
             $video['html'] = new \Twig_Markup($video['html'], 'UTF-8');
             $video['responsive'] = new \Twig_Markup($video['responsive'], 'UTF-8');
             $this->values[$key] = $video;
         }
         if ($this->fieldtype($key) == "date" || $this->fieldtype($key) == "datetime") {
             if ($this->values[$key] === "") {
                 $this->values[$key] = null;
             }
         }
     }
     // Template fields need to be done last
     // As the template has to have been selected
     if ($this->isRootType) {
         if (empty($values['templatefields'])) {
             $this->setValue('templatefields', []);
         } else {
             $this->setValue('templatefields', $values['templatefields']);
         }
     }
 }
Example #18
0
 /**
  * Middleware function to check whether a user is logged on.
  *
  * @return null|\Symfony\Component\HttpFoundation\RedirectResponse
  */
 public function before(Request $request, Application $app)
 {
     // Start the 'stopwatch' for the profiler.
     $app['stopwatch']->start('bolt.backend.before');
     // If there's no active session, don't do anything.
     if (!$app['users']->isValidSession()) {
         $app->abort(Response::HTTP_NOT_FOUND, 'You must be logged in to use this.');
     }
     if (!$app['users']->isAllowed("files:uploads")) {
         $app['session']->getFlashBag()->add('error', Trans::__('You do not have the right privileges to upload.'));
         return Lib::redirect('dashboard');
     }
     // Stop the 'stopwatch' for the profiler.
     $app['stopwatch']->stop('bolt.backend.before');
     return null;
 }
Example #19
0
 /**
  * Creates a link to EDIT this record, if the user is logged in.
  *
  * @return string
  */
 public function editlink()
 {
     $perm = "contenttype:" . $this->contenttype['slug'] . ":edit:" . $this->id;
     if ($this->app['users']->isAllowed($perm)) {
         return Lib::path('editcontent', array('contenttypeslug' => $this->contenttype['slug'], 'id' => $this->id));
     } else {
         return false;
     }
 }
/**
 * Stub for edit_post_link.
 */
function edit_post_link($text = null, $before = '', $after = '', $id = 0)
{
    global $post, $currentuser;
    if (!is_object($post) || empty($currentuser['username'])) {
        return;
    }
    $path = \Bolt\Library::path('editcontent', ['contenttypeslug' => $post->contenttype['slug'], 'id' => $post['id']]);
    if (null === $text) {
        $text = __('Edit This');
    }
    $link = '<a class="post-edit-link" href="' . $path . '">' . $text . '</a>';
    /**
     * Filter the post edit link anchor tag.
     *
     * @since 2.3.0
     *
     * @param string $link    Anchor tag for the edit link.
     * @param int    $post_id Post ID.
     * @param string $text    Anchor text.
     */
    echo $before . apply_filters('edit_post_link', $link, $post['id'], $text) . $after;
}
 public function slugTreeRecord($slug)
 {
     // Add snippets, since this is a Frontend route.
     $this->app['htmlsnippets'] = true;
     if (strripos($slug, '/')) {
         // find the last "/"" in the slug
         //dump($slug);
         // dump($this->app['config']);
         // dump($this->app['config']->get('data/contenttypes'));
         // dump($this->app['config']->get('general/homepage_template'));
         // dump(strripos($slug, '/') == strlen($slug));
         // dump(strripos($slug, '/'));
         // dump(strlen($slug));
         $slug = rtrim($slug, '/');
         if (in_array($slug, array('blogs', 'locations', 'structures', 'pages', 'blogposts', 'jobs', 'events', 'persons', 'network', 'publications', 'pressreleases', 'projects', 'taskforces', 'homepage', 'footers'))) {
             switch ($slug) {
                 case 'blogs':
                     //dump('redirect blogs');
                     \Bolt\Library::simpleredirect('/blogposts');
                     die;
                     break;
                 default:
                     \Bolt\Library::simpleredirect('/' . $slug);
                     die;
                     break;
             }
         }
     }
     // $slug = \Bolt\Helpers\String::slug($slug, -1);
     $slug = $this->app['slugify']->slugify($slug);
     $contenttype = $this->getContenttypeBySlug($slug, true);
     $frontend = new Bolt\Controllers\Frontend();
     return $frontend->record($this->app, $contenttype, $slug);
 }
Example #22
0
 /**
  * Check if a user is logged in, and has the proper required permission. If
  * not, we redirect the user to the dashboard.
  *
  * @param string $permission
  *
  * @return bool True if permission allowed
  */
 public function requireUserPermission($permission = 'dashboard')
 {
     if ($this->app['users']->isAllowed($permission)) {
         return true;
     } else {
         Lib::simpleredirect($this->app['config']->get('general/branding/path'));
         return false;
     }
 }
Example #23
0
 /**
  * Redirect the browser to another page.
  *
  * @param boolean $safe
  *
  * @return string
  */
 public function redirect($path, $safe)
 {
     // Nope! We're not allowing user-supplied content to issue redirects.
     if ($safe) {
         return null;
     }
     Lib::simpleredirect($path);
     return '';
 }
Example #24
0
 /**
  * Return a list with the current stacked items. Add some relevant info to each item,
  * and also check if the item is present and readable.
  *
  * @param integer $count
  * @param string  $typefilter
  *
  * @return array
  */
 public function listitems($count = 100, $typefilter = '')
 {
     $this->initialize();
     // Make sure typefilter is an array, if passed something like "image, document"
     if (!empty($typefilter)) {
         $typefilter = array_map('trim', explode(',', $typefilter));
     }
     // Our basepaths for all files that can be on the stack: 'files' and 'theme'.
     $filespath = $this->app['resources']->getPath('filespath');
     $themepath = $this->app['resources']->getPath('themebasepath');
     $items = $this->items;
     $list = [];
     foreach ($items as $item) {
         $extension = strtolower(Lib::getExtension($item));
         if (in_array($extension, $this->imageTypes)) {
             $type = 'image';
         } elseif (in_array($extension, $this->documentTypes)) {
             $type = 'document';
         } else {
             $type = 'other';
         }
         // Skip this one, if it doesn't match the type.
         if (!empty($typefilter) && !in_array($type, $typefilter)) {
             continue;
         }
         // Figure out the full path, based on the two possible locations.
         $fullpath = '';
         if (is_readable(str_replace('files/files/', 'files/', $filespath . '/' . $item))) {
             $fullpath = str_replace('files/files/', 'files/', $filespath . '/' . $item);
         } elseif (is_readable($themepath . '/' . $item)) {
             $fullpath = $themepath . '/' . $item;
         }
         // No dice! skip this one.
         if (empty($fullpath)) {
             continue;
         }
         $thisitem = ['basename' => basename($item), 'extension' => $extension, 'filepath' => str_replace('files/', '', $item), 'type' => $type, 'writable' => is_writable($fullpath), 'readable' => is_readable($fullpath), 'filesize' => Lib::formatFilesize(filesize($fullpath)), 'modified' => date('Y/m/d H:i:s', filemtime($fullpath)), 'permissions' => util::full_permissions($fullpath)];
         $thisitem['info'] = sprintf('%s: <code>%s</code><br>%s: %s<br>%s: %s<br>%s: <code>%s</code>', Trans::__('Path'), $thisitem['filepath'], Trans::__('Filesize'), $thisitem['filesize'], Trans::__('Modified'), $thisitem['modified'], Trans::__('Permissions'), $thisitem['permissions']);
         if ($type == 'image') {
             $size = getimagesize($fullpath);
             $thisitem['imagesize'] = sprintf('%s × %s', $size[0], $size[1]);
             $thisitem['info'] .= sprintf('<br>%s: %s × %s px', Trans::__('Size'), $size[0], $size[1]);
         }
         //add it to our list.
         $list[] = $thisitem;
     }
     $list = array_slice($list, 0, $count);
     return $list;
 }
Example #25
0
 /**
  * Cache built configuration parameters.
  */
 protected function saveCache()
 {
     // Store the version number along with the config.
     $this->data['version'] = $this->app['bolt_long_version'];
     if ($this->get('general/caching/config')) {
         Lib::saveSerialize($this->app['resources']->getPath('cache/config_cache.php'), $this->data);
         return;
     }
     @unlink($this->app['resources']->getPath('cache/config_cache.php'));
 }
Example #26
0
 /**
  * Get the max upload value in a formatted string.
  *
  * @return string
  */
 public function getMaxUploadSizeNice()
 {
     return Lib::formatFilesize($this->getMaxUploadSize());
 }
Example #27
0
 /**
  * Set up the profilers for the toolbar.
  */
 public function initProfiler()
 {
     // On 'after' attach the debug-bar, if debug is enabled.
     if (!($this['debug'] && ($this['session']->has('user') || $this['config']->get('general/debug_show_loggedoff')))) {
         error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_USER_DEPRECATED);
         return;
     }
     // Set the error_reporting to the level specified in config.yml
     error_reporting($this['config']->get('general/debug_error_level'));
     // Register Whoops, to handle errors for logged in users only.
     if ($this['config']->get('general/debug_enable_whoops')) {
         $this->register(new WhoopsServiceProvider());
         // Add a special handler to deal with AJAX requests
         if ($this['config']->getWhichEnd() == 'async') {
             $this['whoops']->pushHandler(new JsonResponseHandler());
         }
     }
     // Register the Silex/Symfony web debug toolbar.
     $this->register(new Silex\Provider\WebProfilerServiceProvider(), array('profiler.cache_dir' => $this['resources']->getPath('cache') . '/profiler', 'profiler.mount_prefix' => '/_profiler'));
     // Register the toolbar item for our Database query log.
     $this->register(new Provider\DatabaseProfilerServiceProvider());
     // Register the toolbar item for our bolt nipple.
     $this->register(new Provider\BoltProfilerServiceProvider());
     // Register the toolbar item for the Twig toolbar item.
     $this->register(new Provider\TwigProfilerServiceProvider());
     $this['twig.loader.filesystem'] = $this->share($this->extend('twig.loader.filesystem', function (\Twig_Loader_Filesystem $filesystem, Application $app) {
         $filesystem->addPath($app['resources']->getPath('root') . '/vendor/symfony/web-profiler-bundle/Symfony/Bundle/WebProfilerBundle/Resources/views', 'WebProfiler');
         $filesystem->addPath($app['resources']->getPath('app') . '/view', 'BoltProfiler');
         return $filesystem;
     }));
     // PHP 5.3 does not allow 'use ($this)' in closures.
     $app = $this;
     $this->after(function () use($app) {
         foreach (Lib::parseTwigTemplates($app['twig.loader.filesystem']) as $template) {
             $app['twig.logger']->collectTemplateData($template);
         }
     });
 }
Example #28
0
 /**
  * @runInSeparateProcess
  */
 public function testSimpleRedirectAbort()
 {
     $app = $this->getApp();
     $this->setExpectedException('Symfony\\Component\\HttpKernel\\Exception\\HttpException', "Redirecting to '/test2'.");
     $this->expectOutputString("<p>Redirecting to <a href='/test2'>/test2</a>.</p><script>window.setTimeout(function () { window.location='/test2'; }, 500);</script>");
     $redirect = Library::simpleredirect('/test2', true);
 }
Example #29
0
 public function testBadLoadSerializeFails()
 {
     $file = PHPUNIT_ROOT . '/resources/data.php';
     $data = "\n\n" . 'string';
     file_put_contents($file, $data);
     $data = Library::loadSerialize($file);
     $this->assertFalse($data);
     unlink($file);
 }
Example #30
0
 /**
  * Set a Contenttype record's individual value.
  *
  * @param string $key
  * @param mixed  $value
  */
 public function setValue($key, $value)
 {
     // Don't set templateFields if not a real contenttype
     if ($key === 'templatefields' && !$this->isRootType) {
         return;
     }
     // Check if the value need to be unserialized.
     if (is_string($value) && substr($value, 0, 2) === "a:") {
         try {
             $unserdata = Lib::smartUnserialize($value);
         } catch (\Exception $e) {
             $unserdata = false;
         }
         if ($unserdata !== false) {
             $value = $unserdata;
         }
     }
     if ($key == 'id') {
         $this->id = $value;
     }
     // Set the user in the object.
     if ($key === 'ownerid' && !empty($value)) {
         $this->user = $this->app['users']->getUser($value);
     }
     // Only set values if they have are actually a field.
     $allowedcolumns = self::getBaseColumns();
     $allowedcolumns[] = 'taxonomy';
     if (!isset($this->contenttype['fields'][$key]) && !in_array($key, $allowedcolumns)) {
         return;
     }
     if (in_array($key, ['datecreated', 'datechanged', 'datepublish', 'datedepublish'])) {
         if (!preg_match("/(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})/", $value)) {
             // @todo Try better date-parsing, instead of just setting it to
             // 'now' (or 'the past' for datedepublish)
             if ($key == 'datedepublish') {
                 $value = null;
             } else {
                 $value = date('Y-m-d H:i:s');
             }
         }
     }
     if ($key === 'templatefields') {
         if (is_string($value) || is_array($value)) {
             if (is_string($value)) {
                 try {
                     $unserdata = Lib::smartUnserialize($value);
                 } catch (\Exception $e) {
                     $unserdata = false;
                 }
             } else {
                 $unserdata = $value;
             }
             if (is_array($unserdata)) {
                 $templateContent = new Content($this->app, $this->getTemplateFieldsContentType(), [], false);
                 $value = $templateContent;
                 $this->populateTemplateFieldsContenttype($value);
                 $templateContent->setValues($unserdata);
             } else {
                 $value = null;
             }
         }
     }
     if (!isset($this->values['datechanged']) || !preg_match("/(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})/", $this->values['datechanged'])) {
         $this->values['datechanged'] = date("Y-m-d H:i:s");
     }
     $this->values[$key] = $value;
 }