Файл: wboard/source/system/classes/helper.php
Строк: 266
<?php
class Helper
{
    protected $model;
    protected $lng;
    protected $tpl;
    protected $network;
    protected $settings;
    protected $is_root;
    protected $path;
    public function __construct($model, $lng, $tpl, $network, $settings, $is_root, $path)
    {
        $this->model    =& $model;
        $this->lng      =& $lng;
        $this->tpl      =& $tpl;
        $this->network  =& $network;
        $this->settings =& $settings;
        $this->is_root  =& $is_root;
        $this->path     =& $path;
    }
    /**
     * Prepare to display list of CSS styles
     * @param (boolean) $error Display error mesage?
     * @return (string)
     */
    public function css_styles_list($error)
    {
        $get_styles = glob($this->path . 'files' . DIRECTORY_SEPARATOR . 'styles' . DIRECTORY_SEPARATOR . '*.css');
        foreach ($get_styles as $key => $item) {
            $get_styles[$key] = htmlspecialchars(str_replace(
                $this->path . 'files' . DIRECTORY_SEPARATOR . 'styles' . DIRECTORY_SEPARATOR,
                '',
                str_replace('.css', '', $item)
            ));
        }
        return $this->tpl->load('__helper_css_styles', array(
            'css_styles' => $get_styles,
            'current_style' => $this->settings['user']['style'],
            'error' => $error,
        ));
    }
    /**
     * Check css style for exists
     * @param (string) $style Name of style
     * @return (boolean)
     */
    public function css_exists($style)
    {
        return is_file($this->path . 'files' . DIRECTORY_SEPARATOR . 'styles' . DIRECTORY_SEPARATOR . $style . '.css');
    }
    /**
     * Prepare to display list of threads
     * @param (array) $threads List of threads
     * @return (string)
     */
    public function display_threads($threads)
    {
        $list = '';
        foreach ($threads as $item) {
            $list .= $this->tpl->load('__helper_thread_item', array(
                'board'    => htmlspecialchars($item['board']),
                'id'       => intval($item['id']),
                'theme'    => htmlspecialchars($item['theme'], ENT_QUOTES, 'UTF-8'),
                'time'     => $this->display_time($item['time']),
                'name'     => htmlspecialchars($item['name'], ENT_QUOTES, 'UTF-8'),
                'text'     => $item['text'],
                'last'     => $this->display_time($item['last']),
                'lastpost' => $item['lastpost'],
                'icon'     => anchor('files/styles/' . $this->settings['user']['style'] . '/thread.png'),
            ));
        }
        return $list;
    }
    /**
     * Prepare to dipslay list of posts
     * @param (string) $board Name of board
     * @param (int) $tid ID of thread
     * @param (array) $data List of posts
     * @return (string)
     */
    public function display_posts($board, $tid, $data)
    {
        $return = '';
        $tid = intval($tid);
        $i = 0;
        foreach ($data as $item) {
            if (!empty($item['img'])) {
                // Handle images
                $img_path = 'files/boards/' . $board . '/';
                $item['image'] = array(
                    'src' => anchor($img_path . $item['img']['file'] , '<img src="' . anchor($img_path . $item['img']['preview']) . '" alt="" />', 'target="_blank"'),
                    'info' => $item['img']['ext'] . ', ' . $item['img']['size'] . ', ' . $item['img']['resolution'],
                );
            }
            unset($item['img']);
            // Handle Answers
            if (!empty($item['answers'])) {
                foreach ($item['answers'] as $a_key => $aid) {
                    $item['answers'][$a_key] = anchor($board . '/' . $tid . '/#' . $aid, '>>' . $aid);
                }
                $item['answers'] = array_unique($item['answers']);
                $item['answers'] = implode(', ', $item['answers']);
            }
            if ($this->is_root) {
                // Link to remove post
                $item['delete'] = anchor('w_action/remove/index/' . $board . '/' . $tid . '/' . $item['id'], $this->lng->delete);
            }
            if (!$this->is_root) {
                unset($item['user_data']);
            }
            $item['op'] = $i == 0 ? TRUE : FALSE;
            $return .= $this->tpl->load('__helper_display_posts_item', $item);
            $i++;
        }
        return $return;
    }
    /**
     * Format time with timeshift (GMT+3 By default)
     * @param (int) $time Time
     * @return (string) day.month.Year / Hour:minutes:seconds
     */
    public function display_time($time)
    {
        return date('d.m.Y / H:i:s', ($time + (3600 * $this->settings['user']['timeshift'])));
    }
    /**
     * Remove directory
     * @param (string) $dir Path to directory
     * @return (boolean)
     */
    public function delete_directory($dir)
    {
        if (!file_exists($dir)) {
            return true;
        }
        if (!is_dir($dir) || is_link($dir)) {
            return unlink($dir);
        }
        foreach (scandir($dir) as $item) {
            if ($item == '.' || $item == '..') {
                continue;
            }
            if (!$this->delete_directory($dir . DIRECTORY_SEPARATOR . $item)) {
                chmod($dir . DIRECTORY_SEPARATOR . $item, 0777);
                if (!$this->delete_directory($dir . DIRECTORY_SEPARATOR . $item)) {
                    return false;
                }
            }
        }
        return rmdir($dir);
    }
    /**
     * Markup message (BB-Codes, Wakaba markup)
     * @param (string) $string Message
     * @param (string) $board Name of board (for answer backlink)
     * @param (int) $thread ID of thread (for answer backlink)
     * @return (string)
     */
    public function markup_message($string, $board, $thread)
    {
        if (!function_exists('del_markup')) {
            function del_markup($str)
            {
                return strtr($str, array(
                    '>' => '>',
                    '[' => '[',
                    ']' => ']',
                    '/' => '/',
                    '%' => '%',
                    '>' => '>',
                    '<' => '<',
                    '_' => '_',
                    '*' => '*',
                    '^' => '^',
                    '/' => '/',
                    ':' => ':',
                    '=' => '=',
                ));
            }
        }
        if (!function_exists('process_code')) {
            function process_code($str)
            {
                return '<code>'    . del_markup($str[1]) . '</code>';
            }
        }
        if (!function_exists('process_url')) {
            function process_url($url) {
                return '<a href="' . del_markup($url[1]) . '">' . del_markup($url[2]) . '</a>';
            }
        }
        $string = htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
        $string = preg_replace_callback('~`(.+?)`~ius', 'process_code', $string);
        $string = preg_replace_callback('~\[url=(https?://.+?)\](.+?)\[/url\]~', 'process_url', $string);
        $string = preg_replace(
            array(
                '~>>([d]+)~ius',                                   // Answer to post
                '~[big](.+?)[/big]~ius',                                 // Big font
                '~[small](.+?)[/small]~ius',                             // Small font
                "~^>(.+?)$~iusm",                                        // Quote
                '~[sub](.+?)[/sub]~ius',                                  // Sub area
                '~[sup](.+?)[/sup]~ius',                                  // Sup area
                '~%%(.+?)%%~ius',                                         // Spoiler
                '~**(.+?)**~ius',                                         // Bold
                '~__(.+?)__~ius',                                           // Bold
                '~*(.+?)*~ius',                                             // Italic
                '~_(.+?)_~ius',                                             // Italic
                '~^(.+?)^~ius',                                             // Strike
                '~[rn]+~',
            ),
            array(
                anchor($board . '/' . $thread . '/#$1', '>>$1'),
                '<span style="font-size:14pt">$1</span>',                      // Big
                '<span style="font-size:x-small">$1</span>',                   // Small
                '<span class="quote">> $1</span>',                          // Quote
                '<sub>$1</sub>',                                               // Sub
                '<sup>$1</sup>',                                               // Sup
                '<span class="spoiler">$1</span>',                             // Spiiler
                '<span style="font-weight:bold">$1</span>',                    // Bold
                '<span style="font-weight:bold">$1</span>',                    // Bold
                '<span style="font-style:italic">$1</span>',                   // Italic
                '<span style="font-style:italic">$1</span>',                   // Italic
                '<span style="text-decoration: line-through">$1</span>',       // Strike
                "rn",
            ),
            $string
        );
        $string = nl2br(strtr($string, array(
            '[big]' => '', '[/big]' => '',
            '[small]' => '', '[/small]' => '',
            '[code]' => '', '[/code]' => '',
            '[url=]' => '', '[/url]' => '',
            '[sub]' => '', '[/sub]' => '',
            '[sup]' => '', '[/sup]' => ''
        )));
        return $string;
    }
    /**
     * Check file and prepare for upload
     * @param (string) $board Name of board
     * @param (array) $data Data of file
     * @return (array)
     */
    public function prepare_file($board, $data)
    {
        $file = is_array($data) ? $data : array('error' => 4);
        $error = '';
        $upload_errors = array(
            // The uploaded file was only partially uploaded.
            3 => 'upload_err_partial',
            // Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3.
            6 => 'upload_err_no_tmp_dir',
            // Failed to write file to disk. Introduced in PHP 5.1.0.
            7 => 'unable_to_upload',
            // A PHP extension stopped the file upload.
            8 => 'upload_err_extension',
        );
        $error_file = isset($file['error']) ? intval($file['error']) : 4;
        if (array_key_exists($error_file, $upload_errors)) {
            $error = $this->lng->$upload_errors[$error_file];
        } elseif($error_file != 4) {
            if ($file['size'] > 5242880) {
                // Check file size
                $error = $this->lng->file_size_big;
            } else {
                // Get extension
                $temp = explode('.', $file['name']);
                $ext = array_pop($temp);
                $file['name'] = md5($file['name']);
                unset($temp);
                // Check extension
                if (!in_array($ext, array('gif', 'jpg', 'jpeg', 'png',))) {
                    $error = $this->lng->wrong_file_extension;
                } else {
                    $image_size = getimagesize($file['tmp_name']);
                    $types = array(1 => 'gif', 2=> 'jpg', 3 => 'png');
                    $image_type = array_key_exists($image_size[2], $types) ? $types[$image_size[2]] : FALSE;
                    // Create image from temporary file
                    switch ($image_type) {
                        case 'gif':
                            $image = imagecreatefromgif($file['tmp_name']);
                            break;
                        case 'jpg':
                            $image = imagecreatefromjpeg($file['tmp_name']);
                            break;
                        case 'png':
                            $image = imagecreatefrompng($file['tmp_name']);
                            break;
                        default:
                            $error = $this->lng->wrong_file_extension;
                    }
                }
                if (empty($error) && is_file(
                    $this->path . 'files' . DIRECTORY_SEPARATOR
                    . 'boards' . DIRECTORY_SEPARATOR
                    . $board . DIRECTORY_SEPARATOR
                    . $file['name'] . '.' . $ext
                )) {
                    // File with such name already exists. Change name...
                    $file['name'] .= '_' . time() . rand(1000, 9999);
                }
            }
        } else {
            return NULL;
        }
        return !empty($error)
            ? $error
            : array(
                'resource' => $image,             // Image
                'name'     => $file['name'],      // Name
                'tmp_name' => $file['tmp_name'],  // Path to temporary file
                'ext'      => $ext,               // Extension
                'size'     => $file['size'],      // Size of file
                'width'    => $image_size[0],     // Width of image
                'height'   => $image_size[1]      // Height of image
            );
    }
    /**
     * Save file
     * @param (string) $board Name of board
     * @param (array) $file Data of file
     * @return (array|NULL)
     */
    public function save_file($board, $file)
    {
        if (is_array($file)) {
            // Path to files
            $path = $this->path . 'files' . DIRECTORY_SEPARATOR . 'boards' . DIRECTORY_SEPARATOR . $board . DIRECTORY_SEPARATOR;
            $preview = $file['name'] . '_preview.png';
            $filename = $file['name'] . '.' . $file['ext'];
            // Calculate preview resolution
            if ($file['width'] > 200 || $file['height'] > 320) {
                $x_ratio     = 200 / $file['width'];
                $y_ratio     = 320 / $file['height'];
                $ratio       = min($x_ratio, $y_ratio);
                $use_x_ratio = ($x_ratio == $ratio);
                $new_width   = $use_x_ratio  ? 200  : floor($file['width'] * $ratio);
                $new_height  = !$use_x_ratio ? 320 : floor($file['height'] * $ratio);
            } else {
                $new_width = $file['width'];
                $new_height = $file['height'];
            }
            $image_create = 'imagecreate' . ($file['ext'] == 'gif' ? '' : 'truecolor');
            $image_dest  = $image_create($new_width, $new_height);
            // Save transparent
            if ($file['ext'] == 'gif') {
                imagecolortransparent($image_dest, imagecolorallocate($image_dest, 0, 0, 0));
            } elseif ($file['ext'] == 'png') {
                imagealphablending($image_dest, false);
                imagesavealpha($image_dest, true);
            }
            // Resize
            imagecopyresampled(
                $image_dest, $file['resource'], 0, 0, 0, 0,
                $new_width, $new_height, $file['width'], $file['height']
            );
            // Save preview
            imagepng($image_dest, $path . $preview);
            imagedestroy($file['resource']);
            imagedestroy($image_dest);
            // Upload dest
            copy($file['tmp_name'], $path . $filename);
            return array('file' => $filename, 'preview' => $preview);
        }
        return NULL;
    }
}