Полезный класс Application

31 views
Skip to first unread message

Hinikato Dubrai

unread,
Oct 7, 2008, 11:00:45 AM10/7/08
to ru-zend-framework
Написал класс может кому поможет и облегчит усилия. Вот его код:
<pre>
<?php
require_once 'Zend/Loader.php';
require_once 'Zend/Log.php';
require_once 'Zend/Layout.php';
require_once 'Zend/Controller/Action/Helper/ViewRenderer.php';
require_once 'Myak/View.php';

class Myak extends ArrayObject
{
private static $_instance;

private static $_class = 'Myak';

protected $_front, $_config, $_db, $_logger;

protected $_moduleDir, $_varDir, $_templateDir, $_uploadDir,
$_cacheDir, $_logDir, $_sessionDir;

protected $_templateUrl, $_uploadUrl;

public static function setInstance(Myak $instance)
{
self::$_instance = $instance;
self::$_class = get_class($instance);
}

public static function getInstance($new = true)
{
if (null === self::$_instance && $new) {
self::$_instance = new self::$_class;
}
return self::$_instance;
}

public static function unsetInstance()
{
self::$_instance = null;
}

public static function get($index)
{
$instance = self::getInstance();
if (false !== ($getter = $instance->_getGetter($index))) {
return $instance->$getter();
}
if (!$instance->offsetExists($index)) {
require_once 'Myak/Exception.php';
throw new Myak_Exception('No entry is registered for key
"' . $index . '".');
}
return $instance->offsetGet($index);
}

public static function set($index, $value)
{
$instance = self::getInstance();
if (false !== ($setter = $instance->_getSetter($index))) {
$instance->$setter($value);
} else {
$instance->offsetSet($index, $value);
}
return $instance;
}

public function __construct($array = array(), $flags = 0, $class =
'ArrayIterator')
{
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', true);

set_exception_handler(array($this, 'exception'));
set_error_handler(array($this, 'error'));

umask(0);

$this->_unregisterGlobals()
->_stripGlobalSlashes();

parent::__construct($array, $flags, $class);
}

public function exception(Exception $e)
{
try {
$config = $this->getConfig();
$logger = $this->getLogger();
} catch (Exception $e) {
}
if (isset($config->myak->log->enable) && $config->myak->log-
>enable && isset($logger)) {
$logger->emerg($e->__toString());
}
if (isset($config->myak->debug) && $config->myak->debug) {
die('<pre>' . $e . '</pre>');
}
die('Error occurred.');
}

public function error($no, $str, $file, $line)
{
if (!error_reporting()) {
return true;
}
$msg = false;
if ($no == E_RECOVERABLE_ERROR) {
$priority = Zend_Log::CRIT;
$msg = 'Catchable fatal error (E_RECOVERABLE_ERROR,
4096).';
} elseif ($no == E_WARNING || $no == E_USER_WARNING) {
$priority = Zend_Log::WARN;
switch ($no) {
case E_WARNING:
$msg = 'Run-time warning (E_WARNING, 2).';
break;
case E_USER_WARNING:
$msg = 'User-generated warning message
(E_USER_WARNING, 512).';
break;
}
} elseif ($no == E_NOTICE || $no == E_STRICT || $no ==
E_USER_NOTICE) {
$priority = Zend_Log::NOTICE;
switch ($no) {
case E_NOTICE:
$msg = 'Run-time notice (E_NOTICE, 8).';
break;
case E_STRICT:
$msg = 'Run-time notice (E_STRICT, 2048).';
break;
case E_USER_NOTICE:
$msg = 'User-generated notice message
(E_USER_NOTICE, 1024).';
break;
}
} elseif ($no == E_USER_ERROR) {
$priority = Zend_Log::ERR;
$msg = 'User-generated error message (E_USER_ERROR,
256).';
}

$config = $this->getConfig();
if ($msg !== false) {
$msg .= "\nFile: $file\nLine: $line\nMessage: $str";

if (isset($config->myak->log->enable) && $config->myak-
>log->enable) {
$this->getLogger()->log($msg, $priority);
}
}
if (isset($config->myak->debug) && $config->myak->debug) {
return false;
}
return true;
}

public function run()
{
$this->_initFront();

$this->_initView();

$front = $this->getFront();

$front->addModuleDirectory($this->getModuleDir());

$config = $this->getConfig();

if ($config->myak->gzip && extension_loaded('zlib') &&
isset($_SERVER['HTTP_ACCEPT_ENCODING']) &&
(strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false ||
strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false)) {
if (ini_get('zlib.output_compression')) {
$front->returnResponse(true);
} else {
ob_start('ob_gzhandler', 9);
}
}
$this->getResponse()
->setHeader('Expires', 'Thu, 21 Jul 1977 07:30:00 GMT')
->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . '
GMT')
->setHeader('Cache-Control', 'no-cache, must-revalidate')
->setHeader('Cache-Control', 'post-check=0,pre-check=0')
->setHeader('Cache-Control', 'max-age=0')
->setHeader('Pragma', 'no-cache')
->setHeader('Content-type', 'text/html; charset=' .
$config->general->charset);
$response = $front->dispatch();
if ($response !== null) {
$response->setBody(gzencode($response->getBody(), 4));
$response->sendResponse();
}
}

public function offsetExists($index)
{
return array_key_exists($index, $this);
}

public function getFront()
{
if ($this->_front === null) {
require_once 'Zend/Controller/Front.php';
$this->_front = Zend_Controller_Front::getInstance();
}
return $this->_front;
}

public function getConfig()
{
if ($this->_config === null) {
require_once 'Zend/Config.php';
$this->_config = new Zend_Config(array(), true);
}
return $this->_config;
}

