Exemple #1
0
 function ukko_install($settings)
 {
     if (!file_exists($settings['uri'])) {
         @mkdir($settings['uri'], 0777) or error("Couldn't create " . $settings['uri'] . ". Check permissions.", true);
     }
     file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', array()));
 }
Exemple #2
0
 public function build($settings, $board_name)
 {
     global $config, $board;
     openBoard($board_name);
     $recent_images = array();
     $recent_posts = array();
     $stats = array();
     $query = query(sprintf("SELECT *, `id` AS `thread_id`,\n\t\t\t\t(SELECT COUNT(`id`) FROM ``posts_%s`` WHERE `thread` = `thread_id`) AS `reply_count`,\n\t\t\t\t(SELECT SUM(`num_files`) FROM ``posts_%s`` WHERE `thread` = `thread_id` AND `num_files` IS NOT NULL) AS `image_count`,\n\t\t\t\t'%s' AS `board` FROM ``posts_%s`` WHERE `thread`  IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name, $board_name, $board_name)) or error(db_error());
     while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $post['id']);
         $post['board_name'] = $board['name'];
         if ($post['embed'] && preg_match('/^https?:\\/\\/(\\w+\\.)?(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([a-zA-Z0-9\\-_]{10,11})(&.+)?$/i', $post['embed'], $matches)) {
             $post['youtube'] = $matches[2];
         }
         if (isset($post['files'])) {
             $files = json_decode($post['files']);
             if ($files[0]->file == 'deleted') {
                 continue;
             }
             $post['file'] = $config['uri_thumb'] . $files[0]->thumb;
         }
         $recent_posts[] = $post;
     }
     $required_scripts = array('js/jquery.min.js', 'js/jquery.mixitup.min.js', 'js/catalog.js');
     foreach ($required_scripts as $i => $s) {
         if (!in_array($s, $config['additional_javascript'])) {
             $config['additional_javascript'][] = $s;
         }
     }
     file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => $recent_images, 'recent_posts' => $recent_posts, 'stats' => $stats, 'board' => $board_name, 'link' => $config['root'] . $board['dir'])));
 }
Exemple #3
0
function sitemap_build($action, $settings, $board)
{
    global $config;
    // Possible values for $action:
    //	- all (rebuild everything, initialization)
    //	- news (news has been updated)
    //	- boards (board list changed)
    //	- post (a post has been made)
    //	- thread (a thread has been made)
    if ($action != 'post-thread' && $action != 'post-delete') {
        return;
    }
    if ($settings['regen_time'] > 0) {
        if ($last_gen = @filemtime($settings['path'])) {
            if (time() - $last_gen < (int) $settings['regen_time']) {
                return;
            }
            // Too soon
        }
    }
    $boards = explode(' ', $settings['boards']);
    $threads = array();
    foreach ($boards as $board) {
        $query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM ``posts_%s`` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM ``posts_%s`` WHERE `thread` IS NULL", $board, $board)) or error(db_error());
        $threads[$board] = $query->fetchAll(PDO::FETCH_ASSOC);
    }
    file_write($settings['path'], Element('themes/sitemap/sitemap.xml', array('settings' => $settings, 'config' => $config, 'threads' => $threads, 'boards' => $boards)));
}
Exemple #4
0
 public static function homepage($settings)
 {
     global $config;
     $settings['no_recent'] = (int) $settings['no_recent'];
     $query = query("SELECT * FROM `news` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error());
     $news = $query->fetchAll(PDO::FETCH_ASSOC);
     return Element('themes/basic/index.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'news' => $news));
 }
Exemple #5
0
 public static function sidebar($settings)
 {
     global $config, $board;
     $categories = $config['categories'];
     foreach ($categories as &$boards) {
         foreach ($boards as &$board) {
             $title = boardTitle($board);
             if (!$title) {
                 $title = $board;
             }
             // board doesn't exist, but for some reason you want to display it anyway
             $board = array('title' => $title, 'uri' => sprintf($config['board_path'], $board));
         }
     }
     return Element('themes/categories/sidebar.html', array('settings' => $settings, 'config' => $config, 'categories' => $categories));
 }
Exemple #6
0
 public function build($settings, $board_name)
 {
     global $config, $board;
     openBoard($board_name);
     $recent_images = array();
     $recent_posts = array();
     $stats = array();
     $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error());
     while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $post['id']);
         $post['board_name'] = $board['name'];
         $post['file'] = $config['uri_thumb'] . $post['thumb'];
         $recent_posts[] = $post;
     }
     file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => $recent_images, 'recent_posts' => $recent_posts, 'stats' => $stats, 'board' => $board_name, 'link' => $config['root'] . $board['dir'])));
 }
Exemple #7
0
 public function build($settings, $board_name)
 {
     global $config, $board;
     openBoard($board_name);
     $recent_images = array();
     $recent_posts = array();
     $stats = array();
     $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error());
     while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $post['id']);
         $post['board_name'] = $board['name'];
         $post['file'] = $config['uri_thumb'] . $post['thumb'];
         if ($post['embed'] && preg_match('/^https?:\\/\\/(\\w+\\.)?(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([a-zA-Z0-9\\-_]{10,11})(&.+)?$/i', $post['embed'], $matches)) {
             $post['youtube'] = $matches[2];
         }
         $recent_posts[] = $post;
     }
     file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => $recent_images, 'recent_posts' => $recent_posts, 'stats' => $stats, 'board' => $board_name, 'link' => $config['root'] . $board['dir'])));
 }
Exemple #8
0
 public function build($index = false)
 {
     global $board, $config, $debug;
     $built = Element('post_thread.html', array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index));
     if (!$this->mod && $index && $config['cache']['enabled']) {
         cache::set($this->cache_key($index), $built);
     }
     return $built;
 }
