Cotonti / Open Source PHP Content Management FrameworkContent Management Framework

Forums / National / Russian / Модули и плагины / Пишем плагин с нуля.

Cotonti не знаю - пишу плагин с нуля, решил описать процесс здесь так как информации по Cotonti очень мало - собираю по крупицам.

Salador
#1 2015-02-16 07:35

Задача:

Мне нужно создать простую бухгалтерскую систему начисления и выплаты зарплаты. Система простая один человек вносит сколько начислено сотруднику второй сколько выплачено. 

Система нужна для фермы, между тем кто будет начислять и выплачивать большое расстояние, так как интернет очень слабый 1С не подходит. Ничего простого в виде скрипта не нашел (только онлайн бухгатерии, но они с помесячной оплатой да и чтобы зарплату начислить много лишних действий нужно делать).

Выбор CMS:

Начал делать плагин под Wordpress но он слишком громоздкий для этого. Впринципе мне от CMS нужно: 1) Авторизация пользователей. 2) Легкая работа с базами данных, 3) Безопасность, 4) Шаблон на Bootstrap. Выбор на Cotonti пал из-за решения - Фриланс биржи  какое-то время назад оно попадалось мне, но нестал его использовать так как не знал CMS Cotonti.

Шаг 1, Установка:

Впринципе поставился легко. Возникла небольшая проблемка, ставил последнюю версию 0.9.18, версия php была 5.2.7 при установке всё нормально, но после установки сайт не загружался показывал ошибку (какая ошибка была - забыл) после поиска по ошибке нашел что аналогичная блыла на Joomle и связана с версией php. Установил php 5.3 и всё заработало. Вывод для разработчиков: с версии 0.9.18 (а может и раньше) нужно при установке проверять на php 5.3.

Шаг 2, Установка шаблонов:

  1. Шаблон администратора: Шаблон для админки Bootos на Bootstrap - поставился без проблем.
  2. Основной шаблон: Выбрал Barebones на Bootstrap - возникла небольшая проблемка не отображалась тема, в админке (Конфигурация->Темы) нужно поставить ДА в "Принудительная установка темы по умолчанию для всех пользователей:" и заработало. Я так понял что можно в настройках ставить разные темы разным пользователям, но не нашел как (если кто знает - подскажите).

 

Шаг 3, Поиск информации:

Информации очень мало нашел всего 3 сайта:

  1. Этот сайт, как понял главный http://www.cotonti.com/ 
  2. http://cmsworks.ru/
  3. http://mycotonti.ru/

На главном сайте много информации для старых версий, для адаптации под новые нужно менять заголовки и приставку к функциям "sed_" заменить на "cot_" (Например: Функция sed_import будет - cot_import).

Справочник по функциям здесь.

Шаг 4, Простой плагин:

Самый простой плагин взял отсюда (Создание плагина Hello World), дальше использовал информацию (Создание простейшего плагина) из документации. Пришлось немного подредактировать - вот что получилось на данном шаге (Скачать) - Плагин как и в документации умножает введенные числа и выводит ответ. Имеет 4 файла: языковой, шаблона, установочный и исполняемы. Чтобы увидеть плагин нужно перейти по ссылке index.php?e=salazarp

cot_import - как понял важная функция которая обрабатывает все получаемые данные через запросы, вот информация по параметрам.

Добавлено 35 минут спустя:

Шаг 5, Создание таблиц в базе данных:

Впринципе основная информация понятна. Переделываю плагин под себя. Для начала мне нужно чтобы в базе было три таблицы  1) Сотрудники 2) Начисления сотруднику 3) Выплаты сотруднику. 

Впринципе в Contonti это делается легко - просто создаем дирректорию setup в папке плагина и в ней создаем файл nameplugin.install.sql (у меня salazarp.install.sql) и туда добавляем sql скрипт создания таблицы.

Также добавляем файл nameplugin.uninstall.sql (у меня salazarp.uninstall.sql) там sql скрипт удаления таблиц.

 

 

Добавлено 1 час спустя:

Шаг 6, Несколько страниц в плагине:

Мне нужно чтобы в плагине было несколько страниц, данный момент думаю 5: 1) Создание сотрудника 2) Редактирование данных сотрудника 3) Ввод начислений сотруднику 4) Ввод выплат сотрудинку 5) Статистика по начислениям и выплатам на текущий месяц (можно на месяц по выбору).

Для каждой страницы желательно иметь свой файл шаблона.

Итак пока плагин умеет умножать введенные числа. Делаю так чтобы на одной странице он умножал числа, а на другой выводил результат. 