public function setConfig($config)
{
if (is_array($config)) {
require_once 'Zend/Config.php';
$configObj = new Zend_Config($config, true);
} elseif (is_string($config) && is_file($config)) {
$ext = false !== strpos($config, '.') ?
substr(strrchr($config, '.'), 1) : $config;
switch ($ext) {
case 'xml':
case 'ini':
$class = 'Zend_Config_' . ucfirst($ext);
Zend_Loader::loadClass($class);
$configObj = new $class($config, null);
break;

case 'php':
require_once 'Zend/Config.php';
// In .php configuration file should be declared
$config var.
require $config;
$configObj = new Zend_Config($config);
break;

default:
require_once 'Myak/Exception.php';
throw new Myak_Exception("Invalid configuration
file \"$config\".");
break;
}
} else {
if (!$config instanceof Zend_Config) {
require_once 'Myak/Exception.php';
throw new Myak_Exception('Invalid configuration
argument.');
}
$configObj = $config;
}

$config = array();
foreach ($configObj->toArray() as $section => $items) {
$config[strtolower($section)] = $items;
}

// Set default section names if they has not been set.
$config += array(
'general' => array(),
'myak' => array(),
);

$config = new Zend_Config($config, true);

//
// Parse general section.
//
$generalConfig = $config->get('general');
if (null === $generalConfig->get('timezone')) {
$generalConfig->timezone = 'Europe/Moscow';
}
// All timezones available at
http://unicode.org/cldr/data/diff/supplemental/territory_containment_un_m_49.html
date_default_timezone_set($generalConfig->get('timezone'));

if (null === $generalConfig->get('charset')) {
$generalConfig->charset = 'utf-8';
}

//
// Parse myak section.
//
$myakConfig = $config->get('myak');

if (null === $myakConfig->get('base_url')) {
$myakConfig->base_url = $this->getBaseUrl();
} else {
$this->setBaseUrl($myakConfig->get('base_url'));
}

if (null === $myakConfig->get('autoload')) {
$myakConfig->autoload = true;
}
if ($myakConfig->get('autoload')) {
Zend_Loader::registerAutoload();
}

$log = $myakConfig->get('log');
if (!$log instanceof Zend_Config) {
$myakConfig->log = new Zend_Config(array('enable' =>
false, 'level' => -1), true);
} else {
if (!isset($myakConfig->log->enable)) {
$myakConfig->log->enable = false;
}
if (!isset($myakConfig->log->level)) {
$myakConfig->log->level = -1;
}
}

if (!isset($myakConfig->debug)) {
$myakConfig->debug = false;
}
if (!isset($myakConfig->template)) {
$myakConfig->template = null;
}

//
// Parse database section.
//
if (null !== ($databaseConfig = $config->get('database'))) {
if (null === $databaseConfig->get('username') || null ===
$databaseConfig->get('dbname')) {
require_once 'Myak/Exception.php';
throw new Myak_Exception('Invalid configuration (check
username or dbname options).');
}
if (null === $databaseConfig->get('host')) {
$databaseConfig->host = 'localhost';
}
if (null === ($driver = $databaseConfig->get('driver'))) {
$databaseConfig->driver = 'pdo_mysql';
} else {
$databaseConfig->driver = strtolower($driver);
}
if (null === $databaseConfig->get('collation')) {
$databaseConfig->collation = 'utf8';
}
if (null === $databaseConfig->get('prefix')) {
$databaseConfig->prefix = '';
}
$drivers = array(
'db2' => array(),
'mysqli' => array('mysqli'),
'odbc' => array(),
'oracle' => array(),
'pdo_mssql' => array('pdo', 'pdo_mssql'),
'pdo_mysql' => array('pdo', 'pdo_mysql'),
'pdo_oci' => array('pdo', 'pdo_oci8'),
'pdo_pgsql' => array('pdo', 'pdo_pgsql'),
'pdo_sqlite' => array('pdo', 'pdo_sqlite'),
);
$this->_loadRequiredExtensions($drivers[$databaseConfig-
>driver]);
}

$this->_config = $config;

return $this;
}

public function getRequest()
{
$front = $this->getFront();
if (null === $front->getRequest()) {
require_once 'Zend/Controller/Request/Http.php';
$front->setRequest(new Zend_Controller_Request_Http());
}
return $front->getRequest();
}

public function setRequest($request)
{
$this->getFront()->setRequest($request);
return $this;
}

public function getResponse()
{
$front = $this->getFront();
if (null === $front->getResponse()) {
require_once 'Zend/Controller/Response/Http.php';
$front->setResponse(new Zend_Controller_Response_Http());
}
return $front->getResponse();
}

public function getDispatcher()
{
return $this->getFront()->getDispatcher();
}

public function getRouter()
{
return $this->getFront()->getRouter();
}

public function getDb()
{
if ($this->_db === null) {
if (null === ($config = $this->getConfig()-
>get('database'))) {
require_once 'Myak/Exception.php';
throw new Myak_Exception('Database configuration was
no set.');
}
require_once 'Zend/Db.php';
$settings = array(
'host' => $config->host,
'username' => $config->username,
'password' => $config->password,
'dbname' => $config->dbname
);
$db = Zend_Db::factory($config->driver, $settings);
$db->query('SET NAMES \'' . $config->collation . '\'');
$db->prefix = $config->prefix;
$this->_db = $db;

require_once 'Myak/Db/Table.php';
Myak_Db_Table::setDefaultAdapter($db);
}
return $this->_db;
}

public function getLogger()
{
if ($this->_logger === null) {
$this->setLogger();
}
return $this->_logger;
}

public function setLogger()
{
$log = 0;
$config = $this->getConfig();
$varDir = $this->getVarDir();
if ($varDir !== null && isset($config->myak->log)) {
$config = $config->myak->log;
if ($config->get('enable')) {
require_once 'Zend/Log/Writer/Stream.php';
$writer = new Zend_Log_Writer_Stream($this->_varDir .
'/log/' . date('Y-m-d') . '.log');
$format = '%timestamp% %priorityName% (%priority%):
%message%' . PHP_EOL . PHP_EOL;
$writer->setFormatter(new
Zend_Log_Formatter_Simple($format));
$level = $config->get('level');
if ($level >= 0) {
$writer->addFilter(new
Zend_Log_Filter_Priority($level));
}
$log = 1;
}
}
if (!$log) {
require_once 'Zend/Log/Writer/Null.php';
$writer = new Zend_Log_Writer_Null();
}
$this->_logger = new Zend_Log($writer);
return $this;
}

public function setModuleDir($path)
{
$moduleDir = $this->_normalizePath($path);
if (!is_dir($moduleDir)) {
require_once 'Myak/Exception.php';
throw new Myak_Exception('Invalid module directory
provided.');
}
$this->_moduleDir = $moduleDir;
return $this;
}

public function getModuleDir()
{
return $this->_moduleDir;
}

public function setTemplateDir($path)
{
$templateDir = $this->_normalizePath($path);
if (php_sapi_name() == 'cli') {
$this->_templateUrl = '';
} else {
$baseUrl = $this->getBaseUrl();
if (empty($baseUrl)) {
$baseUrl = '/';
}
if (false === ($pos = strripos($templateDir, $baseUrl))) {
require_once 'Myak/Exception.php';
throw new Myak_Exception('Bad path (template directory
or base URL).');
}
$this->_templateUrl = substr($templateDir, $pos);
}
$this->_templateDir = $templateDir;
return $this;
}

public function getTemplateDir()
{
return $this->_templateDir;
}

public function getTemplateUrl()
{
return $this->_templateUrl;
}

public function getTemplate()
{
return $this->getConfig()->get('myak')->get('template');
}

public function setVarDir($path)
{
$varDir = $this->_normalizePath($path);
$dirs = array(
'cacheDir' => $varDir . '/cache',
'logDir' => $varDir . '/log',
'sessionDir' => $varDir . '/session',
);
foreach ($dirs as $key => $dir) {
if (!is_writable($dir) || !is_dir($dir)) {
require_once 'Myak/Exception.php';
throw new Myak_Exception("Directory \"$dir\" should be
valid and has write permissions (777).");
}
$key = '_' . $key;
$this->$key = $dir;
}
$this->_varDir = $varDir;
return $this;
}

public function getVarDir()
{
return $this->_varDir;
}

public function getLogDir()
{
return $this->_logDir;
}

public function getSessionDir()
{
return $this->_sessionDir;
}

public function getCacheDir()
{
return $this->_cacheDir;
}

public function setUploadDir($path)
{
$uploadDir = $this->_normalizePath($path);
if (!is_writable($uploadDir) || !is_dir($uploadDir)) {
require_once 'Myak/Exception.php';
throw new Myak_Exception("Directory \"$path\" should be
valid and has write permissions (777).");
}
if (php_sapi_name() == 'cli') {
$this->_uploadUrl = '';
} else {
$baseUrl = $this->getBaseUrl();
if (empty($baseUrl)) {
$baseUrl = '/';
}
if (false === ($pos = strripos($uploadDir, $baseUrl))) {
require_once 'Myak/Exception.php';
throw new Myak_Exception('Bad path (upload directory
or base URL).');
}
$this->_uploadUrl = substr($uploadDir, $pos);
}
$this->_uploadDir = $uploadDir;
return $this;
}

public function getUploadDir()
{
return $this->_uploadDir;
}

public function getUploadUrl()
{
return $this->_uploadUrl;
}

public function getBaseUrl()
{
$front = $this->getFront();
if (null === $front->getBaseUrl() && php_sapi_name() != 'cli')
{
$config = $this->getConfig();
if (!empty($config->myak->base_url)) {
$front->setBaseUrl((string) $config->myak->base_url);
} else {
$front->setBaseUrl(dirname($_SERVER['SCRIPT_NAME']));
}
}
return $front->getBaseUrl();
}

public function setBaseUrl($url)
{
$this->getFront()->setBaseUrl((string) $url);
return $this;
}

protected function _initView()
{
$template = $this->getTemplate();
$templateDir = $this->_templateDir;

$layout = Zend_Layout::startMvc(array('layoutPath' =>
$templateDir . '/' . $template));
$layout->setLayout('index');

$options = array(
'helperPath' => 'Myak/View/Helper',
'helperPathPrefix' => 'Myak_View_Helper',
);
$view = new Myak_View($options);

$viewRenderer = new
Zend_Controller_Action_Helper_ViewRenderer($view);
// For common .phtml files in themes/template_name directory.
$viewRenderer->view->addScriptPath($templateDir . '/' .
$template);
$viewRenderer->view->setEncoding($this->_config-
>get('general')->get('charset'));
$viewRenderer->setViewScriptPathSpec($template .
'/:controller-:action.:suffix')
->setViewScriptPathNoControllerSpec($template .
'/:action.:suffix');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

return $this;
}

protected function _initFront()
{
$front = $this->getFront();

$front->throwExceptions($this->getConfig()->get('myak')-
>get('debug'));

$front->setBaseUrl($this->getBaseUrl());

Zend_Controller_Action_HelperBroker::addPath(
'Myak/Controller/Action/Helper/',
'Myak_Controller_Action_Helper'
);

$this->getRequest();

$this->getResponse();

return $this;
}

protected function _normalizePath($path)
{
return rtrim(str_replace('\\', '/', $path), '/');
}

protected function _loadRequiredExtensions(array $extensions =
array())
{
foreach ($extensions as $extension) {
if (!extension_loaded($extension)) {
require_once 'Myak/Exception.php';
throw new Myak_Exception("Extension \"$extension\" not
found. Check php.ini and run phpinfo() function.");
}
}
return $this;
}

protected function _getGetter($index)
{
static $mapped = array();
if (isset($mapped[$index])) {
return $mapped[$index];
}
$method = 'get' . ucfirst($index);
if (method_exists($this, $method)) {
$mapped[$index] = $method;
return $method;
}
$mapped[$index] = false;
return false;
}

protected function _getSetter($index)
{
static $mapped = array();
if (isset($mapped[$index])) {
return $mapped[$index];
}
$method = 'set' . ucfirst($index);
if (method_exists($this, $method)) {
$mapped[$index] = $method;
return $method;
}
$mapped[$index] = false;
return false;
}

protected function _unregisterGlobals()
{
$rg = @ini_get('register_globals');
if ($rg === '' || $rg === '0' || strtolower($rg) === 'off') {
return $this;
}

// Prevent script.php?GLOBALS[foo]=bar
if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS']))
{
exit('I\'ll have a steak sandwich and... a steak
sandwich.');
}

$noUnset = array('GLOBALS', '_GET', '_POST', '_COOKIE',
'_REQUEST', '_SERVER', '_ENV', '_FILES');

$input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV,
$_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION :
array());
foreach ($input as $k => $v) {
if (!in_array($k, $noUnset) && isset($GLOBALS[$k])) {
unset($GLOBALS[$k]);
unset($GLOBALS[$k]); // Double unset to circumvent the
zend_hash_del_key_or_index hole in PHP < 5.1.4.
}
}

return $this;
}

protected function _stripGlobalSlashes()
{
set_magic_quotes_runtime(0);

if (get_magic_quotes_gpc()) {
$_GET = $this->_stripSlashesArray($_GET);
$_POST = $this->_stripSlashesArray($_POST);
$_COOKIE = $this->_stripSlashesArray($_COOKIE);
$_REQUEST = $this->_stripSlashesArray($_REQUEST);
}

return $this;
}

protected function _stripSlashesArray(&$array)
{
return is_array($array) ? array_map(array($this,
'_stripSlashesArray'), $array) : stripslashes($array);
}
}
</pre>
Пример использования:
<pre>
$dir = dirname(__FILE__);
set_include_path($dir . '/application'
. PATH_SEPARATOR . $dir . '/library');

require_once 'Myak.php';
Myak::setInstance(new Myak);
Myak::getInstance()
->setConfig($dir . '/config/myak.php')
->setModuleDir($dir . '/modules')
->setTemplateDir($dir . '/templates')
->setUploadDir($dir . '/uploads')
->setVarDir($dir . '/var')
->run();
</pre>
Конфиг может передаваться несколькими способами:
1. Как массив.
2. Как .ini, .xml или .php файл.
Пример конфига:
<pre>
<?php
$config = array(
'General' =>
array (
'charset' => 'utf-8',
'timezone' => 'Europe/Kiev',
),
'Database' =>
array (
'host' => 'localhost',
'username' => 'gazetka',
'password' => 'password',
'dbname' => 'gazetka',
'collation' => 'utf8',
'prefix' => '',
'driver' => 'MySqli',
),
'Myak' =>
array (
'autoload' => '1',
'template' => 'gazetka',
'gzip' => 1,
'debug' => 1,
'log' => array(
'enable' => 1
),
),
);
</pre>
Класс полезен тем, что вы можете получить любой объект в любом месте
программы:
<pre>
Myak::get('db');
Myak::get('router');
Myak::get('logger');
</pre>
и т. д.
Также можно сохранить любой объект с помощью Myak::set('объект'), т.
е. класс действует как реестр.

Все ошибки автоматом пишутся в лог-файл, который будет лежать в
директории var/log.

Если есть вопросы, пожалуйста задавайте. Жду критики и предложений по
улучшению кода.

Александр Ильин

unread,
Oct 7, 2008, 11:04:11 AM10/7/08
to ru-zend-...@googlegroups.com
Чем он лучше Zend_Registry?

7 октября 2008 г. 19:00 пользователь Hinikato Dubrai <hini...@googlemail.com> написал:

Hinikato Dubrai

unread,
Oct 7, 2008, 11:13:19 AM10/7/08
to ru-zend-framework
On 7 окт, 18:04, "Александр Ильин" <mecomma...@gmail.com> wrote:
> Чем он лучше Zend_Registry?

Задачами которые он выполняет.

Забыл написать, что к этому классу нужен роут.
<pre>
class Route_User extends Zend_Controller_Router_Route
{
public function match($path)
{
if ($result = parent::match($path)) {
$result['controller'] = $result['user'] . '-' .
$result['controller'];
}
return $result;
}
}
</pre>
Тогда после его добавления:
<pre>
$roles = array('admin');
$roles = implode('|', $roles);
if (preg_match("#^($roles)#si", ltrim(Myak::get('request')-
>getPathInfo(), '/'))) {
require_once dirname(__FILE__) . '/Route.php';
Myak::get('router')->addRoute('user', new
User_Route(':user/:module/:controller/:action/*', array(
'user' => 'user',
'module' => 'default',
'controller' => 'index',
'action' => 'index'
)));
}
</pre>
URL такого вида: http://host/admin/one/two/three преобразуются в
контроллер One_AdminTwoController и действие threeAction().
Могу сделать рабочий пример, для тех кому непонятно и интересно..

Александр Ильин

unread,
Oct 7, 2008, 11:17:43 AM10/7/08
to ru-zend-...@googlegroups.com
Я не очень понял в чем фишка? Стандартный функционал позволяет делать все почти один в один... плюс паттерн singleton изучите... а то сетИнстанс это не камильфо.

7 октября 2008 г. 19:13 пользователь Hinikato Dubrai <hini...@googlemail.com> написал:

Антон Коленков

unread,
Oct 7, 2008, 11:17:56 AM10/7/08
to ru-zend-...@googlegroups.com
Насколько я понял, пробежавшись по диагонали по предлагаемому классу, вопрос "Чем он лучше Zend_Registry?" будет неверным. Опять же, насколько я понял, автор предлагает класс который инкапсулирует в себя задачи по инициализации приложения. И, параллельно, для удобства же выступает своего рода обёрткой для Zend_Registry.
Иными словами, он не является заменой Zend_Registry, его основная задача в другом, но для удобства он умеет и это :)
Если я что-то недопонял, то автор, надеюсь меня поправит и дополнит. А из "критики" есть пожелание выложить это где-то чтобы это можно было видеть в цвете, а то plaintext читать сложновато :)

7 октября 2008 г. 19:04 пользователь Александр Ильин <mecom...@gmail.com> написал:



--
С уважением,
    Антон

Hinikato Dubrai

unread,
Oct 7, 2008, 11:18:14 AM10/7/08
to ru-zend-framework
У меня есть заготовка для CMS на основе ZF и класса, код которого я
привел выше. Если кому-то интересно и вы готовы поучаствовать,
пожалуйста, пишите, не стесняйтесь... ;)

Александр Ильин

unread,
Oct 7, 2008, 11:21:11 AM10/7/08
to ru-zend-...@googlegroups.com
Я код смотреть вообще не стал так как группы крут все в мясо. Почему не реализовать инициализацию плагином к фронт контроллеру, в чем приемущества?

7 октября 2008 г. 19:17 пользователь Антон Коленков <dora...@gmail.com> написал:

Антон Коленков

unread,
Oct 7, 2008, 11:23:54 AM10/7/08
to ru-zend-...@googlegroups.com
А вот на вопрос о преимуществах мы попросим автора ответить :) Он код лучше знает и у него он не перемолот в мясо.

7 октября 2008 г. 19:21 пользователь Александр Ильин <mecom...@gmail.com> написал:



--
С уважением,
    Антон

Vlad Thepesh

unread,
Oct 7, 2008, 11:25:27 AM10/7/08
to ru-zend-...@googlegroups.com
Могли бы Вы перечислить задачи, которые решает Ваш класс? Дайте больше
деталей по функциональности и примеров, пожалуйста. По коду
разбираться лениво.

2008/10/7 Александр Ильин <mecom...@gmail.com>:

Hinikato Dubrai

unread,
Oct 7, 2008, 11:29:13 AM10/7/08
to ru-zend-framework
Давайте я напишу небольшой Hello World и выложу пример использования
класса вместе с кодом. Где-то часа через два выложу...

Игорь

unread,
Oct 7, 2008, 11:40:50 AM10/7/08
to ru-zend-framework
Ждемс, самому стало интересно, если, что выкладывайте еще
http://zendframework.ru/forum/index.php там много новичков и готовые
решения многим пригодятся.

Hinikato Dubrai

unread,
Oct 7, 2008, 1:36:25 PM10/7/08
to ru-zend-framework
В общем я пока пишу статью по использованию, она будет находиться
здесь: http://hinikato.blogspot.com/search/label/Myak-CMS

Там же есть ссылка на скачивание архива. Чтобы это дело заставить
работать пропишите свои настройки базы и base_url в файле config/
myak.php. Значения ключа 'config' = 1, включает режим отладки. Это
пока основные моменты, об остальном читайте в доках, которые я чуть
позже допишу.

Вот сайт, который я создал на основе этих классов (Myak-CMS):
http://gazetka.org.ua/

Жду ваших комментов.

Hinikato Dubrai

unread,
Oct 7, 2008, 1:38:35 PM10/7/08
to ru-zend-framework
> myak.php. Значения ключа 'config' = 1, включает режим отладки. Это
Опечатался, 'debug' => 1
:)