Exemple #9
0
    $query = prepare('INSERT INTO ``mods`` VALUES (NULL, :username, :password, :salt, :type, :boards, :email)');
    $query->bindValue(':username', $username);
    $query->bindValue(':password', $password);
    $query->bindValue(':salt', $salt);
    $query->bindValue(':type', 20);
    $query->bindValue(':boards', $uri);
    $query->bindValue(':email', $email);
    $query->execute() or error(db_error($query));
    $query = prepare('INSERT INTO ``boards`` (`uri`, `title`, `subtitle`) VALUES (:uri, :title, :subtitle)');
    $query->bindValue(':uri', $_POST['uri']);
    $query->bindValue(':title', $_POST['title']);
    $query->bindValue(':subtitle', $_POST['subtitle']);
    $query->execute() or error(db_error($query));
    $query = Element('posts.sql', array('board' => $uri));
    query($query) or error(db_error());
    if (!openBoard($_POST['uri'])) {
        error(_("Couldn't open board after creation."));
    }
    if ($config['cache']['enabled']) {
        cache::delete('all_boards');
    }
    // Build the board
    buildIndex();
    rebuildThemes('boards');
    $query = prepare("INSERT INTO ``board_create``(uri) VALUES(:uri)");
    $query->bindValue(':uri', $uri);
    $query->execute() or error(db_error());
    _syslog(LOG_NOTICE, "New board: {$uri}");
    $body = Element("8chan/create_success.html", array("config" => $config, "password" => $_POST['password'], "uri" => $uri));
    echo Element("page.html", array("config" => $config, "body" => $body, "title" => _("Success"), "subtitle" => _("This was a triumph")));
}
Exemple #10
0
 public function homepage($settings)
 {
     global $config, $board;
     $recent_images = array();
     $recent_posts = array();
     $stats = array();
     $boards = listBoards();
     $query = '';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `files` IS NOT NULL UNION ALL ", $_board['uri'], $_board['uri']);
     }
     $query = '';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` UNION ALL ", $_board['uri'], $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int) $settings['limit_posts'], $query);
     $query = query($query) or error(db_error());
     while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
         openBoard($post['board']);
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post) . '#' . $post['id'];
         if ($post['body'] != "") {
             $post['snippet'] = pm_snippet($post['body'], 128);
         } else {
             $post['snippet'] = "<em>" . _("(no comment)") . "</em>";
         }
         $post['board_name'] = $board['name'];
         $recent_posts[] = $post;
     }
     // Total posts
     $query = 'SELECT SUM(`top`) FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT MAX(`id`) AS `top` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $stats['total_posts'] = number_format($query->fetchColumn());
     // Unique IPs
     $query = 'SELECT COUNT(DISTINCT(`ip`)) FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT `ip` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $stats['unique_posters'] = number_format($query->fetchColumn());
     // Active content
     $query = 'SELECT DISTINCT(`files`) FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT `files` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ' WHERE `num_files` > 0) AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $files = $query->fetchAll();
     $stats['active_content'] = 0;
     foreach ($files as &$file) {
         preg_match_all('/"size":([0-9]*)/', $file[0], $matches);
         $stats['active_content'] += array_sum($matches[1]);
     }
     return Element('themes/recent_textonly/recent_textonly.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_posts' => $recent_posts, 'stats' => $stats));
 }
Exemple #11
0
    $like = str_replace('%', '%%', $like);
    $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE " . $like . " ORDER BY `time` DESC LIMIT :limit", $board['uri']));
    $query->bindValue(':limit', $search_limit, PDO::PARAM_INT);
    $query->execute() or error(db_error($query));
    if ($query->rowCount() == $search_limit) {
        _syslog(LOG_WARNING, 'Query too broad.');
        $body .= '<p class="unimportant" style="text-align:center">(' . _('Query too broad.') . ')</p>';
        echo Element('page.html', array('config' => $config, 'title' => 'Search', 'body' => $body));
        exit;
    }
    $temp = '';
    while ($post = $query->fetch()) {
        if (!$post['thread']) {
            $po = new Thread($post);
        } else {
            $po = new Post($post);
        }
        $temp .= $po->build(true) . '<hr/>';
    }
    if (!empty($temp)) {
        $_body .= '<fieldset><legend>' . sprintf(ngettext('%d result in', '%d results in', $query->rowCount()), $query->rowCount()) . ' <a href="/' . sprintf($config['board_path'], $board['uri']) . $config['file_index'] . '">' . sprintf($config['board_abbreviation'], $board['uri']) . ' - ' . $board['title'] . '</a></legend>' . $temp . '</fieldset>';
    }
    $body .= '<hr/>';
    if (!empty($_body)) {
        $body .= $_body;
    } else {
        $body .= '<p style="text-align:center" class="unimportant">(' . _('No results.') . ')</p>';
    }
}
echo Element('page.html', array('config' => $config, 'title' => _('Search'), 'body' => '' . $body));
Exemple #12
0
function mod_edit_page($id)
{
    global $config, $mod, $board;
    $query = prepare('SELECT * FROM ``pages`` WHERE `id` = :id');
    $query->bindValue(':id', $id);
    $query->execute() or error(db_error($query));
    $page = $query->fetch();
    if (!$page) {
        error(_('Could not find the page you are trying to edit.'));
    }
    if (!$page['board'] && $mod['boards'][0] !== '*') {
        error($config['error']['noaccess']);
    }
    if (!hasPermission($config['mod']['edit_pages'], $page['board'])) {
        error($config['error']['noaccess']);
    }
    if ($page['board'] && !openBoard($page['board'])) {
        error($config['error']['noboard']);
    }
    if (isset($_POST['method'], $_POST['content'])) {
        $content = $_POST['content'];
        $method = $_POST['method'];
        $page['type'] = $method;
        if (!in_array($method, array('markdown', 'html', 'infinity'))) {
            error(_('Unrecognized page markup method.'));
        }
        switch ($method) {
            case 'markdown':
                $write = purify_html(markdown($content));
                break;
            case 'html':
                if (hasPermission($config['mod']['rawhtml'])) {
                    $write = $content;
                } else {
                    $write = purify_html($content);
                }
                break;
            case 'infinity':
                $c = $content;
                markup($content);
                $write = $content;
                $content = $c;
        }
        if (!isset($write) or !$write) {
            error(_('Failed to mark up your input for some reason...'));
        }
        $query = prepare('UPDATE ``pages`` SET `type` = :method, `content` = :content WHERE `id` = :id');
        $query->bindValue(':method', $method);
        $query->bindValue(':content', $content);
        $query->bindValue(':id', $id);
        $query->execute() or error(db_error($query));
        $fn = ($board['uri'] ? $board['uri'] . '/' : '') . $page['name'] . '.html';
        $body = "<div class='ban'>{$write}</div>";
        $html = Element('page.html', array('config' => $config, 'body' => $body, 'title' => utf8tohtml($page['title'])));
        file_write($fn, $html);
        modLog("Edited page {$page['name']} <span class='unimportant'>(#{$page['id']})</span>");
    }
    if (!isset($content)) {
        $query = prepare('SELECT `content` FROM ``pages`` WHERE `id` = :id');
        $query->bindValue(':id', $id);
        $query->execute() or error(db_error($query));
        $content = $query->fetchColumn();
    }
    mod_page(sprintf(_('Editing static page: %s'), $page['name']), 'mod/edit_page.html', array('page' => $page, 'token' => make_secure_link_token("edit_page/{$id}"), 'content' => prettify_textarea($content), 'board' => $board));
}
Exemple #13
0
 private function saveForBoard($board_name, $recent_posts, $board_link = null)
 {
     global $board, $config;
     if ($board_link === null) {
         $board_link = $config['root'] . $board['dir'];
     }
     $required_scripts = array('js/jquery.min.js', 'js/jquery.mixitup.min.js', 'js/catalog.js');
     // Include scripts that haven't been yet included
     foreach ($required_scripts as $i => $s) {
         if (!in_array($s, $config['additional_javascript'])) {
             $config['additional_javascript'][] = $s;
         }
     }
     file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', array('settings' => $this->settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => array(), 'recent_posts' => $recent_posts, 'stats' => array(), 'board' => $board_name, 'link' => $board_link)));
 }
Exemple #14
0
function mod_config($board_config = false)
{
    global $config, $mod, $board;
    if ($board_config && !openBoard($board_config)) {
        error($config['error']['noboard']);
    }
    if (!hasPermission($config['mod']['edit_config'], $board_config)) {
        error($config['error']['noaccess']);
    }
    $config_file = $board_config ? $board['dir'] . 'config.php' : 'inc/instance-config.php';
    if ($config['mod']['config_editor_php']) {
        $readonly = !(is_file($config_file) ? is_writable($config_file) : is_writable(dirname($config_file)));
        if (!$readonly && isset($_POST['code'])) {
            $code = $_POST['code'];
            // Save previous instance_config if php_check_syntax fails
            $old_code = file_get_contents($config_file);
            file_put_contents($config_file, $code);
            $resp = shell_exec_error('php -l ' . $config_file);
            if (preg_match('/No syntax errors detected/', $resp)) {
                header('Location: ?/config' . ($board_config ? '/' . $board_config : ''), true, $config['redirect_http']);
                return;
            } else {
                file_put_contents($config_file, $old_code);
                error($config['error']['badsyntax'] . $resp);
            }
        }
        $instance_config = @file_get_contents($config_file);
        if ($instance_config === false) {
            $instance_config = "<?php\n\n// This file does not exist yet. You are creating it.";
        }
        $instance_config = str_replace("\n", '&#010;', utf8tohtml($instance_config));
        mod_page(_('Config editor'), 'mod/config-editor-php.html', array('php' => $instance_config, 'readonly' => $readonly, 'boards' => listBoards(), 'board' => $board_config, 'file' => $config_file, 'token' => make_secure_link_token('config' . ($board_config ? '/' . $board_config : ''))));
        return;
    }
    require_once 'inc/mod/config-editor.php';
    $conf = config_vars();
    foreach ($conf as &$var) {
        if (is_array($var['name'])) {
            $c =& $config;
            foreach ($var['name'] as $n) {
                $c =& $c[$n];
            }
        } else {
            $c = @$config[$var['name']];
        }
        $var['value'] = $c;
    }
    unset($var);
    if (isset($_POST['save'])) {
        $config_append = '';
        foreach ($conf as $var) {
            $field_name = 'cf_' . (is_array($var['name']) ? implode('/', $var['name']) : $var['name']);
            if ($var['type'] == 'boolean') {
                $value = isset($_POST[$field_name]);
            } elseif (isset($_POST[$field_name])) {
                $value = $_POST[$field_name];
            } else {
                continue;
            }
            // ???
            if (!settype($value, $var['type'])) {
                continue;
            }
            // invalid
            if ($value != $var['value']) {
                // This value has been changed.
                $config_append .= '$config';
                if (is_array($var['name'])) {
                    foreach ($var['name'] as $name) {
                        $config_append .= '[' . var_export($name, true) . ']';
                    }
                } else {
                    $config_append .= '[' . var_export($var['name'], true) . ']';
                }
                $config_append .= ' = ';
                if (@$var['permissions'] && isset($config['mod']['groups'][$value])) {
                    $config_append .= $config['mod']['groups'][$value];
                } else {
                    $config_append .= var_export($value, true);
                }
                $config_append .= ";\n";
            }
        }
        if (!empty($config_append)) {
            $config_append = "\n// Changes made via web editor by \"" . $mod['username'] . "\" @ " . date('r') . ":\n" . $config_append . "\n";
            if (!is_file($config_file)) {
                $config_append = "<?php\n\n{$config_append}";
            }
            if (!@file_put_contents($config_file, $config_append, FILE_APPEND)) {
                $config_append = htmlentities($config_append);
                if ($config['minify_html']) {
                    $config_append = str_replace("\n", '&#010;', $config_append);
                }
                $page = array();
                $page['title'] = 'Cannot write to file!';
                $page['config'] = $config;
                $page['body'] = '
					<p style="text-align:center">Tinyboard could not write to <strong>' . $config_file . '</strong> with the ammended configuration, probably due to a permissions error.</p>
					<p style="text-align:center">You may proceed with these changes manually by copying and pasting the following code to the end of <strong>' . $config_file . '</strong>:</p>
					<textarea style="width:700px;height:370px;margin:auto;display:block;background:white;color:black" readonly>' . $config_append . '</textarea>
				';
                echo Element('page.html', $page);
                exit;
            }
        }
        header('Location: ?/config' . ($board_config ? '/' . $board_config : ''), true, $config['redirect_http']);
        exit;
    }
    mod_page(_('Config editor') . ($board_config ? ': ' . sprintf($config['board_abbreviation'], $board_config) : ''), 'mod/config-editor.html', array('boards' => listBoards(), 'board' => $board_config, 'conf' => $conf, 'file' => $config_file, 'token' => make_secure_link_token('config' . ($board_config ? '/' . $board_config : ''))));
}
Exemple #15
0
 public function homepage($settings)
 {
     global $config, $board;
     $recent_images = array();
     $recent_posts = array();
     $stats = array();
     $boards = listBoards();
     $query = '';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `files` IS NOT NULL UNION ALL ", $_board['uri'], $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int) $settings['limit_images'], $query);
     if ($query == '') {
         error(_("Can't build the RecentPosts theme, because there are no boards to be fetched."));
     }
     $query = query($query) or error(db_error());
     while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
         openBoard($post['board']);
         if (isset($post['files'])) {
             $files = json_decode($post['files']);
         }
         if ($files[0]->file == 'deleted') {
             continue;
         }
         // board settings won't be available in the template file, so generate links now
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post) . '#' . $post['id'];
         if ($files) {
             if ($files[0]->thumb == 'spoiler') {
                 $tn_size = @getimagesize($config['spoiler_image']);
                 $post['src'] = $config['spoiler_image'];
                 $post['thumbwidth'] = $tn_size[0];
                 $post['thumbheight'] = $tn_size[1];
             } else {
                 $post['src'] = $config['uri_thumb'] . $files[0]->thumb;
             }
         }
         $recent_images[] = $post;
     }
     $query = '';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` UNION ALL ", $_board['uri'], $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int) $settings['limit_posts'], $query);
     $query = query($query) or error(db_error());
     while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
         openBoard($post['board']);
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post) . '#' . $post['id'];
         if ($post['body'] != "") {
             $post['snippet'] = pm_snippet($post['body'], 30);
         } else {
             $post['snippet'] = "<em>" . _("(no comment)") . "</em>";
         }
         $post['board_name'] = $board['name'];
         $recent_posts[] = $post;
     }
     // Total posts
     $query = 'SELECT SUM(`top`) FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT MAX(`id`) AS `top` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $stats['total_posts'] = number_format($query->fetchColumn());
     // Unique IPs
     $query = 'SELECT COUNT(DISTINCT(`ip`)) FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT `ip` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $stats['unique_posters'] = number_format($query->fetchColumn());
     // Active content
     $query = 'SELECT DISTINCT(`files`) FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT `files` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ' WHERE `num_files` > 0) AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $files = $query->fetchAll();
     $stats['active_content'] = 0;
     foreach ($files as &$file) {
         preg_match_all('/"size":([0-9]*)/', $file[0], $matches);
         $stats['active_content'] += array_sum($matches[1]);
     }
     return Element('themes/recent/recent.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => $recent_images, 'recent_posts' => $recent_posts, 'stats' => $stats));
 }