В папку tpl плагина добавлем два файла salazarp.addsotr.tpl и salazarp.outsotr.tpl. Подключение этих шаблонов происходит через XTemplate вот информация (Ссылка1, Ссылка 2).

Подключение шаблона -  

$t_salas= new XTemplate(cot_tplfile('salazarp.addsotr', 'plug'));

Как я понял вывод шаблона должен происходить через одну из функций.

$t_salas->out('MAIN');

или

$plugin_body = $t_salas->text('MAIN');

Но у меня они выводятся криво, и еще вместе с шаблоном показывается название плагина, может кто знает решение? Поэтому я пока решил выводить через главный шаблон.

$t->assign('SALAZARP_PAGES', $t_salas->text('MAIN'));

Вот что получилось на данный момент, на одной странице плагина вводятся данные для умножения, а на другой - ответ (Скачать).

При работе возникла проблема с кэшем (страница плагина не обновлялась после изменений) - в файле datas/config.php  ищем $cfg['cache'] = TRUE; и  $cfg['xtpl_cache'] = TRUE; и заменяем на FALSE.

Добавлено 2 часа спустя:

Шаг 7, Отдельный файл функций:

Нужно для функций сделать отдельный файл. Решил для начала вынести умножение в функцию.

Информацию не искал, просто как в других плагинах сделал папку inc и в ней создал файл salazarp.functions.php и добавил код.

defined('COT_CODE') || die('Wrong URL.');

function sala_proizved($d_1, $d_2) {
	
	$proizved = $d_1*$d_2; 
	return ($proizved);
}

В основном файле заменил 

$proizved = $d_1*$d_2; 
на
$proizved = sala_proizved($d_1,$d_2);

Всё заработало.


This post was edited by Salador (2015-02-16 20:43, 6 years ago)
Dr2005alex
#2 2015-02-16 15:42

Поздравляю !!! Начало положено...

WebKaa.ru - Cotonti Relax
Dayver
#3 2015-02-16 17:33
#40544 Salador:
  1. Основной шаблон: Выбрал Barebones на Bootstrap - возникла небольшая проблемка не отображалась тема, в админке (Конфигурация->Темы) нужно поставить ДА в "Принудительная установка темы по умолчанию для всех пользователей:" и заработало. Я так понял что можно в настройках ставить разные темы разным пользователям, но не нашел как (если кто знает - подскажите).

Любой залогиненый пользователь может на доступной ему странице /index.php?e=users&m=profile выбрать тему отображения сайта среди тек которые есть в папке тем. Вот как на этом сайте: 

Pavel Tkachenko aka Dayver. Гик и веб мастер который делает сайты, увлекается электроникой и очень любит смотреть кино.
О себе: Я злой и страшный серый волк, я в поросятах знааааюююю толк
Salador
#4 2015-02-16 19:14
#40545 Dr2005alex:

Поздравляю !!! Начало положено...

Благодарю.

Добавлено 5 минут спустя:

#40546 Dayver:

Любой залогиненый пользователь может на доступной ему странице /index.php?e=users&m=profile выбрать тему отображения сайта среди тек которые есть в папке тем.

Понятно, а я искал в админке. 

Добавлено 1 час спустя:

Шаг 8, Делаем на каждую страницу свой скрипт и шаблон:

Нужно чтобы каждая страница (например: добавление сотрудников) обрабатывалась отдельным файлом.

Пробовал через хуки (Информация по хукам Cotonti) - неполучилось, и они не для этого.

Незнаю есть ли встроенные методы, сделал по другому вроде норм в salazarp.php написал:

define('SALAZARP_LIB', $cfg['plugins_dir'].'/salazarp/lib/salazarp.'); //Папка с подключаемыми модулями 
$sala_link = cot_import('s','G','TXT'); //Проверяем на какой странице находимся например: s= addsotr

if (!empty($sala_link)) {
	$t= new XTemplate(cot_tplfile('salazarp.'.$sala_link, 'plug')); // подключает шаблон, если $sala_link=addsotr ищет шаблон tpl/salazarp.addsotr.tpl
	require (SALAZARP_LIB . $sala_link . '.php'); // подключает скрипт, если $sala_link=addsotr ищет скрипт lib/salazarp.addsotr.php
}	

еще сделал через скрипт чтобы все данные из языкового файла попадали в шаблон, но оказалось всё намного проще - в файле шаблона добавляется через {PHP.L.НАЗВАНИЕ_В_ЯЗЫКОВОМ_ФАЙЛЕ},  Например: 

$L['SZ_TITLE'] = "Пример плагина"; 	

Добавляем {PHP.L.SZ_TITLE}

Вот текущая версия (Скачать) седующая уже будет подстроена под мою задачу (без калькулятора умножения).

 