Hinikato Dubrai

unread,
Oct 7, 2008, 1:58:48 PM10/7/08
to ru-zend-framework
Кстати, Антон Коленков, вы совершенно правы. Еще забыл сказать
последний Zend Framework надо положить в папку library. Потом в любом
контроллере вы можете писать:
Myak::get('db');
Myak::get('router');
Myak::get('dispatcher');
Myak::get('logger');
Myak::get('config');
Myak::get('front');
Также в любом контроллере можно подгружать модели следующим образом:
$model = $this->loadModel('КлассМодели', 'модуль');
$model->fetchAll();
...
Можно выводить сообщения пользователю. Для этого в контроллере:
$this->addMessage();
а в виде:
echo $this->messenger();
Если идет Ajax запрос, то Myak_Controller_Action от которого должны
наследоваться все контроллеры
автоматом отрубит вид.

С сессией также удобно работать в контроллерах. Для этого просто нужно
ее получить:
$session = $this->getSession();
А затем можно писать в $session->переменная свои данные - они попадут
в сессию.

Александр Ильин

unread,
Oct 8, 2008, 5:35:12 AM10/8/08
to ru-zend-...@googlegroups.com
руками baseUrl прописывать не стоит... только путаница... фреймверк его палит отлично.

7 октября 2008 г. 21:36 пользователь Hinikato Dubrai <hini...@googlemail.com> написал:

Hinikato Dubrai

unread,
Oct 8, 2008, 7:11:12 AM10/8/08
to ru-zend-framework
On 8 окт, 12:35, "Александр Ильин" <mecomma...@gmail.com> wrote:
> руками baseUrl прописывать не стоит... только путаница... фреймверк его
> палит отлично.
Хорошо, на этот счет посмотрю можно ли заменить это на $this-
>getRequest()->getBaseUrl().

Хотелось бы знать ваш ответ, нужно ли продолжать и нужно вообще все
это для вас? Лично я для себя буду заниматься CMS, а вам оно надо?
Если да, то продолжу написание документации и примеров.

Александр Ильин

unread,
Oct 8, 2008, 7:14:14 AM10/8/08
to ru-zend-...@googlegroups.com
Я аналогичным занимался, энтузиазм кончился - разработку заморозил, но в голове зреют идеи... а времени на реализацию нет.

8 октября 2008 г. 15:11 пользователь Hinikato Dubrai <hini...@googlemail.com> написал:

Игорь

unread,
Oct 8, 2008, 7:14:22 AM10/8/08
to ru-zend-framework
Раз вы будите заниматся, то выкладывайте примеры и документацию, думаю
многим пригодится, а кто то и идеи какие то позаимствует.

Александр Махомет