Exemple #16
0
 public function build($index = false, $isnoko50 = false)
 {
     global $board, $config, $debug;
     $hasnoko50 = $this->postCount() >= $config['noko50_min'];
     event('show-thread', $this);
     $file = $index && $config['file_board'] ? 'post_thread_fileboard.html' : 'post_thread.html';
     $built = Element($file, array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50, 'mod' => $this->mod));
     return $built;
 }
Exemple #17
0
 public function build($mod = false)
 {
     global $config, $board;
     $boards = listBoards();
     $body = '';
     $overflow = array();
     $board = array('url' => $this->settings['uri'], 'name' => $this->settings['title'], 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit']));
     $query = '';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], explode(' ', $this->settings['exclude']))) {
             continue;
         }
         $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC', $query);
     $query = query($query) or error(db_error());
     $count = 0;
     $threads = array();
     while ($post = $query->fetch()) {
         if (!isset($threads[$post['board']])) {
             $threads[$post['board']] = 1;
         } else {
             $threads[$post['board']] += 1;
         }
         if ($count < $this->settings['thread_limit']) {
             $config['uri_thumb'] = '/' . $post['board'] . '/thumb/';
             $config['uri_img'] = '/' . $post['board'] . '/src/';
             $board['dir'] = $post['board'] . '/';
             $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod);
             $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board']));
             $posts->bindValue(':id', $post['id']);
             $posts->bindValue(':limit', $post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'], PDO::PARAM_INT);
             $posts->execute() or error(db_error($posts));
             $num_images = 0;
             while ($po = $posts->fetch()) {
                 $config['uri_thumb'] = '/' . $post['board'] . '/thumb/';
                 $config['uri_img'] = '/' . $post['board'] . '/src/';
                 if ($po['files']) {
                     $num_images++;
                 }
                 $thread->add(new Post($po, $mod ? '?/' : $config['root'], $mod));
             }
             if ($posts->rowCount() == ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) {
                 $ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM ``posts_%s`` WHERE `files` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board']));
                 $ct->bindValue(':thread', $post['id'], PDO::PARAM_INT);
                 $ct->execute() or error(db_error($count));
                 $c = $ct->fetch();
                 $thread->omitted = $c['num'] - ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']);
                 $c = $ct->fetch();
                 $thread->omitted_images = $c['num'] - $num_images;
             }
             $thread->posts = array_reverse($thread->posts);
             $body .= '<h2><a href="' . $config['root'] . $post['board'] . '">/' . $post['board'] . '/</a></h2>';
             $body .= $thread->build(true);
         } else {
             $page = 'index';
             if (floor($threads[$post['board']] / $config['threads_per_page']) > 0) {
                 $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1;
             }
             $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html');
         }
         $count += 1;
     }
     $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>';
     $body .= '<script type="text/javascript" src="/' . $this->settings['uri'] . '/ukko.js"></script>';
     $config['default_stylesheet'] = array('Yotsuba B', $config['stylesheets']['Yotsuba B']);
     return Element('index.html', array('config' => $config, 'board' => $board, 'no_post_form' => true, 'body' => $body, 'mod' => $mod, 'boardlist' => createBoardlist($mod)));
 }
