workofstan / mycms
MyCMS - 一个用于交互式网站(包括通用管理)的MVC框架。
Requires
- php: ^5.6 || ^7.0
- ext-mbstring: *
- ext-session: *
- godsdev/tools: ^0.3.8
- latte/latte: >=2.4.6 <2.11.3
- nette/utils: ^2.4.8 || ^3.2.2
- tracy/tracy: ^2.4.10
- workofstan/backyard: ^3.4.2
Requires (Dev)
- phpunit/phpunit: ^4 || ^5
- dev-main
- v0.4.10
- v0.4.9
- v0.4.8
- v0.4.7
- v0.4.6
- v0.4.5
- v0.4.4
- v0.4.3
- v0.4.2
- v0.4.1
- v0.4.0
- v0.3.15
- v0.3.14
- v0.3.13
- v0.3.12
- v0.3.11
- v0.3.10
- v0.3.9
- v0.3.8
- v0.3.7
- v0.3.6
- v0.3.5
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.5
- v0.2.4
- v0.2.3
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1
- dev-dependabot/github_actions/overtrue/phplint-9.0.4
- dev-feature/languageSelectorPage
This package is auto-updated.
Last update: 2024-09-03 22:02:14 UTC
README
MyCMS是一个用于交互式网站(包括通用管理)的MVC框架。此框架允许您通过简单的配置创建应用程序,并通过composer保持框架的更新,同时尽可能多地使用纯PHP。它作为一个开发栈,您先安装它,然后编写您项目特定的类。样板项目在dist
文件夹中准备好,可根据需要进行调整,并使用此WorkOfStan\MyCMS
库。
MyCMS设计用于与以下技术一起使用
- jQuery 和 Bootstrap(版本 4):用于展示
- Latte:用于模板
- MySQL/MariaDB:用于数据库后端
- Tracy:用于调试
- Nette\SmartObject:确保严格的PHP规则
- Psr\Log\LoggerInterface:用于日志记录
- WorkOfStan\Backyard\BackyardMysqli:用于封装SQL层
安装
期望Apache模块mod_alias
(用于隐藏非公开文件)和mod_rewrite
(用于友好URL功能)。
一旦安装了composer,请在项目根目录中执行以下命令以安装此库
composer require workofstan/mycms:^0.4.10
大多数库的类使用前缀My
。为了开发您的项目,请在./classes/
目录中创建自己的类,作为MyCMS类的子类,并不要在名称中使用初始的My
。
$MyCMS = new \WorkOfStan\MyCMS\MyCMS( [ // compulsory 'logger' => $logger, // object \Psr\Log\LoggerInterface //optional ] ); //Finish with Latte initialization & Mark-up output $MyCMS->renderLatte(DIR_TEMPLATE_CACHE, "\\vendor\\ProjectName\\Latte\\CustomFilters::common", $params);
文件process.php
和admin-process.php
必须存在,因为它们处理表单。
注意:$MyCMS
名称被ProjectSpecific extends ProjectCommon
类期望(@todo用参数处理替换全局$MyCMS)
部署
/dist
文件夹/dist
包含使用MyCMS的新项目的初始分发文件,因此将其复制到您的新项目文件夹中,以便轻松开始。将字符串MYCMSPROJECTNAMESPACE
替换为您项目的命名空间。(TODO:rector...)将字符串MYCMSPROJECTSPECIFIC
替换为其他网站特定信息(品牌、Twitter地址、电话号码、phinx.yml中的数据库表前缀等)。如果您想使用自己的表名前缀,请在首次运行./build.sh
之前更改与数据库相关的字符串。
要调整内容和结构,请在首次运行构建之前调整迁移content_table和content_example,或者构建后调整数据库内容,或者运行构建,看看它如何工作,然后调整迁移、删除表并再次运行构建。
包含用户和散列密码的表命名为TAB_PREFIX . 'admin'
。
建议根据注释中的建议,将 Contoller.php、FriendlyUrl.php 和 ProjectSpecific.php 类适配到您的需求。关于部署,请查看 dist/README.md 中的《部署》章节和《语言管理》章节。
MyCMS 仅作为库使用,因此使用它的项目应该实现 RedirectMatch 404 vendor\/
语句,如 dist/.htaccess
中准备的那样,以将库隐藏于网络访问之外。
管理员界面
管理员界面由 MyAdmin::outputAdmin 在以下结构中显示
元素概览
导航
- 特殊 Admin::outputSpecialMenuLinks
- 默认:媒体+用户+设置 MyAdmin::outputNavigation
搜索
- 管理员类变量
$searchColumns
定义了一个数组,格式为数据库表 => [id
,要搜索的字段列表],例如:
protected $searchColumns = [ 'product' => ['id', 'name_#', 'content_#'], // "#" will be replaced by current language ];
议程
- MyAdmin::outputAgendas
- 在 admin.php 的 $AGENDAS 中定义
主要
- 消息
- 工作区:以下之一
- $_GET['search'] => MyAdmin::outputSearchResults
- $_GET['table'] => MyAdmin::outputTable -- $_GET['where'] 是数组 => Admin::outputTableBeforeEdit . MyAdmin::tableAdmin->outputForm . Admin::outputTableAfterEdit -- $_POST['edit-selected'] => MyAdmin::outputTableEditSelected(false) -- $_POST['clone-selected'] => MyAdmin::outputTableEditSelected(true) -- 否则 => Admin::outputTableBeforeListing . MyAdmin::tableAdmin->view . Admin::outputTableAfterListing
- $_GET['media'] => MyAdmin::outputMedia 媒体上传等。
- $_GET['user'] => MyAdmin::outputUser 用户操作(注销,更改密码,创建用户,删除用户)
- Admin::projectSpecificSectionsCondition => Admin::projectSpecificSection 特定管理员部分
- 仪表板:表单列表 MyAdmin::outputDashboard
管理员备注
数据库
管理员界面中显示的表列可以使用注释中设置的多种功能
TODO:active=0/1 显示为开关按钮
TODO:更好的解释。
clientSideResources
在 class/Admin.php
中,您可以重新定义 clientSideResources
变量,以加载到管理员中的资源。其默认值是
protected $clientSideResources = [ 'js' => [ 'scripts/jquery.js', 'scripts/popper.js', 'scripts/bootstrap.js', 'scripts/admin.js?v=' . PAGE_RESOURCE_VERSION, ], 'css-pre-admin' => [ 'styles/bootstrap.css', ], 'css' => [ 'styles/font-awesome.css', 'styles/ie10-viewport-bug-workaround.css', 'styles/bootstrap-datetimepicker.css', 'styles/summernote.css', 'styles/admin.css?v=' . PAGE_RESOURCE_VERSION, ] ];
admin.css
可继承到子项目中,然而,由于供应商文件夹应该被浏览器拒绝访问,因此该标准 admin.css
的内容必须通过方法 MyAdmin::getAdminCss
获取。
测试
从命令行运行
./vendor/bin/phpunit
注意,dist
文件夹包含基于 MyCMS 的项目部署和测试运行,因此,为了开发,必须设置 dist
的环境。
注意:从根目录运行 vendor/bin/phpunit
将导致使用根目录的 MyCMS 类,即使是从 mycms/dist/Test
中。而从 dist
运行 vendor/bin/phpunit
将导致使用 dist/vendor/workofstan/mycms/classes
中的 MyCMS 类。
GitHub Actions 的 PHPUnit 版本使用配置文件 phpunit-github-actions.xml,该文件忽略了 Distribution Test Suite
,因为 MySQLi 环境尚未准备好,并且 CLI 环境中无法工作。
重用工作流
由于 dist/.github/workflows 通过 workflow_call 重用了某些 .github/workflows,因此,绝对不能在那里引入任何破坏性更改。重用的工作流可以通过分支、标签或提交引用,并且不支持 语义版本控制。
# Working examples uses: WorkOfStan/MyCMS/.github/workflows/phpcbf.yml@main # ok, but all encompassing uses: WorkOfStan/MyCMS/.github/workflows/phpcbf.yml@v0.4.10 # it works # Failing examples uses: WorkOfStan/MyCMS/.github/workflows/phpcbf.yml@v0.4 uses: WorkOfStan/MyCMS/.github/workflows/phpcbf.yml@^v0.4 uses: WorkOfStan/MyCMS/.github/workflows/phpcbf.yml@^0.4 uses: WorkOfStan/MyCMS/.github/workflows/phpcbf.yml@v0
因此,如果必须引入破坏性更改,请创建另一个用于重用的工作流,而不是更改现有工作流!
PHPStan
由于支持 PHP<7.1,因此 phpstan/phpstan-webmozart-assert
和 rector/rector
不能在 composer.json 中作为 required-dev 依赖项。因此,为了正确考虑 PHPStan(对于 level>6 相关)的 Assert 语句,请执行临时操作(即不将其提交到存储库)
composer require --dev phpstan/phpstan-webmozart-assert --prefer-dist --no-progress composer require --dev rector/rector --prefer-dist --no-progress
并使用 conf/phpstan.webmozart-assert.neon 允许执行 phpstan --configuration=conf/phpstan.webmozart-assert.neon analyse . --memory-limit 300M
。
预置脚本 ./phpstan.sh 和 ./phpstan-remove.sh 可用于启动(或删除)静态分析。(待办:从根目录调用分发脚本以实现DRY。)
控制器内如何实现友好URL
new Controller(['requestUri' => $_SERVER['REQUEST_URI']]) │ // request URI is set in multiple places │ ->requestUri │ ->projectSpecific->requestUri │ ->friendlyUrl->requestUri │ ->friendlyUrl->projectSpecific->requestUri │ ->result['template'] = TEMPLATE_DEFAULT │ └───run() │ └── $controller->MyCMS->template = $this->result['template']; │ │ │ └───$controller->friendlyUrl │ └── ->determineTemplate(['REQUEST_URI' => $this->requestUri]) // returns mixed string with name of the template when template determined, array with redir field when redirect, bool when default template SHOULD be used │ ├── ->friendlyIdentifyRedirect(['REQUEST_URI' => $this->requestUri]) // returns mixed 1) bool (true) or 2) array with redir string field or 3) array with token string field and matches array field (see above) │ │ ├──if $token === self::PAGE_NOT_FOUND │ │ │ └──$this->MyCMS->template = self::TEMPLATE_NOT_FOUND │ <──────── @return true │ ├──FORCE_301 │ │ ├── ->friendlyfyUrl(URL query) // returns string query key of parse_url, e.g var1=12&var2=b │ │ │ └── ->switchParametric(`type`, `value`) // project specific request to database returns mixed null (do not change the output) or string (URL - friendly or parametric) │ │ │ └──If something new calculated, then │ <────────────── @return redirWrapper(URL - friendly or parametric) │ │ └── if !isset($matches[1]) && ($this->language != DEFAULT_LANGUAGE) // no language subpatern and the language isn't default │ <─────────── @return 302 redirWrapper(languageFolder . interestingPath) // interestingPath is part of PATH beyond applicationDir │ ├──REDIRECTOR_ENABLED │ │ └──if old_url == interestingPath (=part of PATH beyond applicationDir) │ <─────────── @return redirWrapper(new_path) │ └──If there are more (non language) folders, the base of relative URLs would be incorrect, therefore │ <──────── @return **redirect** either to a base URL with query parameters or to a 404 Page not found │ <──── @return [token, matches] │ <──── @return array with redir field when redirect || bool when default template SHOULD be used │ │ │ ├──[token, matches] │ ├──loop through $myCmsConf['templateAssignementParametricRules'] and if $this->get[`type`] found: │ <────── @return template || `TEMPLATE_NOT_FOUND` (if invalid `value`) │ │ │ └── ->pureFriendlyUrl(['REQUEST_URI' => $this->requestUri], $token, $matches); //FRIENDLY URL & Redirect calculation where $token, $matches are expected from above │ ├──default scripts and language directories all result into the default template │ <─────────── @return self::TEMPLATE_DEFAULT │ <──── @return self::TEMPLATE_DEFAULT │ │ │ └── ->findFriendlyUrlToken(token) // project specific request to database @return mixed null on empty result, false on database failure or one-dimensional array [id, type] on success │ │ If there is a pure friendly URL, i.e. the token exactly matches a record in content database, decode it internally to type=id │ │ SQL statement searching for $token in url_LL column of table(s) with content pieces addressed by FriendlyURL tokens │ │ Overide the method if the default UNION on tables, where relevant types are stored, isn't sufficient │ │ spoof $this->get[$found['type']] = $this->get['id'] = $found['id'] │ <────────────── @return $this->determineTemplate(['REQUEST_URI' => $this->requestUri]) RECURSION │ <─────────── @return null │ <──── null => @return self::TEMPLATE_NOT_FOUND │ <──── redir or continue with calculated $controller->MyCMS->template
待办
待办管理
- 200314:在 F/classes/Admin::outputSpecialMenuLinks() 和 ::sectionUrls() 中进行 FriendlyURL 管理,将其通用化并启用,如果 FRIENDLY_URL == true
- 200314:在 Admin.php 中添加相应的 FriendlyURL 编辑部分(根据 F 项目),如果可以通用化
- 200526:如果使用 Texy(仅在 MyTableAdmin 中可见
($comment['display'] == 'html' ? ' richtext' : '') . ($comment['display'] == 'texyla' ? ' texyla' : '')
),则描述它。否则从 composer.json、Latte\CustomFilters、ProjectCommon、dist\index.php 中删除。
待办治理
- 190705:在 classes\LogMysqli.php 中进行日志记录
'log/sql' . date("Y-m-d") . '.log.sql');
到当前调用脚本的目录 - 这对API来说并不有利。如何从 APP_ROOT 中获取? - 200526:描述 jQuery 依赖项;以及其他 JS 库(可能在 dist 中?)
- 200529:现在需要 PHP 7.2 或更高版本:最新 PHPUnit + Phinx https://github.com/cakephp/phinx/releases .. 计划在 0.5.0 版本中发布
- 200608:将所有
array(
替换为[
- 200819:将 FORCE_301、FRIENDLY_URL 和 REDIRECTOR_ENABLED 转换为变量,以便可以对所有场景进行 PHPUnit 测试
- 200819:考虑 REQUEST_URI 查询与 _GET 的区别 - 是否应该只使用一个真理来源?
- 200921:对于 PHP/7.1.0+ 版本,在 MyCommon、MyFriendlyUrl、MyAdminProcess.php 中使用 protected 进行 const
待办 UI
- 220716:Admin Translations 和
Urls
模块应通过核心显示标签页(而不是应用程序) - 230309:‘使用门户规则’:‘条款和条件’,‘使用门户规则’:‘Terms & Bedingungen’不应显示为 & - 要么在 inc-footer.latte 中没有 noescape 过滤器,要么更改
L10n::translate return Tools::h($text);
待办 安全性
- 190723:如果同一域名下有两个不同的 MyCMS 实例,那么即使用户不存在,通过登录到 admin.php 也会登录到所有实例
- 220513,Latte::2.11.3 警告:Engine::addFilter(null, ...) 已弃用,从 ^2.10.8 开始使用 addFilterLoader(),它需要 php: >=7.1 <8.2(停止限制 "latte/latte": ">=2.4.6 <2.11.3")