unread,
Oct 8, 2008, 7:17:33 AM10/8/08
to ru-zend-...@googlegroups.com

Это никому не помешает :) Но многочисленных откликов сразу вы можете не получить :)
обычно тогда и пропадает энтузиазм.

Лично мне всегда интересно посмотреть на чужой опыт.


8 октября 2008 г. 14:11 пользователь Hinikato Dubrai <hini...@googlemail.com> написал:

Hinikato Dubrai

unread,
Oct 8, 2008, 8:10:31 AM10/8/08
to ru-zend-framework
Хорошо, ваше мнение понял. Вообще я делаю для себя, т. е. использую
это все в работе, т. к. я фрилансер. В общем постараюсь выкладывать
релизы и написать документацию, разъясняющую принципы работы.
Последние новости и документацию буду публиковать в моем блоге:
http://hinikato.blogspot.com/search/label/Myak-CMS

A. Steshenko

unread,
Oct 8, 2008, 8:40:09 AM10/8/08
to ru-zend-...@googlegroups.com
Так и чего вы удалили то статью? Я вам там второй комментарий с советами
/ вопросами писал. Напугал мой первый комментарий?)

Насчет документации - если это проект для вас а не на продажу, то чтобы
не тратить время лишнее не обязательно прямо сидеть над качественным
мануалом, но оформлять комментарии надо по стандарту к методам, классам
и внутренней логике, где это необходимо. И писать их сразу во время
разработки, так будет удобнее и вам и в принципе достаточно для изучения
другими людьми.