Exemple #18
0
        } else {
            // no one ever logged in, try board creation time
            $query = query("SELECT UNIX_TIMESTAMP(time) AS time FROM board_create WHERE uri = '{$board}'");
            $crt = $query->fetchAll(PDO::FETCH_COLUMN);
            if ($crt) {
                $last_activity_date->setTimestamp($crt[0]);
            }
            $last_mod_date = false;
        }
    }
    if ($last_activity_date < $ago or $last_mod_date and $last_mod_date < $mod_ago) {
        return array($last_activity_date, $last_mod_date, $mods);
    } else {
        return false;
    }
}
$q = query("SELECT uri FROM boards");
$boards = $q->fetchAll(PDO::FETCH_COLUMN);
$delete = array();
foreach ($boards as $board) {
    $last_activity = last_activity($board);
    if ($last_activity) {
        list($last_activity_date, $last_mod_date, $mods) = $last_activity;
        $last_mod_f = $last_mod_date ? $last_mod_date->format('Y-m-d H:i:s') : '<em>never</em>';
        $last_activity_f = $last_activity_date ? $last_activity_date->format('Y-m-d H:i:s') : '<em>never</em>';
        $delete[] = array('board' => $board, 'last_activity_date' => $last_activity_f, 'last_mod' => $last_mod_date, 'last_mod_f' => $last_mod_f);
    }
}
$body = Element("8chan/claim.html", array("config" => $config, "delete" => $delete));
file_write("claim.html", Element("page.html", array("config" => $config, "body" => $body, "title" => _("Claim"), "subtitle" => _("Take deserted boards back from their owners"))));
Exemple #19
0
                $query->bindValue(':time', time(), PDO::PARAM_INT);
                $query->bindValue(':ip', $_SERVER['REMOTE_ADDR'], PDO::PARAM_STR);
                $query->bindValue(':board', $board['uri'], PDO::PARAM_INT);
                $query->bindValue(':post', $id, PDO::PARAM_INT);
                $query->bindValue(':reason', $reason, PDO::PARAM_STR);
                $query->bindValue(':local', $report_local, PDO::PARAM_BOOL);
                $query->bindValue(':global', $report_global, PDO::PARAM_BOOL);
                $query->execute() or error(db_error($query));
            }
        }
    }
    $is_mod = isset($_POST['mod']) && $_POST['mod'];
    $root = $is_mod ? $config['root'] . $config['file_mod'] . '?/' : $config['root'];
    if (!isset($_POST['json_response'])) {
        $index = $root . $board['dir'] . $config['file_index'];
        echo Element('page.html', array('config' => $config, 'body' => '<div style="text-align:center"><a href="javascript:window.close()">[ ' . _('Close window') . " ]</a> <a href='{$index}'>[ " . _('Return') . ' ]</a></div>', 'title' => _('Report submitted!')));
    } else {
        header('Content-Type: text/json');
        echo json_encode(array('success' => true));
    }
} elseif (isset($_POST['post'])) {
    if (!isset($_POST['body'], $_POST['board'], $_POST['message']) || $_POST['message'] != '') {
        error($config['error']['bot']);
    }
    $post = array('board' => $_POST['board'], 'files' => array(), 'time' => time());
    // Check if board exists
    if (!openBoard($post['board'])) {
        error($config['error']['noboard']);
    }
    if (!isset($_POST['name'])) {
        $_POST['name'] = $config['anonymous'];
Exemple #20
0
<?php

include 'inc/functions.php';
$global = isset($_GET['global']);
$post = isset($_GET['post']) ? $_GET['post'] : false;
$board = isset($_GET['board']) ? $_GET['board'] : false;
if (!$post || !preg_match('/^delete_\\d+$/', $post) || !$board || !openBoard($board)) {
    header('HTTP/1.1 400 Bad Request');
    error(_('Bad request.'));
}
if ($config['report_captcha']) {
    $captcha = generate_captcha($config['captcha']['extra']);
} else {
    $captcha = null;
}
$body = Element('report.html', ['global' => $global, 'post' => $post, 'board' => $board, 'captcha' => $captcha, 'config' => $config]);
echo Element('page.html', ['config' => $config, 'body' => $body]);
Exemple #21
0
                            $body .= '<tr>' . '<td class="minimal">' . $staff . '</td><td>' . $note['body'] . '</td><td class="minimal">' . strftime($config['post_date'], $note['time']) . '</td>' . (hasPermission($config['mod']['remove_notes']) ? '<td class="minimal"><a class="unimportant" href="?/IP/' . $ip . '/deletenote/' . $note['id'] . '">[delete]</a></td>' : '') . '</tr>';
                        }
                        $body .= '</table>';
                    }
                    if (hasPermission($config['mod']['create_notes'])) {
                        $body .= '<form action="" method="post" style="text-align:center;margin:0">' . '<table>' . '<tr>' . '<th>Staff</th>' . '<td>' . $mod['username'] . '</td>' . '</tr>' . '<tr>' . '<th><label for="note">Note</label></th>' . '<td><textarea id="note" name="note" rows="5" cols="30"></textarea></td>' . '</tr>' . '<tr>' . '<td></td>' . '<td><input type="submit" value="New note" /></td>' . '</tr>' . '</table>' . '</form>';
                    }
                    $body .= '</fieldset>';
                }
            }
            if (hasPermission($config['mod']['view_ban'])) {
                $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip");
                $query->bindValue(':ip', $ip);
                $query->execute() or error(db_error($query));
                if ($query->rowCount() > 0) {
                    $body .= '<fieldset><legend>Ban' . ($query->rowCount() == 1 ? '' : 's') . ' on record</legend>';
                    while ($ban = $query->fetch()) {
                        $body .= '<form action="" method="post" style="text-align:center">' . '<table style="width:400px;margin-bottom:10px;border-bottom:1px solid #ddd;padding:5px"><tr><th>Status</th><td>' . ($config['mod']['view_banexpired'] && $ban['expires'] != 0 && $ban['expires'] < time() ? 'Expired' : 'Active') . '</td></tr>' . '<tr><th>IP</th><td>' . $ban['ip'] . '</td></tr>' . '<tr><th>Reason</th><td>' . $ban['reason'] . '</td></tr>' . '<tr><th>Board</th><td>' . (isset($ban['board']) ? sprintf($config['board_abbreviation'], $ban['board']) : '<em>' . _('all boards') . '</em>') . '</td></tr>' . '<tr><th>Set</th><td>' . strftime($config['post_date'], $ban['set']) . '</td></tr>' . '<tr><th>Expires</th><td>' . ($ban['expires'] == 0 ? '<em>Never</em>' : strftime($config['post_date'], $ban['expires'])) . '</td></tr>' . '<tr><th>Staff</th><td>' . (isset($ban['username']) ? !hasPermission($config['mod']['view_banstaff']) ? $config['mod']['view_banquestionmark'] ? '?' : ($ban['type'] == JANITOR ? 'Janitor' : ($ban['type'] == MOD ? 'Mod' : ($ban['type'] == ADMIN ? 'Admin' : '?'))) : utf8tohtml($ban['username']) : '<em>deleted?</em>') . '</td></tr></table>' . '<input type="hidden" name="ban_id" value="' . $ban['id'] . '" />' . '<input type="submit" name="unban" value="Remove ban" ' . (!hasPermission($config['mod']['unban']) ? 'disabled' : '') . '/></form>';
                    }
                    $body .= '</fieldset>';
                }
            }
            if (hasPermission($config['mod']['ip_banform'])) {
                $body .= form_newBan($ip, null, '?/IP/' . $ip);
            }
            echo Element('page.html', array('config' => $config, 'title' => 'IP: ' . $ip, 'subtitle' => $host, 'body' => $body, 'mod' => true));
        }
    } else {
        error($config['error']['404']);
    }
}
Exemple #22
0
 public static function homepage($settings)
 {
     global $config;
     return Element('page.html', array('config' => $config, 'mod' => false, 'hide_dashboard_link' => true, 'title' => _("Ban list"), 'subtitle' => "", 'nojavascript' => true, 'body' => Element('mod/ban_list.html', array('mod' => false, 'boards' => "[]", 'token' => false, 'token_json' => false, 'uri_json' => $config['dir']['home'] . $settings['file_json']))));
 }