This post was edited by Salador (2015-02-16 20:38, 6 years ago)
Dayver
#5 2015-02-16 22:25
#40544 Salador:

Шаг 1, Установка:

Впринципе поставился легко. Возникла небольшая проблемка, ставил последнюю версию 0.9.18, версия php была 5.2.7 при установке всё нормально, но после установки сайт не загружался показывал ошибку (какая ошибка была - забыл) после поиска по ошибке нашел что аналогичная блыла на Joomle и связана с версией php. Установил php 5.3 и всё заработало. Вывод для разработчиков: с версии 0.9.18 (а может и раньше) нужно при установке проверять на php 5.3.

Обязательно проверять будет, для этого уже созданна заявка. Да и в комментариях и на странице релиза уже упоминалось об этом требовании, странно что пришлось искать на сторонних ресурсах. Просто забыли и поздно спохватились с проверкой версии, уже после релиза опомнились.

Pavel Tkachenko aka Dayver. Гик и веб мастер который делает сайты, увлекается электроникой и очень любит смотреть кино.
О себе: Я злой и страшный серый волк, я в поросятах знааааюююю толк
Macik
#6 2015-02-17 11:53

Отличная инструкция для новичков. Спасибо.

Далее немного комментариев

По шагу 5:

  1. Начисления и выплаты, возможно было бы логичнее разместить в одной таблице, а суммы даже в одной колоноке (просто с разным знаком). Это позволит, во-первых, делать меньше запросов к БД, а во-второых, некоторые расчеты осуществлять силами SQL и самой БД.

По шагу 6:

  1. Да, отдельные шаблоны как правило удобнее для поддержки. Тем не менее, особенно если плагин не большой, можно иметь один шаблон с несколькими блоками:
    <!-- BEGIN: ADD_USER -->
    …
    <!-- END: ADD_USER -->
    
    <!-- BEGIN: EDIT_USER -->
    …
    <!-- END: EDIT_USER -->
    
    …

    и при выводе парсить нужный блок.

  2. Вызов шаблона лучше осуществлять таким образом:
    $t_salas= new XTemplate(cot_tplfile(array('salazarp', $mode), 'plug'));

    где в переменной `$mode` у нас находится название текущей страницы (режима в котором работает плагин). См. об этом подробнее в комментарии к шагу 8.

  3. Если мы работает с блоком `MAIN`, его название можно опускать. Кроме этого вызовы функций шаблонизатора можно увязывать в цепочку:
    $plugin_body = $t_salas->parse()->text();

    (не забываем сделать парсинг нужного блока перед выводом)

  4. По шаблонам, логика такая (если код шаблона вызывается по хуку `standalone`) — если определен шаблон `имя_плагина.php` или `plugin.имя_плагина.php`, то он будет загружен автоматически в переменную `$t` (тогда можно использовать вариант с несколькими блоками, см. выше. Блок `MAIN` будет обработан автоматически). Иначе грузится стандартный шаблон `plugin.php` (обычно находится в папке с темой оформления).
    Если хочется использовать свой (например отдельный для кождого раздела), то есть 2 варианта:
       ​а). загрузить шаблон в отдельную переменную (как описано у тебя) и потом делать вывод в переменную `$plugin_body`.
       б). грузить свой шаблон «напрямую», переопределяя переменную `$t`. (В таком случае блок `MAIN` будет обработан автоматически).
  5. Кеширование шаблонов зависит от разных параметров. И в большинствеслучаев страницы обновляются при изменении шаблона.
  6. Если все же кеширование надо отключить — не надо отключать всю систему кеширования `$cfg['cache'] `. Достаточно сделать это только для $cfg['xtpl_cache']. Более того для тестовых целей можно использовать параметры инициализации шаблонизатора, не отключая кеширование на всем сайте:
    if ($cfg['debug_mode']) XTemplate::init(array('cache' => false )); // временно отключаем 
    $plug_tpl = new XTemplate(…); // инициализируем наш шаблон
    XTemplate::init(array(	'cache' => $cfg['xtpl_cache'] )); // возвращаем значения заданные для сайта

     

По шагу 8:

  1. переменная «s» в некоторых модулях используется системой для переключения режима сортировки выводимой информации. Поэтому, чтобы не было путаницы лучше изменить на что-то другое. И лучще если это будет более осмысленное название, например «mode».
  2. Строку 4 с проверкой на не пустое значение для большей безопасности лучше дополнить проверкой на допустимые значения —  `&& in_array('addsotr', 'outsotr', …)`
  3. В фрейморке уже есть некоторый код облегчающий загрузку частей кода в зависимости от выбранного режима. Если файлы `salazarp.addsotr.php` и прочие `salazarp.*.php` расположить в папке `/inc` своего расшрирения, то вызов нужной (строка 6) сведется к следующему:
    require_once cot_incfile('page', 'plug', $mode);

     