Hinikato Dubrai пишет:

Hinikato Dubrai

unread,
Oct 8, 2008, 10:16:14 AM10/8/08
to ru-zend-framework
On 8 окт, 15:40, "A. Steshenko" <lcfs...@gmail.com> wrote:
> Так и чего вы удалили то статью? Я вам там второй комментарий с советами
> / вопросами писал. Напугал мой первый комментарий?)

Я статью просто писал, поэтому она то появлялась, то нет. Сейчас
посмотрите.

Я написал мануал по созданию Hello World! Лежит здесь:
http://hinikato.blogspot.com/search/label/Myak-CMS

Я хотел бы знать, пробует кто-то то что там написано, и если да, то
что
получается, что нет. Жду комментов..

> Насчет документации - если это проект для вас а не на продажу, то чтобы
> не тратить время лишнее не обязательно прямо сидеть над качественным
> мануалом, но оформлять комментарии надо по стандарту к методам, классам
> и внутренней логике, где это необходимо. И писать их сразу во время
> разработки, так будет удобнее и вам и в принципе достаточно для изучения
> другими людьми.

Насчет документации, я считаю что нужна только такая документация как
Programmer's Reference Guide, документацию в стиле phpDocumentor
считаю
бессмысленной. Лучше написать хорошие тесты, они лучше скажут как
пользоваться
классом. Ну тестов пока мало, надо писать и переписывать много, но это
все
постепенно..

Игорь

unread,
Oct 8, 2008, 10:19:46 AM10/8/08
to ru-zend-framework
На сегодня-завтра запустим и посмотрим, тесты тоже хороший вариант, и
мануал в стиле Programmer's Reference Guide тоже нужен

Антон Коленков

unread,
Oct 8, 2008, 1:17:00 PM10/8/08
to ru-zend-...@googlegroups.com

Документация в стиле phpDocumentor полезна при работе в Eclipse или Zend Studio(а может и ещё в каких редакторах), т.к. позволяет среде давать подсказки и списки параметров для функций и методов. Т.е. для генерации документации я её использую крайне редко, а вот для комфортной работы в среде - постоянно.


8 октября 2008 г. 18:16 пользователь Hinikato Dubrai <hini...@googlemail.com> написал:



--
С уважением,
    Антон

Александр Ильин

unread,
Oct 8, 2008, 1:51:02 PM10/8/08
to ru-zend-...@googlegroups.com
Аналогично, очень удобно в ZS.