Exemple #23
0
 public function homepage($settings)
 {
     global $config, $board;
     $recent_images = array();
     $recent_posts = array();
     $stats = array();
     $boards = listBoards();
     $query = '';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int) $settings['limit_images'], $query);
     $query = query($query) or error(db_error());
     while ($post = $query->fetch()) {
         openBoard($post['board']);
         // board settings won't be available in the template file, so generate links now
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $post['id']) . '#' . $post['id'];
         $post['src'] = $config['uri_thumb'] . $post['thumb'];
         $recent_images[] = $post;
     }
     $query = '';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` UNION ALL ", $_board['uri'], $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int) $settings['limit_posts'], $query);
     $query = query($query) or error(db_error());
     while ($post = $query->fetch()) {
         openBoard($post['board']);
         $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $post['id']) . '#' . $post['id'];
         $post['snippet'] = pm_snippet($post['body'], 30);
         $post['board_name'] = $board['name'];
         $recent_posts[] = $post;
     }
     // Total posts
     $query = 'SELECT SUM(`top`) AS `count` FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT MAX(`id`) AS `top` FROM `posts_%s` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $res = $query->fetch();
     $stats['total_posts'] = number_format($res['count']);
     // Unique IPs
     $query = 'SELECT COUNT(DISTINCT(`ip`)) AS `count` FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT `ip` FROM `posts_%s` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $res = $query->fetch();
     $stats['unique_posters'] = number_format($res['count']);
     // Active content
     $query = 'SELECT SUM(`filesize`) AS `count` FROM (';
     foreach ($boards as &$_board) {
         if (in_array($_board['uri'], $this->excluded)) {
             continue;
         }
         $query .= sprintf("SELECT `filesize` FROM `posts_%s` UNION ALL ", $_board['uri']);
     }
     $query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
     $query = query($query) or error(db_error());
     $res = $query->fetch();
     $stats['active_content'] = $res['count'];
     return Element('themes/recent/recent.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => $recent_images, 'recent_posts' => $recent_posts, 'stats' => $stats));
 }
Exemple #24
0
function buildThread($id, $return = false, $mod = false)
{
    global $board, $config, $build_pages;
    $id = round($id);
    if (event('build-thread', $id)) {
        return;
    }
    if ($config['cache']['enabled'] && !$mod) {
        // Clear cache
        cache::delete("thread_index_{$board['uri']}_{$id}");
        cache::delete("thread_{$board['uri']}_{$id}");
    }
    $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri']));
    $query->bindValue(':id', $id, PDO::PARAM_INT);
    $query->execute() or error(db_error($query));
    while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
        if (!isset($thread)) {
            $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod);
        } else {
            $thread->add(new Post($post, $mod ? '?/' : $config['root'], $mod));
        }
    }
    // Check if any posts were found
    if (!isset($thread)) {
        error($config['error']['nonexistant']);
    }
    $body = Element('thread.html', array('board' => $board, 'thread' => $thread, 'body' => $thread->build(), 'config' => $config, 'id' => $id, 'mod' => $mod, 'antibot' => $mod || $return ? false : create_antibot($board['uri'], $id), 'boardlist' => createBoardlist($mod), 'return' => $mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index']));
    if ($config['try_smarter'] && !$mod) {
        $build_pages[] = thread_find_page($id);
    }
    if ($return) {
        return $body;
    }
    file_write($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $id), $body);
    // json api
    if ($config['api']['enabled']) {
        $api = new Api();
        $json = json_encode($api->translateThread($thread));
        $jsonFilename = $board['dir'] . $config['dir']['res'] . $id . '.json';
        file_write($jsonFilename, $json);
    }
}
Exemple #25
0
<p>Thank you for your interest in contributing a translation to infinity. This page will teach you how.</p>

<p><em>Historical note: infinity is based on a project called vichan (pronunced 6chan) which is in turn based on an older, abandoned project called Tinyboard. Vichan uses a service called Transifex to translate their files. In earlier versions of infinity, I decided to just keep using the vichan files because the only substantial source of new strings was the homepage and the Board configuration page, neither of which were displayed to board users so the existing set of translations worked. However, as time went on and more scripts and features were contributed, strings became out of sync. I originally intended to create 8chan a Transifex account, <s>but Transifex charges for something as simple as bulk imports</s>, so we will use this slightly more complicated process instead. Further, despite how much their charismatic CEO tried to sugarcoat it, the Transifex company <a href="https://github.com/transifex/transifex/issues/206#issuecomment-15243207">abandoned their open source repository</a> and became proprietary software, and then <s>immediately put limits on imports/exports</s>. <a href="https://www.gnu.org/philosophy/who-does-that-server-really-serve.html">Please see this page from the Free Software Foundation for more about the philosophy behind this and the dangers of trusting SaaS with your data. Who does that server really serve?</a></em></p>

<p>Some of my criticism of Transifex was not accurate, I apologize. You are free to either use Transifex or follow the steps below. <a href="https://www.transifex.com/projects/p/infinity/">Here's our Transifex team page</a></p>

<p>infinity uses gettext files for translation. This is what allows us to have boards in many languages on the same site, such as <a href="/argentina/">/argentina/ in Spanish</a>, <a href="/deutsch/">/deutsch/ in German</a> and <a href="/japan2/">/japan2/ in Japanese</a>. gettext files have the .po file extension. You can edit PO files by hand, but I highly recommend using POEdit. It is very easy to make syntax errors without POEdit or similar software.</p>
<ol>
\t<li>Install <a href="http://poedit.net/">POEdit</a>. POEdit is free software available for Mac, Linux and Windows.</li>
\t<li>Find your translation file. Go to <a href="https://github.com/ctrlcctrlv/infinity/">our Github project</a>, and in the files list click "inc", then "locale". You will see a list of languages. It's usually self explanatory which code is for which language, but if you're not sure you can check <a href="https://www.gnu.org/software/gettext/manual/html_node/Usual-Language-Codes.html#Usual-Language-Codes">the GNU project's list of usual language codes</a> and search for your language.</li> 
</ol>
<p><strong>If your language is listed and you want to update the translation:</strong></p>
<ol>
\t<li>Download the .po files. <tt>tinyboard.po</tt> contains the strings generated by PHP, like "Comment", "Name", et cetera. <tt>javascript.po</tt> contains the strings generated by JavaScript, like all the fields under [Options]. You can translate one or both. For example, <a href="https://github.com/ctrlcctrlv/infinity/blob/master/inc/locale/fr_FR/LC_MESSAGES/tinyboard.po">here is the French translation of tinyboard.po</a>. To download it, click "Raw" and then save the file to your computer.</li>
\t<li>Click "Edit a translation" in POEdit. Navigate to the file you downloaded, fill in the translation boxes and save your file.</li>
</ol>
<p><strong>If your language is not listed and you want to add a translation for it:</strong></p>
<ol>
\t<li>Download the en <em>English</em> .po file. (Tip: If, for example, you want to create a new Spanish dialect translation when Spanish (Spain) already exists, download es_ES and use that as the template.)</li>
\t<li>Click "Create a new translation" in POEdit and select the po file you downloaded as the template file.</li>
\t<li>Select your language from the dropdown when prompted.</li>
</ol>

<p><em>Tip: If you would like to attribute your translation to you, you can change your Name and Email in Preferences.</em></p>
<p><em>Another tip: You might find that a string you want to translate is not in the files. Don't panic, I accidentally forget to put strings in {% trans %} tags and _() gettext function all the time so gettext doesn't catch them. Just email me and tell me where I forgot and I'll add it and update tinyboard.po/javascript.po. Some strings I don't want to add for legal reasons. Those are the ones at the bottom including the copyright notice.</em></p>

<p>Once you are done translating, save your .po file in POEdit and send it to admin@8chan.co, or, if you know how, open a pull request on Github with your translated file. Make sure to put the language you translated to in the subject of your email. Thanks in advance for your contribution!</p>
</div>
EOT;
echo Element("page.html", array("config" => $config, "body" => $body, "title" => "Translation tutorial"));
Exemple #26
0
 public static function install($settings)
 {
     global $config;
     return Element('themes/zine/zine.html', array('settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()));
 }
Exemple #27
0
function buildThread50($id, $return = false, $mod = false, $thread = null, $antibot = false)
{
    global $board, $config, $build_pages;
    $id = round($id);
    if ($antibot) {
        $antibot->reset();
    }
    if (!$thread) {
        $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id` DESC LIMIT :limit", $board['uri']));
        $query->bindValue(':id', $id, PDO::PARAM_INT);
        $query->bindValue(':limit', $config['noko50_count'] + 1, PDO::PARAM_INT);
        $query->execute() or error(db_error($query));
        $num_images = 0;
        while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
            if (!isset($thread)) {
                $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod);
            } else {
                if ($post['files']) {
                    $num_images += $post['num_files'];
                }
                $thread->add(new Post($post, $mod ? '?/' : $config['root'], $mod));
            }
        }
        // Check if any posts were found
        if (!isset($thread)) {
            error($config['error']['nonexistant']);
        }
        if ($query->rowCount() == $config['noko50_count'] + 1) {
            $count = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL\n\t\t\t\t\t\t  SELECT SUM(`num_files`) FROM ``posts_%s`` WHERE `files` IS NOT NULL AND `thread` = :thread", $board['uri'], $board['uri']));
            $count->bindValue(':thread', $id, PDO::PARAM_INT);
            $count->execute() or error(db_error($count));
            $c = $count->fetch();
            $thread->omitted = $c['num'] - $config['noko50_count'];
            $c = $count->fetch();
            $thread->omitted_images = $c['num'] - $num_images;
        }
        $thread->posts = array_reverse($thread->posts);
    } else {
        $allPosts = $thread->posts;
        $thread->posts = array_slice($allPosts, -$config['noko50_count']);
        $thread->omitted += count($allPosts) - count($thread->posts);
        foreach ($allPosts as $index => $post) {
            if ($index == count($allPosts) - count($thread->posts)) {
                break;
            }
            if ($post->files) {
                $thread->omitted_images += $post->num_files;
            }
        }
    }
    $hasnoko50 = $thread->postCount() >= $config['noko50_min'];
    $body = Element('thread.html', array('board' => $board, 'thread' => $thread, 'body' => $thread->build(false, true), 'config' => $config, 'id' => $id, 'mod' => $mod, 'hasnoko50' => $hasnoko50, 'isnoko50' => true, 'antibot' => $mod ? false : ($antibot ? $antibot : create_antibot($board['uri'], $id)), 'boardlist' => createBoardlist($mod), 'return' => $mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index']));
    if ($return) {
        return $body;
    } else {
        file_write($board['dir'] . $config['dir']['res'] . sprintf($config['file_page50'], $id), $body);
    }
}
Exemple #28
0
 public function build($index = false)
 {
     global $board, $config, $debug;
     event('show-thread', $this);
     $built = Element('post_thread.html', array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index));
     return $built;
 }