https://github.com/macik
правильный хостинг — https://goo.gl/fjCa1F
Salador
#7 2015-02-17 15:22
#40548 Dayver:

странно что пришлось искать на сторонних ресурсах.

просто по привычке, чуть что сразу в поисковик.

 

Добавлено 1 час спустя:

#40550 Macik:

По шагу 5:

Начисления и выплаты, возможно было бы логичнее разместить в одной таблице,

точно, так и сделаю

С кэшем не получилось выдает ошибку на функцию

XTemplate::init(array('cache' => $cfg['xtpl_cache']));

Fatal error: Uncaught exception 'Exception' with message 'Your "/templates/" is not writable' in /home/proficit/public_html/mysyte.ru/system/cotemplate.php:348 Stack trace: #0 /home/proficit/public_html/mysyte.ru/system/cotemplate.php(88): XTemplate->restart('themes/barebone...') #1 /home/proficit/public_html/mysyte.ru/system/header.php(82): XTemplate->__construct('themes/barebone...') #2 /home/proficit/public_html/mysyte.ru/system/plugin.php(118): require_once('/home/proficit/...') #3 /home/proficit/public_html/mysyte.ru/index.php(172): require_once('/home/proficit/...') #4 {main} thrown in /home/proficit/public_html/mysite.ru/system/cotemplate.php on line 348

права на папку /datas/cache/templates - 777 и видно что он туда записывает кэш.

получается 'cache' => false работает, а 'cache' => true выдает ошибку.

 

 

Добавлено 15 минут спустя:

Шаг 8, (Изменение):

Переделал как подсказал Macik  убрал папку lib из нее все файлы перекинул в папку inc, изменил код salazarp.php на этот

$mode = cot_import('mode','G','TXT'); //Проверяем на какой странице находимся например: mode= addsotr

$sala_pages=array('addsotr','outsotr'); //Список страниц которые будут в Модуле
$sala_links=sala_zap_url($sala_pages); //Функция создания ссылок на страницы
if ($cfg['debug_mode']) XTemplate::init(array('cache' => false )); // временно отключаем кэш если включен режим отладки 
if ((!empty($mode)) && in_array($mode, $sala_pages)) {
	$t= new XTemplate(cot_tplfile(array('salazarp', $mode), 'plug')); // подключает шаблон, если $mode=addsotr ищет шаблон tpl/salazarp.addsotr.tpl
	require_once cot_incfile('salazarp', 'plug', $mode); // подключает скрипт, если $mode=addsotr ищет скрипт inc/salazarp.addsotr.php
}
//XTemplate::init(array('cache' => $cfg['xtpl_cache'])); // возвращаем значения кэша заданные для сайта (!пока выдает ошибку)

впринципе уже можно начинать писать на нем свой плагин.

 


This post was edited by Salador (2015-02-19 14:31, 6 years ago)
Wilder
#8 2015-02-18 08:14
#40544 Salador:
Шаг 3, Поиск информации:

Информации очень мало нашел всего 3 сайта:

  1. Этот сайт, как понял главный http://www.cotonti.com/ 
  2. http://cmsworks.ru/
  3. http://mycotonti.ru/

Кроме этого, еще:


This post was edited by Wilder (2015-02-18 14:56, 6 years ago)
Dayver
#9 2015-02-18 18:32

Ребята, не превращайте полезный топик в каталог ресурсов

Pavel Tkachenko aka Dayver. Гик и веб мастер который делает сайты, увлекается электроникой и очень любит смотреть кино.
О себе: Я злой и страшный серый волк, я в поросятах знааааюююю толк
Salador
#10 2015-02-19 05:41

Шаг 9, Начало. Работа с базами данных:

Структуру Cotonti примерно понял теперь начинаю переделывать плагин под себя. Сначала сделаю добавление сотрудников.

1. Cоздал форму добавления сотрудника в файле tpl/salazarp.addsotr.tpl

2. В файле setup/salazarp.install.sql прописываем sql таблицы сотрудников