8 октября 2008 г. 21:17 пользователь Антон Коленков
<dora...@gmail.com> написал:

Александр Махомет

unread,
Oct 8, 2008, 1:58:46 PM10/8/08
to ru-zend-...@googlegroups.com
+1 :)

8 октября 2008 г. 20:17 пользователь Антон Коленков <dora...@gmail.com> написал:

Hinikato Dubrai

unread,
Oct 8, 2008, 4:52:03 PM10/8/08
to ru-zend-framework
Обновил класс Myak и Myak_Controller_Action. Исправил несколько багов,
изменил способ отдачи baseUrl. Предыдущий способ мог приводить к
зацикливанию программы. Добавил папку с тестами. Обновленный вариант
скачать можно отсюда:
http://code.google.com/p/myak-cms/downloads/list

Hinikato Dubrai

unread,
Oct 8, 2008, 4:52:54 PM10/8/08
to ru-zend-framework

Arech

unread,
Oct 8, 2008, 5:07:54 PM10/8/08
to ru-zend-framework
On 8 окт, 21:51, "Александр Ильин" <mecomma...@gmail.com> wrote:
> Аналогично, очень удобно в ZS.

+1. Окончательно перешёл на ZS несколько недель назад с ВижуалСтудии
+VS.PHP и потихоньку начинаю тащиться от этого инструмента. Весьма
своеобразный и виндузятнику по началу приходится не легко, но как
нарабатываешь навыки и опыт - потихоньку начинаешь просто влюбляться.
Очень грамотный инструмент с шикарными возможностями. Жаль только
JavaScript дебужить не умеет...

(оффтопег злостный, да простит топикстартер )))

Hinikato Dubrai

unread,
Oct 9, 2008, 6:19:09 AM10/9/08
to ru-zend-framework
Хотелось бы знать ваше мнение, класс Myak по идее может использовать
базу данных? Т. е. в методе getRoles() использовать БД... Также я еще
не продумал до конца как классу Myak_Helper_Broker получать список
активных модулей. Должен ли он лезть для этого в БД или может есть
какой-то другой хороший способ.

Скорее всего все-таки придется оговорить что класс Myak это уже не
просто библиотека а класс, отвечающий за инициализацию CMS (это можно
будет сделать, если будет привязка к БД, а она так или иначе
понадобится).

Просто хочу от вас получить мнение, все таки затачивать весь
функционал (в папке application) именно как CMS, или оставить на
уровне библиотек?

Hinikato Dubrai

unread,
Oct 10, 2008, 8:32:00 AM10/10/08
to ru-zend-framework
Сделал измения в методе Myak_Controller_Action::getSession() и создал
SVN: http://code.google.com/p/myak-cms/source/checkout

Последнию релиз вы можете получить так:
svn co http://myak-cms.googlecode.com/svn/trunk/

sibcoder

unread,
Oct 11, 2008, 9:50:05 AM10/11/08
to ru-zend-framework
> Просто хочу от вас получить мнение, все таки затачивать весь
> функционал (в папке application) именно как CMS, или оставить на
> уровне библиотек?

Лучше в отдельный метод вынести, чтобы убрать можно было.

Hinikato Dubrai

unread,
Oct 11, 2008, 10:44:41 AM10/11/08
to ru-zend-framework
Еще хочу узнать.. Кто-то что-то пытался сделать из того, что я написал
в блоге, или никто ничего не понял/или посчитали это все ненужным..
Может написано непонятно? Или нужно еще примеры?

sibcoder

unread,
Oct 11, 2008, 11:18:48 AM10/11/08
to ru-zend-framework
Штука интересная на первый взгляд по диагонали, но пока не пробовал,
ибо дедлайн

Arech

unread,
Oct 12, 2008, 4:36:08 AM10/12/08
to ru-zend-framework
On 11 окт, 18:44, Hinikato Dubrai <hinik...@googlemail.com> wrote:
Хм... Честно говоря, я хоть и с интересом слежу за этой темой, но тоже
не смотрел туда, потому что во первых "ибо дедлайн" (с), да, а во
вторых - конкретно сейчас мне это не нужно...

Если Вам интересно мнение, то я бы на Вашем месте чётко определился бы
со своими целями (зачем конкретно мне то, что я делаю, какую мне это
несёт пользу) и в зависимости от ответа бы решал собственные задачи,
выкладывая описание реализованных возможностей (если так хочется) в
сеть. С тем бы, кто заинтересовался бы, можно было бы работать более
предметно...

Просто получается такая штуковина, что ты либо занимаешься достижением
своих целей, либо, грубо говоря, "отапливаешь Вселенную" (если согрев
окружающих не входит в твои личные цели).

Подчеркну ещё раз, всё ИМХО.

Hinikato Dubrai

unread,
Oct 12, 2008, 7:44:00 AM10/12/08
to ru-zend-framework
> Хм... Честно говоря, я хоть и с интересом слежу за этой темой, но тоже
> не смотрел туда, потому что во первых "ибо дедлайн" (с), да, а во
> вторых - конкретно сейчас мне это не нужно...
>
> Если Вам интересно мнение, то я бы на Вашем месте чётко определился бы
> со своими целями (зачем конкретно мне то, что я делаю, какую мне это
> несёт пользу) и в зависимости от ответа бы решал собственные задачи,
> выкладывая описание реализованных возможностей (если так хочется) в
> сеть. С тем бы, кто заинтересовался бы, можно было бы работать более
> предметно...
>
> Просто получается такая штуковина, что ты либо занимаешься достижением
> своих целей, либо, грубо говоря, "отапливаешь Вселенную" (если согрев
> окружающих не входит в твои личные цели).
>
> Подчеркну ещё раз, всё ИМХО.