Exemple #29
0
    $sql_errors = '';
    foreach ($queries as &$query) {
        if (!query($query)) {
            $sql_errors .= '<li>' . db_error() . '</li>';
        }
    }
    $boards = listBoards();
    foreach ($boards as &$_board) {
        setupBoard($_board);
        buildIndex();
    }
    $page['title'] = 'Installation complete';
    $page['body'] = '<p style="text-align:center">Thank you for using Tinyboard. Please remember to report any bugs you discover. <a href="http://tinyboard.org/docs/?p=Config">How do I edit the config files?</a></p>';
    if (!empty($sql_errors)) {
        $page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to install the database. This may be the result of using a database which is already occupied with a Tinyboard installation; if so, you can probably ignore this.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul><p><a href="?step=5">Ignore errors and complete installation.</a></p></div>';
    } else {
        file_write($config['has_installed'], VERSION);
        if (!file_unlink(__FILE__)) {
            $page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>';
        }
    }
    echo Element('page.html', $page);
} elseif ($step == 5) {
    $page['title'] = 'Installation complete';
    $page['body'] = '<p style="text-align:center">Thank you for using Tinyboard. Please remember to report any bugs you discover.</p>';
    file_write($config['has_installed'], VERSION);
    if (!file_unlink(__FILE__)) {
        $page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>';
    }
    echo Element('page.html', $page);
}
Exemple #30
0
 public function build($index = false, $isnoko50 = false)
 {
     global $board, $config, $debug;
     $hasnoko50 = $this->postCount() >= $config['noko50_min'];
     //event('show-thread', $this);
     $built = Element('post_thread.html', array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50));
     return $built;
 }