Example #1
0
    /**
     * Recursively builds an array of files
     * 
     * @param string  $key  Upload key that we're processing
     * @param mixed  $value  Either a string or an array of the value
     * @param array  $output  The referenced array object for manipulation
     * @param string  $path  A string for colon-delimited path searching
     * @return void
     */
    private static function buildFileArray($key, $value, &$output, $path)
    {
        if (is_array($value)) {
            foreach ($value as $sub_key => $sub_value) {
                if (!isset($output[$sub_key]) || !is_array($output[$sub_key])) {
                    $output[$sub_key] = array();
                }
                $new_path = (empty($path)) ? $sub_key : $path . ':' . $sub_key;
                self::buildFileArray($key, $sub_value, $output[$sub_key], $new_path);
            }
        } else {
            $output[$key] = $value;

            // add error message
            if ($key === 'error') {
                $error_message   = self::getFriendlyErrorMessage($value);
                $success_status  = ($value === UPLOAD_ERR_OK);
                    
                $output['error_message'] = $error_message;
                $output['success']       = $success_status;
            } elseif ($key === 'size') {
                $human_readable_size = File::getHumanSize($value);
                $output['size_human_readable'] = $human_readable_size;
            }
        }
    }
 public function redactor__fetch_files()
 {
     $this->authCheck();
     $dir = Path::tidy(ltrim(Request::get('path'), '/') . '/');
     $file_list = glob($dir . "*.*", GLOB_BRACE);
     $files = array();
     if (count($file_list) > 0) {
         foreach ($file_list as $file) {
             $pi = pathinfo($file);
             $files[] = array('link' => Path::toAsset($file), 'title' => $pi['filename'], 'name' => $pi['basename'], 'size' => File::getHumanSize(File::getSize(Path::assemble(BASE_PATH, $file))));
         }
     }
     echo json_encode($files);
 }
 public function index()
 {
     /*
     |--------------------------------------------------------------------------
     | Paramers
     |--------------------------------------------------------------------------
     |
     | Match overrides Extension. Exclusion applies in both cases.
     |
     */
     $match = $this->fetchParam('match', false);
     $exclude = $this->fetchParam('exclude', false);
     $extension = $this->fetchParam(array('extension', 'type'), false);
     $in = $this->fetchParam(array('in', 'folder', 'from'), false);
     $not_in = $this->fetchParam('not_in', false);
     $file_size = $this->fetchParam('file_size', false);
     $file_date = $this->fetchParam('file_date', false);
     $depth = $this->fetchParam('depth', false);
     $sort_by = $this->fetchParam(array('sort_by', 'order_by'), false);
     $sort_dir = $this->fetchParam(array('sort_dir', 'sort_direction'), 'asc');
     $limit = $this->fetchParam('limit', false);
     if ($in) {
         $in = Helper::explodeOptions($in);
     }
     if ($not_in) {
         $not_in = Helper::explodeOptions($not_in);
     }
     if ($file_size) {
         $file_size = Helper::explodeOptions($file_size);
     }
     if ($extension) {
         $extension = Helper::explodeOptions($extension);
     }
     /*
     |--------------------------------------------------------------------------
     | Finder
     |--------------------------------------------------------------------------
     |
     | Get_Files implements most of the Symfony Finder component as a clean
     | tag wrapper mapped to matched filenames.
     |
     */
     $finder = new Finder();
     if ($in) {
         foreach ($in as $location) {
             $finder->in(Path::fromAsset($location));
         }
     }
     /*
     |--------------------------------------------------------------------------
     | Name
     |--------------------------------------------------------------------------
     |
     | Match is the "native" Finder name() method, which is supposed to
     | implement string, glob, and regex. The glob support is only partial,
     | so "extension" is a looped *single* glob rule iterator.
     |
     */
     if ($match) {
         $finder->name($match);
     } elseif ($extension) {
         foreach ($extension as $ext) {
             $finder->name("*.{$ext}");
         }
     }
     /*
     |--------------------------------------------------------------------------
     | Exclude
     |--------------------------------------------------------------------------
     |
     | Exclude directories from matching. Remapped to "not in" to allow more
     | intuitive differentiation between filename and directory matching.
     |
     */
     if ($not_in) {
         foreach ($not_in as $location) {
             $finder->exclude($location);
         }
     }
     /*
     |--------------------------------------------------------------------------
     | Not Name
     |--------------------------------------------------------------------------
     |
     | Exclude files matching a given pattern: string, regex, or glob.
     | By default we don't allow looking for PHP files. Be smart.
     |
     */
     if ($this->fetchParam('allow_php', false) !== TRUE) {
         $finder->notName("*.php");
     }
     if ($exclude) {
         $finder->notName($exclude);
     }
     /*
     |--------------------------------------------------------------------------
     | File Size
     |--------------------------------------------------------------------------
     |
     | Restrict files by size. Can be chained and allows comparison operators.
     |
     */
     if ($file_size) {
         foreach ($file_size as $size) {
             $finder->size($size);
         }
     }
     /*
     |--------------------------------------------------------------------------
     | File Date
     |--------------------------------------------------------------------------
     |
     | Restrict files by last modified date. Can use comparison operators, and
     | since/after is aliased to >, and until/before to <.
     |
     */
     if ($file_date) {
         $finder->date($file_date);
     }
     /*
     |--------------------------------------------------------------------------
     | Depth
     |--------------------------------------------------------------------------
     |
     | Recursively traverse directories, starting at 0.
     |
     */
     if ($depth) {
         $finder->depth($depth);
     }
     /*
     |--------------------------------------------------------------------------
     | Sort By
     |--------------------------------------------------------------------------
     |
     | Sort by name, file, or type
     |
     */
     if ($sort_by) {
         if ($sort_by === 'file' || $sort_by === 'name') {
             $finder->sortByName();
         } elseif ($sort_by === 'type') {
             $finder->sortByType();
         }
     }
     /*
     |--------------------------------------------------------------------------
     | Assemble File Array
     |--------------------------------------------------------------------------
     |
     | Select the important bits of data on the list of files.
     |
     */
     $matches = $finder->files()->followLinks();
     $files = array();
     foreach ($matches as $file) {
         $files[] = array('extension' => $file->getExtension(), 'filename' => $file->getFilename(), 'file' => Path::toAsset($file->getPathname()), 'name' => Path::toAsset($file->getPathname()), 'size' => File::getHumanSize($file->getSize()), 'size_bytes' => $file->getSize(), 'size_kilobytes' => number_format($file->getSize() / 1024, 2), 'size_megabytes' => number_format($file->getSize() / 1048576, 2), 'size_gigabytes' => number_format($file->getSize() / 1073741824, 2), 'is_image' => File::isImage($file->getPathname()));
     }
     /*
     |--------------------------------------------------------------------------
     | Sort Direction
     |--------------------------------------------------------------------------
     |
     | Set the sort direction, defaulting to "asc" (ascending)
     |
     */
     if ($sort_dir === 'desc') {
         $files = array_reverse($files);
     }
     /*
     |--------------------------------------------------------------------------
     | Randomizing
     |--------------------------------------------------------------------------
     |
     | You can't sort randomly using Symfony finder, so we'll do it manually.
     |
     */
     if ($sort_by === 'random') {
         shuffle($files);
     }
     /*
     |--------------------------------------------------------------------------
     | Limit Files
     |--------------------------------------------------------------------------
     |
     | Limit the number of files returned. Needs to be run after sort_dir to 
     | ensure consistency.
     |
     */
     if ($limit) {
         $files = array_slice($files, 0, $limit);
     }
     return Parse::tagLoop($this->content, $files, true, $this->context);
 }
 /**
  * _render_layout
  * Renders the page
  *
  * @param string $_html HTML of the template to use
  * @param string $template_type Content type of the template
  * @return string
  */
 public function _render_layout($_html, $template_type = 'html')
 {
     if (self::$_layout) {
         $this->data['layout_content'] = $_html;
         if ($template_type != 'html' or self::$_control_panel) {
             extract($this->data);
             ob_start();
             require self::$_layout . ".php";
             $html = ob_get_clean();
         } else {
             if (!File::exists(self::$_layout . ".html")) {
                 Log::fatal("Can't find the specified theme.", 'core', 'template');
                 return '<p style="text-align:center; font-size:28px; font-style:italic; padding-top:50px;">We can\'t find your theme files. Please check your settings.';
             }
             $this->appendNewData($this->data);
             // Fetch layout and parse any front matter
             $layout = Parse::frontMatter(File::get(self::$_layout . '.html'), false);
             $html = Parse::template($layout['content'], Statamic_View::$_dataStore, array($this, 'callback'));
         }
         // inject noparse
         $html = Lex\Parser::injectNoparse($html);
     } else {
         $html = $_html;
     }
     // post-render hook
     $html = \Hook::run('_render', 'after', 'replace', $html, $html);
     Debug::setValue('memory_used', File::getHumanSize(memory_get_usage(true)));
     return $html;
 }
 /**
  * Get list of files from a bucket / directory.
  * @return (array)
  * @todo Pass in destination as querystring parameter
  * @todo Figure out sorting, alpha natural sort
  * @todo Breadcrumbs
  */
 public function fileclerk__list()
 {
     // Force AJAX, except in dev
     if (!Request::isAjax() && FILECLERK_ENV != 'dev') {
         echo FILECLERK_AJAX_WARNING;
         exit;
     }
     // Destination config parameter
     $destination = Request::get('destination');
     $destination = is_null($destination) ? 0 : $destination;
     // Merge configs before we proceed
     $this->config = $this->tasks->merge_configs($destination);
     // Setup client
     self::load_s3();
     // Set default error to false
     $error = false;
     // Do some werk to setup paths
     $bucket = $this->config['bucket'];
     $directory = $this->config['directory'];
     $uri = Request::get('uri');
     $uri = explode('?', $uri);
     $uri = reset($uri);
     $s3_url = Url::tidy('s3://' . join('/', array($bucket, $directory, $uri)));
     // Let's make sure we  have a valid URL before movin' on
     if (Url::isValid($s3_url)) {
         // Just messing around native SDK methods get objects
         if (FALSE) {
             // Trying out listIterator
             $iterator = $this->client->getIterator('ListObjects', array('Bucket' => $this->config['bucket'], 'Delimiter' => '/'), array('limit' => 1000, 'return_prefixes' => true));
             //dd($iterator);
             echo '<pre>';
             foreach ($iterator as $object) {
                 //if( ! isset($object['Prefix']) ) continue; // Skip non-directories
                 echo var_dump($object) . '<br>';
                 //echo var_dump($object) . '<br>';
             }
             echo '</pre>';
             exit;
         }
         // Finder instance
         $finder = new Finder();
         // Finder call
         try {
             $finder->ignoreUnreadableDirs()->ignoreDotFiles(true)->in($s3_url)->depth('== 0');
             $results = iterator_to_array($finder);
         } catch (Exception $e) {
             $error = $e->getMessage();
             header('Content-Type', 'application/json');
             echo self::build_response_json(false, true, FILECLERK_S3_ERROR, $error, 'error', null, null, null);
             exit;
         }
         // Data array for building out view
         $data = array('crumbs' => explode('/', $uri), 'destination' => $destination, 'list' => array());
         // Prepare breadcrumbs
         foreach ($data['crumbs'] as $key => $value) {
             $path = explode('/', $uri, $key + 1 - count($data['crumbs']));
             $path = implode('/', $path);
             //$path = Url::tidy( $path . '/?' . $querystring );
             $path = Url::tidy($path);
             $data['crumbs'][$key] = array('name' => $value, 'path' => $path);
         }
         // Build breadcrumb
         $breadcrumb = Parse::template(self::get_view('_list-breadcrumb'), $data);
         /**
          * Let's make sure we've got somethin' up in this mutha.
          */
         if ($finder->count() > 0) {
             foreach ($finder as $file) {
                 // Get the filename
                 $filename = $file->getFilename();
                 // Set the S3 key string for the objet
                 $key = Url::tidy(join('/', array($directory, $uri, $filename)));
                 // File / directory attributes
                 $this->data = $this->tasks->get_file_data_array();
                 // Set some file data
                 $file_data = array('basename' => $file->getBasename('.' . $file->getExtension()), 'destination' => $destination, 'extension' => $file->getExtension(), 'file' => $file->getPathname(), 'filename' => $file->getFilename(), 'last_modified' => $file->isDir() ? '--' : $file->getMTime(), 'is_file' => $file->isFile(), 'is_directory' => $file->isDir(), 'size' => $file->isDir() ? '--' : File::getHumanSize($file->getSize()), 'size_bytes' => $file->getSize(), 'uri' => $uri);
                 /**
                  * Need to set the uri value
                  */
                 if ($file->isFile()) {
                     // Check if file is an iamge
                     $file_data['is_image'] = self::is_image($file_data['extension']);
                     // Set filesize data
                     $file_data['size_kilobytes'] = $this->tasks->get_size_kilobytes($file_data['size_bytes']);
                     $file_data['size_megabytes'] = $this->tasks->get_size_megabytes($file_data['size_bytes']);
                     $file_data['size_gigabytes'] = $this->tasks->get_size_gigabytes($file_data['size_bytes']);
                 } elseif ($file->isDir()) {
                     if (is_null($uri)) {
                         $file_data['uri'] = Url::tidy('/' . join('/', array($file_data['filename'])));
                     } else {
                         $file_data['uri'] = Url::tidy('/' . join('/', array($uri, $file_data['filename'])));
                     }
                 } else {
                     // Keep on movin' on.
                     continue;
                 }
                 // Set the URL
                 $file_data['url'] = Url::tidy(self::get_url_prefix($uri) . '/' . $filename);
                 // Push file data to a new array with the filename as the key for sorting.
                 $data['list'][$filename] = $file_data;
                 unset($file_data);
             }
             // Nothing returned from Finder
         } else {
             /**
              * Return an error of type dialog that should show a message to the user
              * that there are is nothing to see her. Doh!
              * @return [array] JSON
              * @todo See `self::set_json_return`.
              */
             // echo self::build_response_json(false, true, FILECLERK_LIST_NO_RESULTS, 'No results returned.');
             // exit;
             $no_results_template = File::get(__DIR__ . '/views/error-no-results.html');
             end($data['crumbs']);
             $previous_directory = prev($data['crumbs']);
             echo json_encode(array('error' => TRUE, 'type' => 'dialog', 'code' => FILECLERK_LIST_NO_RESULTS, 'breadcrumb' => $breadcrumb, 'html' => Parse::template($no_results_template, array('previous_directory' => $previous_directory['path']))));
             exit;
         }
     }
     // Need to pass in the destination for root requests.
     $data['destination'] = $destination;
     // Sort this f*****g multi-dimensional array already.
     uksort($data['list'], 'strcasecmp');
     //array_multisort( array_keys($data['list']), SORT_FLAG_CASE, $data['list'] );
     /**
      * THIS ONLY WORKS IN PHP 5.4+. F**K!
      */
     // array_multisort( array_keys($data['list']), SORT_NATURAL | SORT_FLAG_CASE, $data['list'] );
     // Now we need to tweak the array for parsing.
     foreach ($data['list'] as $filename => $filedata) {
         $data['list'][] = $filedata;
         unset($data['list'][$filename]);
     }
     // We're basically parsing template partials here to build out the larger view.
     $parsed_data = array('list' => Parse::template(self::get_view('_list'), $data));
     // Put it all together
     $ft_template = File::get(__DIR__ . '/views/list.html');
     // Return JASON
     header('Content-Type', 'application/json');
     echo self::build_response_json(true, false, FILECLERK_LIST_SUCCESS, null, null, $data, $breadcrumb, Parse::template($ft_template, $parsed_data));
     exit;
 }