Ну в общем я уже определился.. Я просто делаю CMS для себя, но и
хочется поделиться этим, чтобы люди могли пользоваться, если посчитают
это нужным. Вообще, хочу, преобрести опыт, ведь если делаешь сам и не
выкладываешь нигде, никто не сможет высказать замечания, оценить,
показать ошибки и т. д. Вот уже благодаря этой теме, я изменил способ
определения $baseUrl в классе Myak. Многие же знают больше меня и
могут дать совет. Вообще я потратил кучу времени, чтобы прийти к
такому результату (пусть и пока маленькому). Хочется чтобы другие
экономили время, если подход, предложенный мной, им понравится.

Вообщем сейчас я сконцентрировался на том, чтобы сделать инсталлятор и
начать разрабатывать парочку модулей с админкой. Считаю, что нужно
сейчас реализовать модуль авторизации и разграничения прав на основе
Zend_Acl + Zend_Auth. Может это лучше сделать плагином или Action-
хелпером, я еще не знаю. Вот и хочется тоже узнать какие-есть
варианты? На сегодняшний момент я думаю сделать так:

1. есть модуль users и контроллер Users_IndexController, имеющий два
действия: loginAction() и logoutAction(). Эти действия отвечают за
авторизацию. Авторизация ведется по логину и паролю. При проверке
логин и пароль берется из базы. После успешной авторизации
пользователю в сессию сохраняется id и username. В общем вот код этого
контроллера:
<?php
class Users_IndexController extends Myak_Controller_Action
{
public function init()
{
parent::init();
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$this->_redirect($this->_getUrl());;
}
}

public function loginAction()
{
$form = new Myak_Form(array(
'elements' => array(
'username' => array('text', array(
'size' => 20,
'label' => 'Логин',
'required' => true,
'validators' => array(
array('NotEmpty', false, array('messages' =>
'Не указан логин.')),
),
'filters' => array(
'StringTrim',
),
)),
'password' => array('password', array(
'size' => 20,
'label' => 'Пароль',
'required' => true,
'validators' => array(
array('NotEmpty', false, array('messages' =>
'Не указан пароль.')),
),
'filters' => array(
'StringTrim',
),
)),
'submit' => array('submit', array(
'value' => 'Войти',
'style' => 'margin-bottom: 1em;',
)),
),
'action' => $this->_request->getRequestUri(),
));
$form->addDisplayGroup(array('username', 'password',
'submit'), 'login', array('legend' => 'Вход на сайт'));
if ($this->_request->isPost()) {
if ($form->isValid($_POST)) {
$data = $this->getAllowedData(array('username',
'password'), $form->getValues());
$authAdapter = new
Zend_Auth_Adapter_DbTable(Myak::get('db'), 'users', 'username',
'password', "MD5(CONCAT('1234_decode_me_if_you_can', ?, salt))");
$authAdapter->setIdentity($data['username']);
$authAdapter->setCredential($data['password']);

$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($authAdapter);
if ($result->isValid()) {
$data = $authAdapter-
>getResultRowObject(array('id', 'username'));
$auth->getStorage()->write($data);
$this->_redirect($this->_getUrl());
} else {
$this->addError('Неправильный логин или пароль.');
}
}
}
echo $this->view->messenger();
echo $form;
$this->_helper->viewRenderer->setNoRender();
}

public function logoutAction()
{
Zend_Auth::getInstance()->clearIdentity();
$this->_redirect('/');
}

protected function _getUrl()
{
$to = $this->_request->getQuery('to');
if ($to === null || preg_match('#^/?users#si', $to)) {
return '/';
}
return $this->view->escape($to);
}
}
Пример этой формы можно увидеть здесь: http://gazetka.org.ua/users/index/login

2. На этом собственно я застопорился. Теперь надо продумать каким
образом проверять и разграничивать доступ к определенным частям сайта.
Наброски есть, это плагин Myak_Controller_Plugin_Acl. Но еще не
понятно где должны иницилизироваться роли. Очевидно, что их надо брать
из базы. Но в каком классе это лучше делать непонятно. Также пока
непонятно, где надо прописывать правила для этих ролей (т. е. куда
можно ходить им и что можно делать). То ли создать класс Myak_Acl и
там все это сделать, то ли сделать это все в плагине, а может все
вместе? В любом случае хочется чтобы класс Myak_Acl или плагин были
доступны через Myak::get('acl').

Вот пока так...

sibcoder

unread,
Oct 12, 2008, 10:03:27 AM10/12/08
to ru-zend-framework
Может формы со всеми валидаторами и фильтрами в отдельные классы
вынести?

matera.ttp

unread,
Oct 12, 2008, 12:25:12 PM10/12/08
to ru-zend-...@googlegroups.com
оффтоп:
на будущее, пожалуйста, выкладывайте код в раздел файлов/страниц группы, а здесь думаю было б удобнее просто написать для чего он предназначен

Hinikato Dubrai

unread,
Oct 21, 2008, 1:41:53 AM10/21/08
to ru-zend-framework
Обновил Myak-CMS до версии 0.1.0 PR (Preview Release).

Скачать последнюю версию можно отсюда: http://code.google.com/p/myak-cms/downloads/list

Лучше пользуйтесь SVN для получения свежей версии. Пример скачивания
по SVN:
svn checkout http://myak-cms.googlecode.com/svn/trunk/

В ближайшем будущем планируется написать документацию и продолжить
работу над проектом.

И не стесняйтесь, осваивайте, изучайте, дорабатывайте!
Reply all
Reply to author
Forward
0 new messages