CREATE TABLE IF NOT EXISTS `cot_sotr` (
    `sotr_id` INT NOT NULL AUTO_INCREMENT, 
    `sotr_name` VARCHAR(100) NOT NULL, 
	`sotr_dolzh` VARCHAR(90) NOT NULL, 
    `sotr_desk` VARCHAR(255) NOT NULL, 
    `sotr_oklad` DECIMAL(10,2) default NULL, 
     PRIMARY KEY (`sotr_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Теперь нужно в админке удалить и заного установить плагин.

3. Используя информацию по работе с базами данных Cotonti и API Cotonti в файле inc/salazarp.addsotr.php сделал добавление сотрудника в базу.

$table_sotr='cot_sotr';   // название таблицы сотрудников
$par = cot_import('par','G','TXT'); 
if ((!empty($par)) && $par=='add') {	
	$arr_sotr=array (                           //получение значений из формы добавления сотрудника в массив
		'sotr_name'=>cot_import('sotr_name','P','TXT'),
		'sotr_dolzh'=>cot_import('sotr_dolzh','P','TXT'),
		'sotr_desk'=>cot_import('sotr_desk','P','TXT'),
		'sotr_oklad'=>cot_import('sotr_oklad','P','TXT')
	);
	if ($db->insert($table_sotr,$arr_sotr)) {   //ввод данных в таблицу сотрудников
		$plugin_body = $t_sz->parse('SUC_ADD_SOTR')->text('SUC_ADD_SOTR'); //успешное добавление сотрудника
	} else {
		$plugin_body = $t_sz->parse('NOT_ADD_SOTR')->text('NOT_ADD_SOTR'); //неудачное добавление сотрудника
	}
	 
} 
$plugin_body .= $t_sz->parse('ADD_SOTR')->text('ADD_SOTR');

4. Немного понял как работает XTemplate, в $t автоматически обрабатывается только 'MAIN' блок поэтому другие блоки туда нет смысла пихать. 

Немного переработал вывод - так как файл tpl/salazarp.tpl перекрывает стандартный вывод плагина для шаблона  /themes/barebones/plugin.tpl, то сделал его почти таким же:

<!-- BEGIN: MAIN -->
    {PLUGIN_BODY}
<!-- END: MAIN -->

а в файле salazarp.php сделал подключение шаблона в переменную $t_sz и добавил: 

if (!empty($plugin_body)) {
	$t->assign('PLUGIN_BODY',$plugin_body); //если не пустая переменная $plugin_body, то будет выводится её содержимое
} else {
	$t=$t_sz; //если переменная $plugin_body пустая, то будет выводится содержимое блока MAIN
}

 

Добавлено 1 день спустя:

Что-то немогу добавить JS и CSS файлы в <head>. Посмотрел как в других плагинах - сделал файл salazarp.rc.php туда положил код:

/* ====================
[BEGIN_COT_EXT]
Hooks=rc
[END_COT_EXT]
==================== */

define('SALAZARP_PLUG', $cfg['plugins_dir'].'/salazarp/');
cot_rc_add_file(SALAZARP_PLUG . 'js/moment.min.js');
cot_rc_add_file(SALAZARP_PLUG . 'js/daterangepicker.jss');
cot_rc_add_file(SALAZARP_PLUG . 'tpl/daterangepicker-bs2.css');

Неработает. Может с хуками не до конца разобрался, его (этот файл) как-то подключать нужно?


This post was edited by Salador (2015-02-20 13:16, 6 years ago)
Alex300
#11 2015-02-20 14:11

После того как добавили файл salazarp.rc.php плагин переустановили?

Код из этого файла выполняется?

Приходится бежать со всех ног, чтобы только оставаться на месте. А чтобы куда-то попасть, приходится бежать еще быстрее...
...Sorry for my english...
Бесплатные расширения для Cotonti: http://portal30.ru/sozdanie-internet-sajtov/free-scripts/
Salador
#12 2015-02-20 14:43
#40589 Alex300:

После того как добавили файл salazarp.rc.php плагин переустановили?

Код из этого файла выполняется?

Точно, Благодарю. В админке обновил плагин - заработало.

Добавлено 22 часа спустя:

Шаг 10, Хуки

Информация по хукам здесь. Мне нужно добать календарь для Bootscrap, для этого нужно в <head> подключить 1 css и 2 js файла.

Создал файл salazarp.rc.php (по хуку rc информацию не нашел, но так было в другом плагине)

/* ====================
[BEGIN_COT_EXT]
Hooks=rc
[END_COT_EXT]
==================== */

defined('COT_CODE') or die('Wrong URL');

require_once cot_incfile('salazarp', 'plug'); //Подключаем tpl/salazarp.functions.php 

if ($cfg['jquery']) { //Проверка подключения jquery
	cot_rc_add_file(SALAZARP_PLUG . 'js/moment.min.js'); //Добавление файла css или js в <head>
	cot_rc_add_file(SALAZARP_PLUG . 'js/daterangepicker.js');
	cot_rc_add_file(SALAZARP_PLUG . 'tpl/daterangepicker-bs2.css');
	cot_rc_add_file(SALAZARP_PLUG . 'tpl/salazarp.css');
}

Обновляем плагин в админке.

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

Шаг 11, Начисления сотрудникам

Для ввода начислений создал два файла inc/salazarp.mnach.php в файл шаблона tpl/salazarp.mnach.tpl  в нем создал форму:

При выборе даты подключается календарь bootstrap-daterangepicker

Сумма считается как оклад умноженный на ставку и обрабатывается через Jquery, также если внесена сумма, ставка считается автоматически.

Вот самая важная часть шаблона - вывод строки таблицы:

<!-- BEGIN: SOTR_TABLE_MONTH -->
/*Вывод даты и заголовок таблицы*/
<!-- BEGIN: SOTR_ROW -->
<tr>
  <input type="hidden" name="sotrzarp[{SOTR_ID}][sotr_id]" value="{SOTR_ID}">
  <input type="hidden" name="sotrzarp[{SOTR_ID}][datenach]" value="{SOTR_DATE_SQL}">
  <td>{SOTR_NAME}</td>
  <td class="zarpokl">{SOTR_OKLAD}</td>
  <td>{SOTR_DATE}</td>
  <td><input type="text" class="input-mini zarpkoeff" name="sotrzarp[{SOTR_ID}][koeff]" value="{SOTR_STAV}"></td>
  <td><input type="text" class="input-mini zarpvalue" name="sotrzarp[{SOTR_ID}][summa]" value="{SOTR_SUMMA}"></td>
 </tr>
<!-- END: SOTR_ROW -->
/*закрытие таблицы и кнопка сохранить*/
<!-- END: SOTR_TABLE_MONTH -->

Обработка данных из базы данных для вывода в таблицу в файле inc/salazarp.mnach.php

 if (empty($tekDate))  {	
	$tekDate = date("d-m-Y");					   //Если даты нет - ставим сегодняшнюю
 }	
 $tekDateForSql= date("Y-m-d", strtotime($tekDate));   //Преобразование даты в формат для MySQL
 $t_sz->assign('TEK_DATE' , $tekDate);                 //Записываем дату в переменную TEK_DATE для шаблона
 $arr_sotrs = $db->query("SELECT * FROM $table_sotr")->fetchAll();  //Выбираем всех сотрудников
 if(is_array($arr_sotrs)){
	 foreach($arr_sotrs as $sotr) {
		$sotr_zarp = $db->query("SELECT * FROM $table_zarp 
							 WHERE `sotr_id`='$sotr[sotr_id]' 
							 AND `datenach`='$tekDateForSql'
							 AND `nach` = 1")->fetch(); //Ищем начисления на определенную дату для сотрудника
		if (!empty($sotr_zarp)) { 
			$sotr['sotr_stav']=$sotr_zarp['koeff'];
			$sotr['sotr_summa']=$sotr_zarp['summa'];
		} else {
			$sotr['sotr_stav']='0';
			$sotr['sotr_summa']='0';
		}
		 $t_sz->assign(array(
			'SOTR_ID' => $sotr['sotr_id'],
			'SOTR_NAME' => $sotr['sotr_name'],
			'SOTR_OKLAD' => $sotr['sotr_oklad'],
			'SOTR_STAV' => $sotr['sotr_stav'],
			'SOTR_SUMMA' => $sotr['sotr_summa'],
			'SOTR_DATE_SQL' =>  $tekDateForSql,
			'SOTR_DATE' =>  $tekDate
		));
		$t_sz->parse('SOTR_TABLE_MONTH.SOTR_ROW');     //Выполняем парсинг шаблона каждой строки таблицы
	 }
 }
 $plugin_body .= $t_sz->parse('SOTR_TABLE_MONTH')->text('SOTR_TABLE_MONTH');

думал проблемы возникнут с выводм строки таблицы 

$t_sz->parse('SOTR_TABLE_MONTH.SOTR_ROW');     //Выполняем парсинг шаблона каждой строки таблицы

но она заработала безпроблем.

дальше добавил обработку сохранения изменений, в базе сравниваем если уже есть начисление по сотруднику на текущую дату, то его обновляем, если нет и сумма начислений не равна 0, то добавляем.

$tekDate = cot_import('tekdate','P','TXT');    //Получаем дату из формы

// Проверяем если в GET есть параметр 'add' то 
// все данные из POST записываем в масиив $arr_zarp
$par = cot_import('par','G','TXT'); 
if ((!empty($par)) && $par=='add') {	
	$arr_zarp=cot_import('sotrzarp','P','ARR');
	// Обрабатываем каждую строку массива $arr_zarp как $zarp
	// все данные из POST записываем в масиив $arr_zarp
	foreach($arr_zarp as $zarp) {
		$zarp['user_id']=$usr['id'];	//Выбираем id пользователя кто изменил данные 
										//($usr содержит массив данных текущего пользователя)
		$zarp['nach']='1';              // 1- это начисление  0 - выплата 
		$tekDate = date("d-m-Y", strtotime($zarp[datenach]));
		$arr_sotr = $db->query("SELECT * FROM $table_sotr 
						WHERE `sotr_id`='$zarp[sotr_id]'"
						)->fetch(); //Выбираем сотрудника по id для отображения его ФИО
		$t_sz->assign('SOTR_NAME' , $arr_sotr['sotr_name']); // ФИО сотрудника в шаблон

		$sotr_zarp_row = $db->query("SELECT * FROM $table_zarp 
							 WHERE `sotr_id`='$zarp[sotr_id]' 
							 AND `datenach`='$zarp[datenach]'
							 AND `nach` = '1'")->fetch();  //Ищем начисления на определенную дату для сотрудника
	
		//Если начисления есть то обновляем их
		if (!empty($sotr_zarp_row)) {	
			if ($updzarp=$db->update($table_zarp, $zarp, "`sotr_id`='$zarp[sotr_id]' 
											AND `datenach`='$zarp[datenach]' 
											AND `nach` = '1'")) {  
					$plugin_body .= $t_sz->parse('SUC_UPD_SOTR_ZARP')
						->text('SUC_UPD_SOTR_ZARP'); //успешное обновление начислений
			} else {
					$plugin_body .= $t_sz->parse('NOT_UPD_SOTR_ZARP')
						->text('NOT_UPD_SOTR_ZARP'); //неудачное обновление начислений
			}		
		// Если начислений нет и текущие начисления 
		// не равны 0 то добавляем начисление
		} else {
		
			if (($zarp['summa'])!='0') {
				if ($db->insert($table_zarp ,$zarp)) {   
					$plugin_body .= $t_sz->parse('SUC_ADD_SOTR_ZARP')
						->text('SUC_ADD_SOTR_ZARP'); //успешное добавление начислений
				} else {
					$plugin_body .= $t_sz->parse('NOT_ADD_SOTR_ZARP')
						->text('NOT_ADD_SOTR_ZARP'); //неудачное добавление начислений
				}
			}
		}
	}
}	

Этот код вставляем в файле inc/salazarp.mnach.php перед предыдущем.

Добавлено 17 минут спустя:

Шаг 12, Ввод оплаты сотруднику

Вринципе код почти такой же как на предыдущем шаге.

Созданы два файла inc/salazarp.pay.php в файл шаблона tpl/salazarp.pay.tpl в нем создал форму:

Весь код примерно такой же как в на предыдущем шаге только в базе выбираем по `nach` = '0'

Также добавлено вычисление средств которые должны быть выплачены сотруднику

//суммируем в базе все начисления по сотруднику
$sotr_zarp_allnach = $db->query("SELECT SUM(summa) FROM $table_zarp 
							 WHERE `sotr_id`='$sotr[sotr_id]' 
							 AND `nach` = 1")->fetch(); 
//суммируем в базе все выплаты по сотруднику
$sotr_zarp_allvipl = $db->query("SELECT SUM(summa) FROM $table_zarp 
							 WHERE `sotr_id`='$sotr[sotr_id]' 
							 AND `nach` = 0")->fetch(); 
//вычисляем остаток средств которые должны выплатить сотруднику
$sotr_zarp_ost = $sotr_zarp_allnach['SUM(summa)']-$sotr_zarp_allvipl['SUM(summa)'];		

 

Добавлено 3 часа спустя:

Шаг 13, Меню (Хуки):

Вот здесь хуки вроде использовал правильно. 

в файле шаблона /themes/barebones/header.tpl вместо стандартного меню ставим: 

<ul class="nav">
	{MENU_GENERAL}
</ul><!-- /nav -->

Перекрывать будем хук header.tags он отвечает за теги для header. (сначала пробовал перекрывать header.first, но ничего не получилось)

Создаем файл salazarp.header.tags.php и пишем:

/* ====================
[BEGIN_COT_EXT]
Hooks=header.tags 
[END_COT_EXT]
==================== */

defined('COT_CODE') or die('Wrong URL');

require_once cot_incfile('salazarp', 'plug'); //Подключаем tpl/salazarp.functions.php 

//Массив - меню
$arr_menu = Array ( 
	Array ( 
		'tip' => 2,
		'active'=>false,
		'menu_name' => 'Сотрудники',
		'menu_link' => array(
			Array ( 
				'tip' => 1,
				'active'=>false,
				'menu_name' => 'Добавить сотрудника',
				'menu_link' => sala_zap_url('addsotr')
			),
			Array ( 
				'tip' => 1,
				'active'=>false,
				'menu_name' => 'Список сотрудников',
				'menu_link' => sala_zap_url('outsotr')
			)
		)
	),
    Array ( 
		'tip' => 1,
		'active'=>false,
		'menu_name' => 'Начисления',
		'menu_link' => sala_zap_url('mnach')
	),
	Array ( 
		'tip' => 1,
		'active'=>false,
		'menu_name' => 'Оплата',
		'menu_link' => sala_zap_url('pay')
	)
	);

$cfg['menu1']=$arr_menu;

//присвоение MENU_GENERAL текста созданного при помощи 
//шаблона tpl/salazarp.menu.tpl и массива $arr_menu
$t_sz=new XTemplate(cot_tplfile(array('salazarp', 'menu'), 'plug')); 
$text_menu= $t_sz->parse()->text();
$t->assign('MENU_GENERAL',$text_menu);

Посмотрел есть плагин меню для cotonti в шаблоне использовал тэг {MENU_GENERAL} на будующее.

Для шаблона tpl/salazarp.menu.tpl использовалась информация по циклам для шаблонов 

Ниже код если в массиве tip=1 создается простое меню, если  tip=2 то выпадающее. 

<!-- BEGIN: MAIN --> 
	<!-- FOR {VALUE} IN {PHP.cfg.menu1} -->	
		<!-- IF {VALUE.tip} == '1' -->
			<li class="<!-- IF {VALUE.active} == '1' -->active<!-- ENDIF -->">
				<a href="{VALUE.menu_link}">{VALUE.menu_name}</a>
			</li>
		<!-- ENDIF -->
		<!-- IF {VALUE.tip} == '2' -->
			<li class="dropdown">
				<a class="dropdown-toggle <!-- IF {VALUE.active} == '1' -->active<!-- ENDIF -->" data-toggle="dropdown" href="#">
					{VALUE.menu_name}
					<b class="caret"></b>
				</a>
				<ul class="dropdown-menu">
					<!-- FOR {VALUE1} IN {VALUE.menu_link} -->	
						<!-- IF {VALUE1.tip} == '1' -->
							<li class="<!-- IF {VALUE1.active} == '1' -->active<!-- ENDIF -->">
								<a href="{VALUE1.menu_link}">{VALUE1.menu_name}</a>
							</li>
						<!-- ENDIF -->
					<!-- ENDFOR -->
				</ul>
		  </li>
		<!-- ENDIF -->
	<!-- ENDFOR -->
<!-- END: MAIN -->

Вот такое меню получилось:

Вот архив плагина на текущий момент (Скачать).

Что осталось сделать:

  1. Выводить статистику по начислениям и оплатам за месяц (неделю).
  2. Список сотрудников с возможностью уволить, и по нему небудут отображаться начисления.
  3. Чтобы это всё работало только у зарегистрированных пользователей (регистрация должна проходить модерацию).
  4. У незарегистрированных отображалась только форма входа.
  5. Ну и хотелось бы, для обучения в админке плагина добавить какой-нибудь свой параметр.

 

Добавлено 1 день спустя:

Шаг 14. Доступ для зарегистрированных пользователей

Чтобы плагин работал только у зарегистрированных пользователей, нужно просто в админке плагина во вкладке "Права" убрать все галочки у группы Guests.

Чтобы параметры доступа ставились сразу после установки добавляем в файле salazarp.setup.php между строк [BEGIN_COT_EXT]

Auth_guests=
Lock_guests=RWA

Почему-то в шаблоен нет ссылки на регистрацию,  в файл /themes/barebones/login.tpl  добавил строку:

<a href="{USERS_AUTH_REGISTER}" class="btn btn-small">{PHP.L.Register}</a>

Не стал заморачиваться с формой авторизации на главной странице, просто в файл \themes\barebones\index.tpl добавил ссылку:

<a href="{PHP|cot_url('login')}" class="btn btn-primary btn-large">Вход</a>

 


This post was edited by Salador (2015-02-23 01:11, 6 years ago)
Виктор
#13 2016-04-02 06:40

Побольше бы таких тем, сам только начал изучать php, и для практиктики беру cotonti, многое не понятно но вот такие темы очень помогают. Жаль большинство документации на английском с которым не дружу, и вопрос к разработчикам в каком порятке изучать движок чтоб быстрее понять как он работает. Спасибо.

Macik
#14 2016-04-02 13:59

Пошаговых инструкций, возможно не хватает, но ради справедливости замечу, что документация по основным темам (актуальным для новичков) переведена на 70-80%, и это не так мало. 

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

https://github.com/macik
правильный хостинг — https://goo.gl/fjCa1F