[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Управление текстовыми страницами
Sylex
PHP
<?php

/**
 * Управление текстовыми страницами (простая CMS на файлах)
 * 
 * @package    ACFrame
 * @version    1.0 (2009/02/07)
 * @copyright    Sylex ©, 2009
 * @author    Sylex <zcub [at] mail.ru>
 */

class CTextPage
{
    
/**
     * Директория для файлов
     *
     * @var string
     */
    
protected $path null;
    
    
/**
     * Имя файла БД
     *
     * @var string
     */
    
protected $dbFile 'db.txt';
    
    
/**
     * Проверять существование файла?
     *
     * @var bool
     */
    
public $dbFileExists false;
    
    
/**
     * Расширение файла
     *
     * @var string
     */
    
protected $extension '.txt';
    
    
/**
     * Содержит данные страниц
     *
     * @var array
     */
    
protected $data null;
    
    
/**
     * Массив ошибок
     *
     * @var array
     */
    
protected $errors = array();
    
    
/**
     * Массив имен ошибок
     *
     * @var array
     */
    
protected $errors_ru = array(
        
'PAGE_NOT_FOUND' =>        'Страница не найдена',
        
'ERROR_ADD_PAGE' =>        'Нельзя добавлять страницы в дочерние разделы',
        
'DIR_NOT_WRITABLE' =>    'Ошибка при записи в директорию (проверьте путь и права)',
        
'UNKNOWN_PARENT' =>        'Не найден родительский раздел',
        
'UNKNOWN_ID_PAGE' =>    'Неверный идентификатор страницы',
        
'FILE_DB_NOT_EXITST' =>    'Файл БД не существует',
        
'ENTER_NAME_PAGE' =>    'Введите название страницы'
    
);
    
    
/**
     * Инцициализация
     *
     * @param string $dir - директория для файлов
     * @param string $dbFile - имя файла БД
     */
    
public function __construct($dir$dbFile '')
    {
        
$this->path = (string) $dir;
        if (!empty(
$dbFile)) {
            
$this->dbFile = (string) $dbFile;
        }
    }
    
    
/**
     * Устанавливает директорию для файлов и читает данные с БД
     *
     * @param array $dir - путь
     */
    
public function setPath($dir)
    {
        
$this->path = (string) $dir;
        
// получаем данные
        
$this->data null;
        
$this->getData();
    }
    
    
/**
     * Возвращает строки данных применяя фильтр
     *
     * @param array $aParams - параметры
     * @return array
     */
    
public function getAll($aParams = array())
    {
        
$this->getData();
        
// результат
        
$res = array();
        if (
$this->data)
        foreach(
$this->data as $line) {
            
// применяем фильтр
            
if (isset($aParams['parent'])) {
                if (
$aParams['parent'] != $line['parent']) continue;
            }
            if (isset(
$aParams['public'])) {
                if (
$aParams['public'] != $line['public']) continue;
            }
            
// пополняем массив
            
$res[] = $line;
        }
        return 
$res;
    }
    
    
/**
     * Возвращает строку данных применяя фильтр
     *
     * @param int $iID - ID страницы
     * @param array $aParams - параметры
     * @return array
     */
    
public function getRow($iID 0$aParams = array())
    {
        
$this->getData();
        
        
$iID = (int)$iID;
        
// результат
        
$res = array();
        if (
$this->data)
        foreach(
$this->data as $line) {
            
// применяем фильтр
            
if ($iID>0) {
                if (
$iID != $line['id']) continue;
            }
            if (isset(
$aParams['parent'])) {
                if (
$aParams['parent'] != $line['parent']) continue;
            }
            if (isset(
$aParams['public'])) {
                if (
$aParams['public'] != $line['public']) continue;
            }
            
// содержимое страницы
            
$line['content'] = '';
            
// имя файла
            
$file_name $this->path $iID $this->extension;
            
// если существует - возвращаем содержимое
            
if (is_file($file_name)) {
                
$line['content'] = file_get_contents($file_name);
            }
            
// возвращаем строку
            
return $line;
        }
        return 
false;
    }
    
    
/**
     * Возвращает данные страницы для сайта
     *
         * @param array $iID - ID страницы
     * @return array
     */
    
public function get($iID)
    {
        return 
$this->getRow($iID, array('public' => true));
    }
    
    
/**
     * Удаляет страницу
     *
         * @param int $iID - идентификатор страницы
     * @return bool
     */
    
public function remove($iID)
    {
        
$this->getData();
        
        
$iID = (int)$iID;
        
        if (
$this->data)
        foreach (
$this->data as $k => $line) {
            
// если найдено
            
if ($line['id'] == $iID) {
                if (
is_writable($this->path)) {
                    
// удаляем из массива
                    
unset($this->data[$k]);
                    
// имя файла
                    
$fn $this->path $iID $this->extension;
                    
// если существует - удаляем
                    
if (is_file($fn)) unlink($fn);
                    
// обновляем БД
                    
$this->writeDB();
                    return 
true;
                } else {
                    
$this->errors[] = 'DIR_NOT_WRITABLE';
                    return 
false;
                }
            }
        }
        
$this->errors[] = 'PAGE_NOT_FOUND';
        return 
false;
    }
    
    
/**
     * Добавляет страницу
     *
         * @param int $iParent - ID родителя
         * @param array $aFields - поля
     * @return bool
     */
    
public function add($iParent$aFields)
    {
        
$this->getData();
        
        
$iParent = (int)$iParent;
        
        
// проверяем поля
        
if (!$this->checkFields($aFields)) return false;
        
        if (
$this->data)
        foreach (
$this->data as $k => $line) {
            
// если найдено
            
if ($line['id'] == $iParent) {
                
// проверка, что это родительский раздел
                
if ($line['parent'] > 0) {
                    
$this->errors[] = 'ERROR_ADD_PAGE';
                    return 
false;
                }
                
// новый идентификатор страницы
                
$id    end($this->data);
                
$id intval($id['id']) + 1;
                
// имя файла
                
$fn $this->path $id $this->extension;
                if (
is_writable($this->path)) {
                    
// сохраняем текст страницы
                    
file_put_contents($fn$aFields['content']);
                } else {
                    
$this->errors[] = 'DIR_NOT_WRITABLE';
                    return 
false;
                }
                
// добавляем запись
                
$this->data[] = array(
                    
'id' => $id,
                    
'parent' => $iParent,
                    
'name' => $aFields['name'],
                    
'public' => 'Y'
                
);
                
// обновляем БД
                
$this->writeDB();
                return 
true;
            }
        }
        
$this->errors[] = 'UNKNOWN_PARENT';
        return 
false;
    }
    
    
/**
     * Изменяет данные страницы
     *
         * @param array $iID - ID страницы
         * @param array $aFields - поля
     * @return bool
     */
    
public function update($iID$aFields)
    {
        
$this->getData();
        
        
$iID = (int)$iID;
        
        
$check_name false;
        if (
$this->data)
        foreach (
$this->data as $k => $line) {
            
// если найдено
            
if ($line['id'] == $iID) {
                
$check_name = ($line['parent'] == 0);
                break;
            }
        }
        
        
// проверяем поля
        
if (!$this->checkFields($aFields$check_name)) return false;
        
        if (
$this->data)
        foreach (
$this->data as $k => $line) {
            
// если найдено
            
if ($line['id'] == $iID) {
                
// имя файла
                
$fn $this->path $iID $this->extension;
                if (
is_writable($this->path)) {
                    
// обвновляем текст страницы
                    
file_put_contents($fn$aFields['content']);
                } else {
                    
$this->errors[] = 'DIR_NOT_WRITABLE';
                    return 
false;
                }
                
// название страницы
                
$name_page = ($line['parent'] == 0) ? $line['name'] : $aFields['name'];
                
// обновляем запись
                
$this->data[$k] = array(
                    
'id' => $iID,
                    
'parent' => $line['parent'],
                    
'name' => $name_page,
                    
'public' => $aFields['public']
                );
                
// обновляем БД
                
$this->writeDB();
                return 
true;
            }
        }
        
$this->errors[] = 'UNKNOWN_ID_PAGE';
        return 
false;        
    }

    
/**
     * Возвращает массив ошибок, если они есть
     *
     * @return string
     */
    
public function getErrors()
    {
        
// если нет ошибок
        
if (sizeof($this->errors) == 0) return '';
        
$res = array();
        
// собираем все имена ошибок в массив
        
foreach ($this->errors as $v) {
            
$res[] = $this->errors_ru[$v];
        }
        return 
implode('<br>'$res);
    }
    
    
/**
     * Считывает данные из БД и возвращает массив данных
     *
     * @return array
     */
    
protected function getData()
    {
        
// если результат уже получали - возвращаем его
        
if ($this->data) return $this->data;
        
// если нужно проверить существование файла
        
if ($this->dbFileExists) {
            if (!
is_file($this->path $this->dbFile)) {
                
$this->errors[] = 'FILE_DB_NOT_EXITST';
                return 
false;
            }
        }
        
// пробуем получить данные в массив
        
$data file($this->path $this->dbFile);
        
// если пустой - выход
        
if (!$data) return false;
        
$res = array();
        foreach(
$data as $k => $line) {
            
// делим строку
            
$s explode("\t"$line);
            
// если элементов не 4 - пропуск
            
if (sizeof($s)<>4) continue;
            
// заполняем данные
            
$res[$k] = array();
            
$res[$k]['id'] = (int) $s[0];
            
$res[$k]['parent'] = (int) trim($s[1]);
            
$res[$k]['name'] = trim($s[2]);
            
$res[$k]['public'] = (trim($s[3]) == 'N') ? 'N' 'Y';
        }
        
// сохраняем данные
        
$this->data $res;
        return 
$res;
    }
    
    
/**
     * Проверяет данные на корректность
     *
     * @return bool
     */
    
protected function checkFields(&$aFields$update false)
    {
        
// стираем символ табуляции, т.к. он является разделителем
        
$aFields['name'] = str_replace("\t"""$aFields['name']);
        
// поле "Имя" должно быть заполнено
        
if (!$update && empty($aFields['name'])) {
            
$this->errors[] = 'ENTER_NAME_PAGE';
            return 
false;
        }
        
// обрезаем строки
        
if (strlen($aFields['name'])>100) {
            
$aFields['name'] = substr($aFields['name'], 0100);
        }
        if (
strlen($aFields['content'])>50000) {
            
$aFields['content'] = substr($aFields['content'], 050000);
        }
        
// публикация
        
$aFields['public'] = $aFields['public'] > 'Y' 'N';
        return 
true;
    }
    
    
/**
     * Записывает данные в БД
     *
     */
    
protected function writeDB()
    {
        if (!
$this->data) return false;
        
$res = array();
        foreach (
$this->data as $data) {
            
$res[] = "{$data['id']}\t{$data['parent']}\t{$data['name']}\t{$data['public']}";
        }
        
file_put_contents($this->path $this->dbFileimplode("\r\n"$res));
    }
    
}




Спустя 3 минуты, 46 секунд (11.06.2009 - 07:59) Sylex написал(а):
Пример файла:
Код
1 0 Главная Y
2 0 О компании Y
3 0 Услуги Y
4 0 Интернет-сервис Y
5 0 Контактная информация Y
6 2 Добавленная страница Y
9 1 Текст пополам Y


Т.е. id - parent - name - public, разделенные табуляцией

Пример использования:

Конфиг:
PHP
<?php
// разделитель пути
define(DSR, DIRECTORY_SEPARATOR);
// путь скрипта
define('ROOT', dirname(__FILE__) . DSR);
// путь к файлам БД
define('DB_DIR', ROOT . 'files_db' . DSR);
// проверять существование файла
$dbFileExists = true;

// ******************** АДМИН СИСТЕМА ******************** //
// ссылка
$href_admin = '/admin.php';
// путь к TinyMCE
$tinymce_js = '/tinymce/jscripts/tiny_mce/tiny_mce.js';
// файл конфигурации
$tinymce_init = '/public/tinymce_content.js';
$admin_js = '/public/admin.js';
$admin_css = '/public/admin.css';
// путь для открытия страницы на сайте
$admin_ext_url = '/content.php?page=';
$pass_admin = '123456';


PHP
<?php

require_once('config.php');
// подключаем класс и создаем объект
require_once(ROOT.'class.textpage.php');
$TP = new CTextPage(DB_DIR);
// проверять существование файла
$TP->dbFileExists = $dbFileExists;

// получаем страницу
$content = $TP->get(1); // главная
// если не нашли
if (!$content) {
    // ошибка 404
    require_once(ROOT.'404.php');
    die();
}

// получаем главные разделы
$menu_left = $TP->getAll(array('parent' => 0, 'public' => 'Y'));


Построение меню:
PHP
<?php
if 
($menu_left)
foreach ($menu_left as $menu) {
    $menu['name'] = htmlspecialchars($menu['name']);
    echo <<<EOF
    <p><a href="/content.php?page={$menu['id']}">{$menu['name']}</a></p>
EOF;
}

Спустя 4 минуты, 18 секунд (11.06.2009 - 08:03) Sylex написал(а):
Админ-система

PHP
<?php

// редирект
function redirect($path "") {
    if (
$path == ''$path $_SERVER['REQUEST_URI'];
    
header("Location: {$path}"true302);
    die();
}

require_once(
'config.php');
require_once(
'auth.php');
if (!
$auth) die();

// подключаем класс и создаем объект
require_once(ROOT.'class.textpage.php');
$TP = new CTextPage(DB_DIR);
// проверять существование файла
$TP->dbFileExists $dbFileExists;

// редактируемая страница
$page_edit = isset($_GET['page']) ? (int)$_GET['page'] : 1;
// действие
$action = isset($_GET['action']) ? $_GET['action'] : '';
// текущий раздел
$cur_page $page_edit;
// ссылка
$href $href_admin;
// массив ошибок
$errors = array();

// удаление страницы
if ($action == 'del') {
    
$TP->remove($_GET['del_page']);
    
redirect($href '?page=' $page_edit);
}

// добавление страницы
if (isset($_POST['add_new_page'])) {
    if (
$TP->add($page_edit$_POST)) redirect();
}

// обновление страницы
if (isset($_POST['content'])) {
    if (
$TP->update($page_edit$_POST)) {
        
$_SESSION['saved'] = true;
        
redirect();
    }
}

// получаем содержимое
$content $TP->getRow($page_edit);
if (
$content) {
    
// если родительский раздел
    
if ($content['parent'] == 0) {
        
// получаем все его страницы
        
if ($page_edit == 0$page_edit 1;
        
$pages $TP->getAll(array('parent' => $page_edit));
    } else {
        
// получаем родителя
        
$cur_page = (int)$content['parent'];
    }
}

// получаем левое меню
$menu_left $TP->getAll(array('parent' => 0));

// шаблон
$page 'tmpl.admin.php';
require_once(
ROOT.'maket.php');


Шаблон:
PHP
<h1>Админ-система</h1>
<
p>&nbsp;</p>

&
#60;script type="text/javascript" src="<?=$tinymce_js?>"></script> 
<script type="text/javascript" src="<?=$tinymce_init?>"></script> 
<script type="text/javascript" src="<?=$admin_js?>"></script>
<link href="<?=$admin_css?>" type="text/css" rel="stylesheet">

<?php
$er 
$TP->GetErrors();
if (
$er) {
    echo 
'<p class="errors"><b>Ошибки:</b><br>'$er'</p>';
}
?>

<table width="100%">
<tr valign="top">
<td style="width: 240px; padding-right: 20px">
    <?php
    
    
if ( $menu_left ) {
    
?>
    <h2>Разделы сайта:</h2>
    <?php
    
// строим меню
    
$otstup false;
    foreach (
$menu_left as $v)
    {
        
$sel '';
        
// выделяем выбранную страницу
        
if ( $v['id'] == $cur_page $sel ' class="sel_p"';
        
        
$v['name'] = htmlspecialchars($v['name']);
        
        
// если кол-во страниц больше 0 - выводим
        
if ($v['count_pages']>0$v['name'] .= " ({$v['count_pages']})";
        
// если раздел скрытый - выделяем курсивом
        
if ( $v['public'] == 'N' $v['name'] = '<span style="color: #303;"><em>' $v['name'] . '</em></span>';
        
// вывод
        
echo '<p' $sel '><a href="' $href '?page=' $v['id'] . '">' $v['name'] . '</a></p>';
    }
    }
    
?>
    <p>&nbsp;</p>
    <p><a href="/logout.php">Выход</a></p>
</td>

<td>
    <form action="" method="post">

    <?php
    
    $content
['name'] = htmlspecialchars($content['name']);
    
    if (
$content['parent'] == 0) {
        echo 
"<h1>{$content['name']}</h1><div style='height: 20px'></div>";
    } else {
        echo 
'<p><b>Название</b> <input style="width: 600px" type="text" name="name" value="' $content['name'] . '"></p>';
    }
    
    
?>

    <?php if ( $_SESSION['saved'] ) {
        
$_SESSION['saved'] = false;
        echo 
'<p><b>Данные сохранены.</b></p>';
    } else {
    
?>

    <textarea name="content" cols="70" rows="30" style="width: 750px"><?=$content['content']?></textarea>
    
    <p>Публиковать <input type="checkbox" name="public" style="width: 20px" value="1"<?php if ( $content['public'] == 'Y' ) echo " checked";?>></p>
    
    <p><input type="submit" value="Сохранить">
    </form>
    
    <div style="height: 20px"></div>
    
    <?php if ($content['pid'] == 0) { ?>
    <div style="height: 20px"></div>
    <h2>Добавление страницы</h2>
    <form action="" method="post" class="tab_form">
        <p>Название страницы <input type="text" name="name"></p>
        <input type="hidden" name="add_new_page" value="1">
        <p><input type="submit" value="Добавить"></p>
    </form>
    
    <h2>Страницы:</h2>
    <?php if ($pages) {
        echo 
'<table>';
        foreach (
$pages as $page_d)
        {
            
$page_d['name'] = htmlspecialchars($page_d['name']);
            echo <<<EOF
            <tr>
                <td style="padding: 10px 20px 0 0"><a href="
{$href}?page={$page_d['id']}">{$page_d['name']}</a></td>
                <td><a style="font-size: 10px; color: #00C;" href="
{$admin_ext_url}{$page_d['id']}" target="_blank">- открыть -</a></td>
                <td><a style="font-size: 10px; color: #00C; margin-left: 20px" href="
{$href}?action=del&del_page={$page_d['id']}" onclick="return chance3()">- удалить -</a></td>
            </tr>
EOF;
        }
        echo 
'</table>';
    } else echo 
'<p>Страниц, добавленных к текущей не существует.</p>';
    
?>
    
    <?php 
    } 
?>

<

Спустя 7 минут, 48 секунд (11.06.2009 - 08:11) Sylex написал(а):
Конечно, полную готовую сборку файлов я не писал, это просто наброски, как можно делать новичкам. Основная фишка - класс CTextPage, который можно доработать и использовать для простых задач.

Так что принимаются замечания, улучшения, доработки smile.gif

Спустя 1 месяц, 17 дней, 15 часов, 43 секунды (28.07.2009 - 23:12) arnest написал(а):

Почетму файлы без названий?

Спустя 8 часов, 12 минут, 32 секунды (29.07.2009 - 07:24) Sylex написал(а):
Цитата (arnest @ 29.07.2009 - 02:12)
Почетму файлы без названий?


Цитата (Sylex @ 11.06.2009 - 11:11)
Конечно, полную готовую сборку файлов я не писал, это просто наброски, как можно делать новичкам. Основная фишка - класс CTextPage, который можно доработать и использовать для простых задач.


уж имена файлов ты можешь дать на свое усмотрение smile.gif

Спустя 4 минуты, 51 секунда (29.07.2009 - 07:29) Guest написал(а):
А готовый вариант сбросить на почту можно? Естественно за "Спасибо"

Спустя 17 минут, 58 секунд (29.07.2009 - 07:47) Sylex написал(а):
aska 19386(десять)двадцатьдва


_____________
Я думал я буду сеять добро, но у меня не получилось. Во-первых, мне помешали, во-вторых я сам отрекся от этой идеи.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.