first commit
This commit is contained in:
commit
a5a45e92ae
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# IDE & System Related Files
|
||||
.idea
|
||||
|
||||
# Local System File
|
||||
config.php
|
||||
php.ini
|
||||
|
||||
# Vendor directory handling
|
||||
/libraries/vendor
|
52
.htaccess
Normal file
52
.htaccess
Normal file
@ -0,0 +1,52 @@
|
||||
###########################################
|
||||
# ======= Enable the Rewrite Engine =======
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======= No directory listings =======
|
||||
|
||||
IndexIgnore *
|
||||
Options +FollowSymLinks
|
||||
Options -Indexes
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======== Remove multiple slashes ========
|
||||
|
||||
RewriteCond %{HTTP_HOST} !=""
|
||||
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
|
||||
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
|
||||
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======== Remove trailing slashes ========
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)/$ /$1 [R=301,L]
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======== SEF URL Routing ========
|
||||
|
||||
# If the request is not for a static asset
|
||||
RewriteCond %{REQUEST_URI} !^/media/
|
||||
|
||||
# Or for a file that exists in the web directory
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
# Rewrite the request to run the application
|
||||
RewriteRule (.*) index.php
|
||||
|
||||
###########################################
|
340
LICENSE
Normal file
340
LICENSE
Normal file
@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
63
README.md
Normal file
63
README.md
Normal file
@ -0,0 +1,63 @@
|
||||
# Content Management System
|
||||
|
||||
Content Management of Pages in the Kumwe CMS
|
||||
|
||||
# Tutorial
|
||||
|
||||
[![](https://git.vdm.dev/Kumwe/cms/raw/branch/master/media/images/tutorial_thumb.jpg "View Tutorial")](https://www.youtube.com/watch?v=43_V9OxUAdE)
|
||||
|
||||
## To install this CMS
|
||||
|
||||
1. Import the SQL tables into your database found in /sql/install.sql
|
||||
2. Copy the /config.php.example file to /config.php
|
||||
3. Update the /config.php to reflect your CMS details
|
||||
4. Copy the /htaccess.txt file to /.htaccess
|
||||
5. **Remove** the /installation folder from you root directory
|
||||
|
||||
## To install all composer libraries
|
||||
|
||||
0. Make sure you have [composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos) installed on your system.
|
||||
1. In your terminal go to the root folder of your Kumwe website where you will find the composer.json file.
|
||||
2. Run the following command `composer install` to install all PHP packages.
|
||||
|
||||
## To create an account
|
||||
|
||||
1. Open [hostname:]/administrator
|
||||
2. Click on link that says [Create Account] __FIRST account will get admin access, but there rest created will need admin approval__
|
||||
3. Fill in your details [done]
|
||||
|
||||
## To login to admin/staff area again
|
||||
|
||||
1. Open [hostname:]/administrator
|
||||
2. Add you username and password
|
||||
3. Click login [done]
|
||||
|
||||
## To add Items
|
||||
|
||||
> Items get linked to menus and are the text of your pages
|
||||
|
||||
1. Login to [hostname:]/administrator
|
||||
2. Click on items menu [hostname:]/administrator/index.php/items
|
||||
3. Here you can update, delete and create items
|
||||
|
||||
## To add menus
|
||||
|
||||
> Menus link to items, and mange the menus of your site
|
||||
|
||||
1. Login to [hostname:]/administrator
|
||||
2. Click on menus menu [hostname:]/administrator/index.php/menus
|
||||
3. Here you can update, delete and create menus (pages) that link to items
|
||||
|
||||
## To set site home page
|
||||
|
||||
> Home page is the first page you see when you open your public website
|
||||
|
||||
1. Inside the menu edit/create view [hostname:]/administrator/index.php/menu
|
||||
2. You can select one to be the home page
|
||||
|
||||
# Just for fun... ((ewɘ))yn
|
||||
|
||||
### License & Copyright
|
||||
- Written by [Llewellyn van der Merwe](https://github.com/Llewellynvdm), March 2022
|
||||
- Copyright (C) 2022. All Rights Reserved
|
||||
- License [GNU/GPL Version 2](http://www.gnu.org/licenses/gpl-2.0.html)
|
BIN
administrator/favicon.ico
Normal file
BIN
administrator/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
100
administrator/includes/app.php
Normal file
100
administrator/includes/app.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// Option to override defines from root folder
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L15
|
||||
if (file_exists(dirname(__DIR__) . '/defines.php'))
|
||||
{
|
||||
include_once dirname(__DIR__) . '/defines.php';
|
||||
}
|
||||
|
||||
// Load the default defines
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L20
|
||||
if (!defined('_LDEFINES'))
|
||||
{
|
||||
define('LPATH_BASE', dirname(__DIR__));
|
||||
require_once LPATH_BASE . '/includes/defines.php';
|
||||
}
|
||||
|
||||
// Check for presence of vendor dependencies not included in the git repository
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L26
|
||||
if (!file_exists(LPATH_LIBRARIES . '/vendor/autoload.php'))
|
||||
{
|
||||
echo file_get_contents(LPATH_ROOT . '/templates/system/build_incomplete.html');
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// Load configuration (or install)
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L34
|
||||
require_once LPATH_BASE . '/includes/framework.php';
|
||||
|
||||
// Wrap in a try/catch so we can display an error if need be
|
||||
try
|
||||
{
|
||||
$container = (new Joomla\DI\Container)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\ConfigurationProvider(LPATH_CONFIGURATION . '/config.php'))
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\SessionProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\UserProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\InputProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\AdminApplicationProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\AdminRouterProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\AdminMVCProvider)
|
||||
->registerServiceProvider(new Joomla\Database\Service\DatabaseProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\EventProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\HttpProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\LoggingProvider)
|
||||
->registerServiceProvider(new Joomla\Preload\Service\PreloadProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\AdminTemplatingProvider);
|
||||
|
||||
// Alias the web application to Kumwe's base application class as this is the primary application for the environment
|
||||
$container->alias(Joomla\Application\AbstractApplication::class, Joomla\Application\AbstractWebApplication::class);
|
||||
|
||||
// Alias the web logger to the PSR-3 interface as this is the primary logger for the environment
|
||||
$container->alias(Monolog\Logger::class, 'monolog.logger.application.web')
|
||||
->alias(Psr\Log\LoggerInterface::class, 'monolog.logger.application.web');
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
error_log($e);
|
||||
|
||||
header('HTTP/1.1 500 Internal Server Error', null, 500);
|
||||
echo '<html><head><title>Container Initialization Error</title></head><body><h1>Container Initialization Error</h1><p>An error occurred while creating the DI container: ' . $e->getMessage() . '</p></body></html>';
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Execute the application
|
||||
// source: https://github.com/joomla/framework.joomla.org/blob/master/www/index.php#L85
|
||||
try
|
||||
{
|
||||
$app = $container->get(Joomla\Application\AbstractApplication::class);
|
||||
// Set the application as global app
|
||||
\Kumwe\CMS\Factory::$application = $app;
|
||||
// Execute the application.
|
||||
$app->execute();
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
error_log($e);
|
||||
|
||||
if (!headers_sent())
|
||||
{
|
||||
header('HTTP/1.1 500 Internal Server Error', null, 500);
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
}
|
||||
|
||||
echo '<html><head><title>Application Error</title></head><body><h1>Application Error</h1><p>An error occurred while executing the application: ' . $e->getMessage() . '</p></body></html>';
|
||||
|
||||
exit(1);
|
||||
}
|
||||
// I am just playing around... ((ewɘ))yn purring
|
24
administrator/includes/defines.php
Normal file
24
administrator/includes/defines.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// Global definitions
|
||||
$parts = explode(DIRECTORY_SEPARATOR, LPATH_BASE);
|
||||
array_pop($parts);
|
||||
|
||||
// Defines.
|
||||
define('LPATH_ROOT', implode(DIRECTORY_SEPARATOR, $parts));
|
||||
define('LPATH_SITE', LPATH_ROOT);
|
||||
define('LPATH_CONFIGURATION', LPATH_ROOT);
|
||||
define('LPATH_ADMINISTRATOR', LPATH_ROOT . DIRECTORY_SEPARATOR . 'administrator');
|
||||
define('LPATH_LIBRARIES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'libraries');
|
||||
define('LPATH_INSTALLATION', LPATH_ROOT . DIRECTORY_SEPARATOR . 'installation');
|
||||
define('LPATH_TEMPLATES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'templates/admin');
|
35
administrator/includes/framework.php
Normal file
35
administrator/includes/framework.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// System includes
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/framework.php#L14
|
||||
require_once LPATH_LIBRARIES . '/bootstrap.php';
|
||||
|
||||
// Installation check, and check on removal of the installation directory.
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/framework.php#L17
|
||||
if (!file_exists(LPATH_CONFIGURATION . '/config.php')
|
||||
|| (filesize(LPATH_CONFIGURATION . '/config.php') < 10)
|
||||
|| (file_exists(LPATH_INSTALLATION . '/index.php')))
|
||||
{
|
||||
if (file_exists(LPATH_INSTALLATION . '/index.php'))
|
||||
{
|
||||
header('Location: ../installation/index.php');
|
||||
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo 'No configuration file found and no installation code available. Exiting...';
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
1
administrator/includes/index.html
Normal file
1
administrator/includes/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><title></title>
|
35
administrator/index.php
Normal file
35
administrator/index.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 3rd April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// NOTE: This file should remain compatible with PHP 5.2 to allow us to run our PHP minimum check and show a friendly error message
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/index.php#L9
|
||||
|
||||
// Define the application's minimum supported PHP version as a constant, so it can be referenced within the application.
|
||||
define('KUMWE_MINIMUM_PHP', '7.2.5');
|
||||
|
||||
if (version_compare(PHP_VERSION, KUMWE_MINIMUM_PHP, '<'))
|
||||
{
|
||||
die(
|
||||
str_replace(
|
||||
'{{phpversion}}',
|
||||
KUMWE_MINIMUM_PHP,
|
||||
file_get_contents(dirname(__FILE__) . '/../templates/system/incompatible.html')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant that is checked in included files to prevent direct access.
|
||||
*/
|
||||
define('_LEXEC', 1);
|
||||
|
||||
// We must setup some house rules, since we can't have all
|
||||
// this code just doing what it wants can we.... <<eWɘ>>yn growling
|
||||
require_once dirname(__FILE__) . '/includes/app.php';
|
1
administrator/media/css/index.html
Normal file
1
administrator/media/css/index.html
Normal file
@ -0,0 +1 @@
|
||||
<html><body bgcolor="#FFFFFF"></body></html>
|
0
administrator/media/css/template.css
Normal file
0
administrator/media/css/template.css
Normal file
1
administrator/media/index.html
Normal file
1
administrator/media/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><title></title>
|
1
administrator/media/js/index.html
Normal file
1
administrator/media/js/index.html
Normal file
@ -0,0 +1 @@
|
||||
<html><body bgcolor="#FFFFFF"></body></html>
|
0
administrator/media/js/template.js
Normal file
0
administrator/media/js/template.js
Normal file
1
administrator/media/mix-manifest.json
Normal file
1
administrator/media/mix-manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
1
administrator/media/sri-manifest.json
Normal file
1
administrator/media/sri-manifest.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
72
composer.json
Normal file
72
composer.json
Normal file
@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "kumwe/cms",
|
||||
"type": "project",
|
||||
"description": "Kumwe CMS",
|
||||
"keywords": [
|
||||
"kumwe",
|
||||
"cms"
|
||||
],
|
||||
"homepage": "https://github.com/Kumwe/cms",
|
||||
"license": "GPL-2.0",
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"platform": {
|
||||
"php": "7.2.5"
|
||||
},
|
||||
"vendor-dir": "libraries/vendor",
|
||||
"github-protocols": ["https"],
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kumwe\\CMS\\": "libraries/src/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"ext-json": "*",
|
||||
"joomla/application": "~2.0",
|
||||
"joomla/archive": "~2.0",
|
||||
"joomla/authentication": "~2.0",
|
||||
"joomla/console": "~2.0",
|
||||
"joomla/controller": "~2.0",
|
||||
"joomla/crypt": "~2.0",
|
||||
"joomla/data": "~2.0",
|
||||
"joomla/database": "~2.0",
|
||||
"joomla/di": "~2.0",
|
||||
"joomla/event": "~2.0",
|
||||
"joomla/filter": "~2.0",
|
||||
"joomla/filesystem": "~2.0",
|
||||
"joomla/http": "~2.0",
|
||||
"joomla/input": "~2.0",
|
||||
"joomla/model": "~2.0",
|
||||
"joomla/preload": "~2.0",
|
||||
"joomla/ldap": "~2.0",
|
||||
"joomla/oauth1": "~2.0",
|
||||
"joomla/oauth2": "~2.0",
|
||||
"joomla/registry": "~2.0",
|
||||
"joomla/renderer": "~2.0",
|
||||
"joomla/router": "~2.0",
|
||||
"joomla/session": "~2.0",
|
||||
"joomla/string": "~2.0",
|
||||
"joomla/uri": "~2.0",
|
||||
"joomla/utilities": "~2.0",
|
||||
"algo26-matthias/idna-convert": "~3.0",
|
||||
"joomla/view": "~2.0",
|
||||
"laminas/laminas-diactoros": "^2.3",
|
||||
"monolog/monolog": "^2.1",
|
||||
"psr/link": "^1.0",
|
||||
"ramsey/uuid": "^4.0.1",
|
||||
"robmorgan/phinx": "^0.12.3",
|
||||
"defuse/php-encryption": "^2.0",
|
||||
"symfony/asset": "^5.1.2",
|
||||
"symfony/process": "^5.1.2",
|
||||
"symfony/web-link": "^5.1.2",
|
||||
"symfony/yaml": "^5.1.2",
|
||||
"theiconic/php-ga-measurement-protocol": "^2.7.2",
|
||||
"twig/twig": "^2.13",
|
||||
"phpmailer/phpmailer": "~6.0"
|
||||
}
|
||||
}
|
5398
composer.lock
generated
Normal file
5398
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
95
config.php.example
Normal file
95
config.php.example
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
* -------------------------------------------------------------------------
|
||||
* THIS SHOULD ONLY BE USED AS A LAST RESORT WHEN THE WEB INSTALLER FAILS
|
||||
*
|
||||
* If you are installing Kumwe! manually ie not using the web browser installer
|
||||
* then rename this file to config.php eg
|
||||
*
|
||||
* UNIX -> mv config.php.example config.php
|
||||
* Windows -> rename config.php.example config.php
|
||||
*
|
||||
* Now edit this file and configure the parameters for your site and
|
||||
* database.
|
||||
*
|
||||
* Finally move this file to the root folder of your Kumwe installation eg
|
||||
*
|
||||
* UNIX -> mv config.php ../
|
||||
* Windows -> copy config.php ../
|
||||
*
|
||||
* SOURCE: https://github.com/joomla/joomla-cms/blob/4.1-dev/installation/configuration.php-dist
|
||||
*
|
||||
*/
|
||||
class LConfig
|
||||
{
|
||||
public $sitename = 'Kumwe!'; // Name of Kumwe site
|
||||
|
||||
/* Database Settings */
|
||||
public $dbtype = 'mysqli'; // Normally mysqli
|
||||
public $host = 'localhost'; // This is normally set to localhost
|
||||
public $user = ''; // Database username
|
||||
public $password = ''; // Database password
|
||||
public $db = ''; // Database name
|
||||
public $dbprefix = 'kumwe_'; // LEAVE THIS UNCHANGED FOR NOW
|
||||
public $dbencryption = 0;
|
||||
public $dbsslverifyservercert = false;
|
||||
public $dbsslkey = '';
|
||||
public $dbsslcert = '';
|
||||
public $dbsslca = '';
|
||||
public $dbsslcipher = '';
|
||||
|
||||
/* Server Settings */
|
||||
public $secret = 'EiT9pmiqMycmQ6xx'; // Use something very secure. For example on linux the following command `cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-16} | head -n 1`
|
||||
public $helpurl = 'https://help.kumwe.net/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}';
|
||||
public $tmp_path = '/tmp'; // This path needs to be writable by Kumwe!
|
||||
|
||||
/* Locale Settings */
|
||||
public $offset = 'UTC';
|
||||
|
||||
/* Session settings */
|
||||
public $lifetime = 15; // Session time
|
||||
public $session_handler = 'database';
|
||||
public $session_filesystem_path = '';
|
||||
public $session_memcached_server_host = 'localhost';
|
||||
public $session_memcached_server_port = 11211;
|
||||
public $session_metadata = true;
|
||||
public $session_redis_persist = 1;
|
||||
public $session_redis_server_auth = '';
|
||||
public $session_redis_server_db = 0;
|
||||
public $session_redis_server_host = 'localhost';
|
||||
public $session_redis_server_port = 6379;
|
||||
|
||||
/* Mail Settings */
|
||||
public $mailonline = true;
|
||||
public $mailer = 'mail';
|
||||
public $mailfrom = '';
|
||||
public $fromname = '';
|
||||
public $massmailoff = false;
|
||||
public $replyto = '';
|
||||
public $replytoname = '';
|
||||
public $sendmail = '/usr/sbin/sendmail';
|
||||
public $smtpauth = false;
|
||||
public $smtpuser = '';
|
||||
public $smtppass = '';
|
||||
public $smtphost = 'localhost';
|
||||
public $smtpsecure = 'none';
|
||||
public $smtpport = 25;
|
||||
|
||||
/* Meta Settings */
|
||||
public $MetaDesc = 'Kumwe! - the dynamic portal engine and content management system';
|
||||
public $MetaAuthor = true;
|
||||
public $MetaVersion = false;
|
||||
public $MetaRights = '';
|
||||
public $robots = '';
|
||||
public $sitename_pagetitles = 0;
|
||||
|
||||
/* Cookie Settings */
|
||||
public $cookie_domain = '';
|
||||
public $cookie_path = '';
|
||||
}
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
52
htaccess.txt
Normal file
52
htaccess.txt
Normal file
@ -0,0 +1,52 @@
|
||||
###########################################
|
||||
# ======= Enable the Rewrite Engine =======
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======= No directory listings =======
|
||||
|
||||
IndexIgnore *
|
||||
Options +FollowSymLinks
|
||||
Options -Indexes
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======== Remove multiple slashes ========
|
||||
|
||||
RewriteCond %{HTTP_HOST} !=""
|
||||
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$ [OR]
|
||||
RewriteCond %{THE_REQUEST} ^[A-Z]+\s(.*/)/+\sHTTP/[0-9.]+$
|
||||
RewriteRule .* http://%{HTTP_HOST}/%1 [R=301,L]
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======== Remove trailing slashes ========
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)/$ /$1 [R=301,L]
|
||||
|
||||
###########################################
|
||||
|
||||
|
||||
###########################################
|
||||
# ======== SEF URL Routing ========
|
||||
|
||||
# If the request is not for a static asset
|
||||
RewriteCond %{REQUEST_URI} !^/media/
|
||||
|
||||
# Or for a file that exists in the web directory
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
# Rewrite the request to run the application
|
||||
RewriteRule (.*) index.php
|
||||
|
||||
###########################################
|
96
includes/app.php
Normal file
96
includes/app.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// Option to override defines from root folder
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L15
|
||||
if (file_exists(dirname(__DIR__) . '/defines.php'))
|
||||
{
|
||||
include_once dirname(__DIR__) . '/defines.php';
|
||||
}
|
||||
|
||||
// Load the default defines
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L20
|
||||
if (!defined('_LDEFINES'))
|
||||
{
|
||||
define('LPATH_BASE', dirname(__DIR__));
|
||||
require_once LPATH_BASE . '/includes/defines.php';
|
||||
}
|
||||
|
||||
// Check for presence of vendor dependencies not included in the git repository
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L26
|
||||
if (!file_exists(LPATH_LIBRARIES . '/vendor/autoload.php'))
|
||||
{
|
||||
echo file_get_contents(LPATH_ROOT . '/templates/system/build_incomplete.html');
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// Load configuration (or install)
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L34
|
||||
require_once LPATH_BASE . '/includes/framework.php';
|
||||
|
||||
// Wrap in a try/catch so we can display an error if need be
|
||||
try
|
||||
{
|
||||
$container = (new Joomla\DI\Container)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\SiteApplicationProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\ConfigurationProvider(LPATH_CONFIGURATION . '/config.php'))
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\InputProvider)
|
||||
->registerServiceProvider(new Joomla\Database\Service\DatabaseProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\EventProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\HttpProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\LoggingProvider)
|
||||
->registerServiceProvider(new Joomla\Preload\Service\PreloadProvider)
|
||||
->registerServiceProvider(new Kumwe\CMS\Service\SiteTemplatingProvider);
|
||||
|
||||
// Alias the web application to Kumwe's base application class as this is the primary application for the environment
|
||||
$container->alias(Joomla\Application\AbstractApplication::class, Joomla\Application\AbstractWebApplication::class);
|
||||
|
||||
// Alias the web logger to the PSR-3 interface as this is the primary logger for the environment
|
||||
$container->alias(Monolog\Logger::class, 'monolog.logger.application.web')
|
||||
->alias(Psr\Log\LoggerInterface::class, 'monolog.logger.application.web');
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
error_log($e);
|
||||
|
||||
header('HTTP/1.1 500 Internal Server Error', null, 500);
|
||||
echo '<html><head><title>Container Initialization Error</title></head><body><h1>Container Initialization Error</h1><p>An error occurred while creating the DI container: ' . $e->getMessage() . '</p></body></html>';
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Execute the application
|
||||
// source: https://github.com/joomla/framework.joomla.org/blob/master/www/index.php#L85
|
||||
try
|
||||
{
|
||||
$app = $container->get(Joomla\Application\AbstractApplication::class);
|
||||
// Set the application as global app
|
||||
\Kumwe\CMS\Factory::$application = $app;
|
||||
// Execute the application.
|
||||
$app->execute();
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
error_log($e);
|
||||
|
||||
if (!headers_sent())
|
||||
{
|
||||
header('HTTP/1.1 500 Internal Server Error', null, 500);
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
}
|
||||
|
||||
echo '<html><head><title>Application Error</title></head><body><h1>Application Error</h1><p>An error occurred while executing the application: ' . $e->getMessage() . '</p></body></html>';
|
||||
|
||||
exit(1);
|
||||
}
|
||||
// I am just playing around... ((ewɘ))yn purring
|
23
includes/defines.php
Normal file
23
includes/defines.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// Global definitions
|
||||
$parts = explode(DIRECTORY_SEPARATOR, LPATH_BASE);
|
||||
|
||||
// Defines.
|
||||
define('LPATH_ROOT', implode(DIRECTORY_SEPARATOR, $parts));
|
||||
define('LPATH_SITE', LPATH_ROOT);
|
||||
define('LPATH_CONFIGURATION', LPATH_ROOT);
|
||||
define('LPATH_ADMINISTRATOR', LPATH_ROOT . DIRECTORY_SEPARATOR . 'administrator');
|
||||
define('LPATH_LIBRARIES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'libraries');
|
||||
define('LPATH_INSTALLATION', LPATH_ROOT . DIRECTORY_SEPARATOR . 'installation');
|
||||
define('LPATH_TEMPLATES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'templates/site');
|
35
includes/framework.php
Normal file
35
includes/framework.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// System includes
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/framework.php#L14
|
||||
require_once LPATH_LIBRARIES . '/bootstrap.php';
|
||||
|
||||
// Installation check, and check on removal of the installation directory.
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/framework.php#L17
|
||||
if (!file_exists(LPATH_CONFIGURATION . '/config.php')
|
||||
|| (filesize(LPATH_CONFIGURATION . '/config.php') < 10)
|
||||
|| (file_exists(LPATH_INSTALLATION . '/index.php')))
|
||||
{
|
||||
if (file_exists(LPATH_INSTALLATION . '/index.php'))
|
||||
{
|
||||
header('Location: ' . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], 'index.php')) . 'installation/index.php');
|
||||
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo 'No configuration file found and no installation code available. Exiting...';
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
1
includes/index.html
Normal file
1
includes/index.html
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><title></title>
|
35
index.php
Normal file
35
index.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 3rd April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// NOTE: This file should remain compatible with PHP 5.2 to allow us to run our PHP minimum check and show a friendly error message
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/index.php#L9
|
||||
|
||||
// Define the application's minimum supported PHP version as a constant, so it can be referenced within the application.
|
||||
define('KUMWE_MINIMUM_PHP', '7.2.5');
|
||||
|
||||
if (version_compare(PHP_VERSION, KUMWE_MINIMUM_PHP, '<'))
|
||||
{
|
||||
die(
|
||||
str_replace(
|
||||
'{{phpversion}}',
|
||||
KUMWE_MINIMUM_PHP,
|
||||
file_get_contents(dirname(__FILE__) . '/templates/system/incompatible.html')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant that is checked in included files to prevent direct access.
|
||||
*/
|
||||
define('_LEXEC', 1);
|
||||
|
||||
// We must setup some house rules, since we can't have all
|
||||
// this code just doing what it wants can we?... <<eWɘ>>yn growling
|
||||
require_once dirname(__FILE__) . '/includes/app.php';
|
31
installation/includes/app.php
Normal file
31
installation/includes/app.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// Option to override defines from root folder
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L15
|
||||
if (file_exists(dirname(__DIR__) . '/defines.php'))
|
||||
{
|
||||
include_once dirname(__DIR__) . '/defines.php';
|
||||
}
|
||||
|
||||
// Load the default defines
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/includes/app.php#L20
|
||||
if (!defined('_LDEFINES'))
|
||||
{
|
||||
define('LPATH_BASE', dirname(__DIR__));
|
||||
require_once LPATH_BASE . '/includes/defines.php';
|
||||
}
|
||||
|
||||
// I have not yet had time to finish this part of the application (CMS)
|
||||
echo file_get_contents(LPATH_ROOT . '/templates/system/install_notice.html');
|
||||
|
||||
exit;
|
23
installation/includes/defines.php
Normal file
23
installation/includes/defines.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// Global definitions
|
||||
$parts = explode(DIRECTORY_SEPARATOR, LPATH_BASE);
|
||||
array_pop($parts);
|
||||
|
||||
// Defines.
|
||||
define('LPATH_ROOT', implode(DIRECTORY_SEPARATOR, $parts));
|
||||
define('LPATH_SITE', LPATH_ROOT);
|
||||
define('LPATH_CONFIGURATION', LPATH_ROOT);
|
||||
define('LPATH_ADMINISTRATOR', LPATH_ROOT . DIRECTORY_SEPARATOR . 'administrator');
|
||||
define('LPATH_LIBRARIES', LPATH_ROOT . DIRECTORY_SEPARATOR . 'libraries');
|
||||
define('LPATH_INSTALLATION', LPATH_ROOT . DIRECTORY_SEPARATOR . 'installation');
|
41
installation/includes/framework.php
Normal file
41
installation/includes/framework.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// System includes
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/administrator/includes/framework.php#L14
|
||||
require_once LPATH_LIBRARIES . '/bootstrap.php';
|
||||
|
||||
// Installation check, and check on removal of the installation directory.
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/administrator/includes/framework.php#L17
|
||||
if (!file_exists(LPATH_CONFIGURATION . '/config.php')
|
||||
|| (filesize(LPATH_CONFIGURATION . '/config.php') < 10)
|
||||
|| (file_exists(LPATH_INSTALLATION . '/index.php')))
|
||||
{
|
||||
if (file_exists(LPATH_INSTALLATION . '/index.php'))
|
||||
{
|
||||
header('Location: ../installation/index.php');
|
||||
|
||||
exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo 'No configuration file found and no installation code available. Exiting...';
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-Load configuration. Don't remove the Output Buffering due to BOM issues.
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/administrator/includes/framework.php#L36
|
||||
ob_start();
|
||||
require_once LPATH_CONFIGURATION . '/config.php';
|
||||
ob_end_clean();
|
35
installation/index.php
Normal file
35
installation/index.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// NOTE: This file should remain compatible with PHP 5.2 to allow us to run our PHP minimum check and show a friendly error message
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/index.php#L9
|
||||
|
||||
// Define the application's minimum supported PHP version as a constant, so it can be referenced within the application.
|
||||
define('KUMWE_MINIMUM_PHP', '7.2.5');
|
||||
|
||||
if (version_compare(PHP_VERSION, KUMWE_MINIMUM_PHP, '<'))
|
||||
{
|
||||
die(
|
||||
str_replace(
|
||||
'{{phpversion}}',
|
||||
KUMWE_MINIMUM_PHP,
|
||||
file_get_contents(dirname(__FILE__) . '/../templates/system/incompatible.html')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant that is checked in included files to prevent direct access.
|
||||
*/
|
||||
define('_LEXEC', 1);
|
||||
|
||||
// We must setup some house rules, since we can't have all
|
||||
// this code just doing what it wants can we.... <<eWɘ>>yn growling
|
||||
require_once dirname(__FILE__) . '/includes/app.php';
|
9
libraries/.htaccess
Normal file
9
libraries/.htaccess
Normal file
@ -0,0 +1,9 @@
|
||||
# Apache 2.4+
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
|
||||
# Apache 2.0-2.2
|
||||
<IfModule !mod_authz_core.c>
|
||||
Deny from all
|
||||
</IfModule>
|
48
libraries/bootstrap.php
Normal file
48
libraries/bootstrap.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_LEXEC') or die;
|
||||
|
||||
// Set the platform root path as a constant if necessary.
|
||||
// source: https://github.com/joomla/joomla-cms/blob/4.1-dev/libraries/bootstrap.php#L12
|
||||
defined('LPATH_PLATFORM') or define('LPATH_PLATFORM', __DIR__);
|
||||
|
||||
// Detect the native operating system type.
|
||||
$os = strtoupper(substr(PHP_OS, 0, 3));
|
||||
|
||||
defined('IS_WIN') or define('IS_WIN', ($os === 'WIN'));
|
||||
defined('IS_UNIX') or define('IS_UNIX', (($os !== 'MAC') && ($os !== 'WIN')));
|
||||
|
||||
// Import the library loader if necessary.
|
||||
if (!class_exists('LLoader'))
|
||||
{
|
||||
require_once LPATH_PLATFORM . '/loader.php';
|
||||
|
||||
// If JLoader still does not exist panic.
|
||||
if (!class_exists('LLoader'))
|
||||
{
|
||||
throw new RuntimeException('Kumwe Platform not loaded.');
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the autoloaders.
|
||||
LLoader::setup();
|
||||
|
||||
// Create the Composer autoloader
|
||||
/** @var \Composer\Autoload\ClassLoader $loader */
|
||||
$loader = require LPATH_LIBRARIES . '/vendor/autoload.php';
|
||||
|
||||
// We need to pull our decorated class loader into memory before unregistering Composer's loader
|
||||
class_exists('\\Kumwe\\CMS\\Autoload\\ClassLoader');
|
||||
|
||||
$loader->unregister();
|
||||
|
||||
// Decorate Composer autoloader
|
||||
spl_autoload_register([new \Kumwe\CMS\Autoload\ClassLoader($loader), 'loadClass'], true, true);
|
599
libraries/loader.php
Normal file
599
libraries/loader.php
Normal file
@ -0,0 +1,599 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* Joomla! Content Management System
|
||||
*
|
||||
* @source https://github.com/joomla/joomla-cms/blob/4.1-dev/libraries/loader.php
|
||||
* @adapted Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
*
|
||||
* @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
**/
|
||||
|
||||
defined('LPATH_PLATFORM') or die;
|
||||
|
||||
/**
|
||||
* Static class to handle loading of libraries.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
abstract class LLoader
|
||||
{
|
||||
/**
|
||||
* Container for already imported library paths.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.7.0
|
||||
*/
|
||||
protected static $classes = array();
|
||||
|
||||
/**
|
||||
* Container for already imported library paths.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.7.0
|
||||
*/
|
||||
protected static $imported = array();
|
||||
|
||||
/**
|
||||
* Container for registered library class prefixes and path lookups.
|
||||
*
|
||||
* @var array
|
||||
* @since 3.0.0
|
||||
*/
|
||||
protected static $prefixes = array();
|
||||
|
||||
/**
|
||||
* Holds proxy classes and the class names the proxy.
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2
|
||||
*/
|
||||
protected static $classAliases = array();
|
||||
|
||||
/**
|
||||
* Holds the inverse lookup for proxy classes and the class names the proxy.
|
||||
*
|
||||
* @var array
|
||||
* @since 3.4
|
||||
*/
|
||||
protected static $classAliasesInverse = array();
|
||||
|
||||
/**
|
||||
* Container for namespace => path map.
|
||||
*
|
||||
* @var array
|
||||
* @since 3.1.4
|
||||
*/
|
||||
protected static $namespaces = array();
|
||||
|
||||
/**
|
||||
* Holds a reference for all deprecated aliases (mainly for use by a logging platform).
|
||||
*
|
||||
* @var array
|
||||
* @since 3.6.3
|
||||
*/
|
||||
protected static $deprecatedAliases = array();
|
||||
|
||||
/**
|
||||
* The root folders where extensions can be found.
|
||||
*
|
||||
* @var array
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected static $extensionRootFolders = array();
|
||||
|
||||
/**
|
||||
* Method to get the list of registered classes and their respective file paths for the autoloader.
|
||||
*
|
||||
* @return array The array of class => path values for the autoloader.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static function getClassList()
|
||||
{
|
||||
return self::$classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the list of deprecated class aliases.
|
||||
*
|
||||
* @return array An associative array with deprecated class alias data.
|
||||
*
|
||||
* @since 3.6.3
|
||||
*/
|
||||
public static function getDeprecatedAliases()
|
||||
{
|
||||
return self::$deprecatedAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the list of registered namespaces.
|
||||
*
|
||||
* @return array The array of namespace => path values for the autoloader.
|
||||
*
|
||||
* @since 3.1.4
|
||||
*/
|
||||
public static function getNamespaces()
|
||||
{
|
||||
return self::$namespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the file for a class.
|
||||
*
|
||||
* @param string $class The class to be loaded.
|
||||
*
|
||||
* @return boolean True on success
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static function load($class)
|
||||
{
|
||||
// Sanitize class name.
|
||||
$key = strtolower($class);
|
||||
|
||||
// If the class already exists do nothing.
|
||||
if (class_exists($class, false))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the class is registered include the file.
|
||||
if (isset(self::$classes[$key]))
|
||||
{
|
||||
$found = (bool) include_once self::$classes[$key];
|
||||
|
||||
if ($found)
|
||||
{
|
||||
self::loadAliasFor($class);
|
||||
}
|
||||
|
||||
// If the class doesn't exists, we probably have a class alias available
|
||||
if (!class_exists($class, false))
|
||||
{
|
||||
// Search the alias class, first none namespaced and then namespaced
|
||||
$original = array_search($class, self::$classAliases) ? : array_search('\\' . $class, self::$classAliases);
|
||||
|
||||
// When we have an original and the class exists an alias should be created
|
||||
if ($original && class_exists($original, false))
|
||||
{
|
||||
class_alias($original, $class);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a class prefix with lookup path. This will allow developers to register library
|
||||
* packages with different class prefixes to the system autoloader. More than one lookup path
|
||||
* may be registered for the same class prefix, but if this method is called with the reset flag
|
||||
* set to true then any registered lookups for the given prefix will be overwritten with the current
|
||||
* lookup path. When loaded, prefix paths are searched in a "last in, first out" order.
|
||||
*
|
||||
* @param string $prefix The class prefix to register.
|
||||
* @param string $path Absolute file path to the library root where classes with the given prefix can be found.
|
||||
* @param boolean $reset True to reset the prefix with only the given lookup path.
|
||||
* @param boolean $prepend If true, push the path to the beginning of the prefix lookup paths array.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function registerPrefix($prefix, $path, $reset = false, $prepend = false)
|
||||
{
|
||||
// Verify the library path exists.
|
||||
if (!is_dir($path))
|
||||
{
|
||||
$path = (str_replace(LPATH_ROOT, '', $path) == $path) ? basename($path) : str_replace(LPATH_ROOT, '', $path);
|
||||
|
||||
throw new RuntimeException('Library path ' . $path . ' cannot be found.', 500);
|
||||
}
|
||||
|
||||
// If the prefix is not yet registered or we have an explicit reset flag then set set the path.
|
||||
if ($reset || !isset(self::$prefixes[$prefix]))
|
||||
{
|
||||
self::$prefixes[$prefix] = array($path);
|
||||
}
|
||||
// Otherwise we want to simply add the path to the prefix.
|
||||
else
|
||||
{
|
||||
if ($prepend)
|
||||
{
|
||||
array_unshift(self::$prefixes[$prefix], $path);
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$prefixes[$prefix][] = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Offers the ability for "just in time" usage of `class_alias()`.
|
||||
* You cannot overwrite an existing alias.
|
||||
*
|
||||
* @param string $alias The alias name to register.
|
||||
* @param string $original The original class to alias.
|
||||
* @param string|boolean $version The version in which the alias will no longer be present.
|
||||
*
|
||||
* @return boolean True if registration was successful. False if the alias already exists.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function registerAlias($alias, $original, $version = false)
|
||||
{
|
||||
// PHP is case insensitive so support all kind of alias combination
|
||||
$lowercasedAlias = strtolower($alias);
|
||||
|
||||
if (!isset(self::$classAliases[$lowercasedAlias]))
|
||||
{
|
||||
self::$classAliases[$lowercasedAlias] = $original;
|
||||
|
||||
$original = self::stripFirstBackslash($original);
|
||||
|
||||
if (!isset(self::$classAliasesInverse[$original]))
|
||||
{
|
||||
self::$classAliasesInverse[$original] = array($lowercasedAlias);
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$classAliasesInverse[$original][] = $lowercasedAlias;
|
||||
}
|
||||
|
||||
// If given a version, log this alias as deprecated
|
||||
if ($version)
|
||||
{
|
||||
self::$deprecatedAliases[] = array('old' => $alias, 'new' => $original, 'version' => $version);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a namespace to the autoloader. When loaded, namespace paths are searched in a "last in, first out" order.
|
||||
*
|
||||
* @param string $namespace A case sensitive Namespace to register.
|
||||
* @param string $path A case sensitive absolute file path to the library root where classes of the given namespace can be found.
|
||||
* @param boolean $reset True to reset the namespace with only the given lookup path.
|
||||
* @param boolean $prepend If true, push the path to the beginning of the namespace lookup paths array.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @since 3.1.4
|
||||
*/
|
||||
public static function registerNamespace($namespace, $path, $reset = false, $prepend = false)
|
||||
{
|
||||
// Verify the library path exists.
|
||||
if (!is_dir($path))
|
||||
{
|
||||
$path = (str_replace(LPATH_ROOT, '', $path) == $path) ? basename($path) : str_replace(LPATH_ROOT, '', $path);
|
||||
|
||||
throw new RuntimeException('Library path ' . $path . ' cannot be found.', 500);
|
||||
}
|
||||
|
||||
// Trim leading and trailing backslashes from namespace, allowing "\Parent\Child", "Parent\Child\" and "\Parent\Child\" to be treated the same way.
|
||||
$namespace = trim($namespace, '\\');
|
||||
|
||||
// If the namespace is not yet registered or we have an explicit reset flag then set the path.
|
||||
if ($reset || !isset(self::$namespaces[$namespace]))
|
||||
{
|
||||
self::$namespaces[$namespace] = array($path);
|
||||
}
|
||||
|
||||
// Otherwise we want to simply add the path to the namespace.
|
||||
else
|
||||
{
|
||||
if ($prepend)
|
||||
{
|
||||
array_unshift(self::$namespaces[$namespace], $path);
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$namespaces[$namespace][] = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to setup the autoloaders for the Kumwe Platform.
|
||||
* Since the SPL autoloaders are called in a queue we will add our explicit
|
||||
* class-registration based loader first, then fall back on the autoloader based on conventions.
|
||||
* This will allow people to register a class in a specific location and override platform libraries
|
||||
* as was previously possible.
|
||||
*
|
||||
* @param boolean $enablePsr True to enable autoloading based on PSR-0.
|
||||
* @param boolean $enablePrefixes True to enable prefix based class loading (needed to auto load the Kumwe core).
|
||||
* @param boolean $enableClasses True to enable class map based class loading (needed to auto load the Kumwe core).
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.1.4
|
||||
*/
|
||||
public static function setup($enablePsr = true, $enablePrefixes = true, $enableClasses = true)
|
||||
{
|
||||
if ($enableClasses)
|
||||
{
|
||||
// Register the class map based autoloader.
|
||||
spl_autoload_register(array('LLoader', 'load'));
|
||||
}
|
||||
|
||||
if ($enablePrefixes)
|
||||
{
|
||||
// Register the prefix autoloader.
|
||||
spl_autoload_register(array('LLoader', '_autoload'));
|
||||
}
|
||||
|
||||
if ($enablePsr)
|
||||
{
|
||||
// Register the PSR based autoloader.
|
||||
spl_autoload_register(array('LLoader', 'loadByPsr'));
|
||||
spl_autoload_register(array('LLoader', 'loadByAlias'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to autoload classes that are namespaced to the PSR-4 standard.
|
||||
*
|
||||
* @param string $class The fully qualified class name to autoload.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @deprecated 5.0 Use LLoader::loadByPsr instead
|
||||
*/
|
||||
public static function loadByPsr4($class)
|
||||
{
|
||||
return self::loadByPsr($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to autoload classes that are namespaced to the PSR-4 standard.
|
||||
*
|
||||
* @param string $class The fully qualified class name to autoload.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static function loadByPsr($class)
|
||||
{
|
||||
$class = self::stripFirstBackslash($class);
|
||||
|
||||
// Find the location of the last NS separator.
|
||||
$pos = strrpos($class, '\\');
|
||||
|
||||
// If one is found, we're dealing with a NS'd class.
|
||||
if ($pos !== false)
|
||||
{
|
||||
$classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR;
|
||||
$className = substr($class, $pos + 1);
|
||||
}
|
||||
// If not, no need to parse path.
|
||||
else
|
||||
{
|
||||
$classPath = null;
|
||||
$className = $class;
|
||||
}
|
||||
|
||||
$classPath .= $className . '.php';
|
||||
|
||||
// Loop through registered namespaces until we find a match.
|
||||
foreach (self::$namespaces as $ns => $paths)
|
||||
{
|
||||
if (strpos($class, "{$ns}\\") === 0)
|
||||
{
|
||||
$nsPath = trim(str_replace('\\', DIRECTORY_SEPARATOR, $ns), DIRECTORY_SEPARATOR);
|
||||
|
||||
// Loop through paths registered to this namespace until we find a match.
|
||||
foreach ($paths as $path)
|
||||
{
|
||||
$classFilePath = realpath($path . DIRECTORY_SEPARATOR . substr_replace($classPath, '', 0, strlen($nsPath) + 1));
|
||||
|
||||
// We do not allow files outside the namespace root to be loaded
|
||||
if (strpos($classFilePath, realpath($path)) !== 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// We check for class_exists to handle case-sensitive file systems
|
||||
if (is_file($classFilePath) && !class_exists($class, false))
|
||||
{
|
||||
$found = (bool) include_once $classFilePath;
|
||||
|
||||
if ($found)
|
||||
{
|
||||
self::loadAliasFor($class);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to autoload classes that have been aliased using the registerAlias method.
|
||||
*
|
||||
* @param string $class The fully qualified class name to autoload.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function loadByAlias($class)
|
||||
{
|
||||
$class = strtolower(self::stripFirstBackslash($class));
|
||||
|
||||
if (isset(self::$classAliases[$class]))
|
||||
{
|
||||
// Force auto-load of the regular class
|
||||
class_exists(self::$classAliases[$class], true);
|
||||
|
||||
// Normally this shouldn't execute as the autoloader will execute applyAliasFor when the regular class is
|
||||
// auto-loaded above.
|
||||
if (!class_exists($class, false) && !interface_exists($class, false))
|
||||
{
|
||||
class_alias(self::$classAliases[$class], $class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a class alias for an already loaded class, if a class alias was created for it.
|
||||
*
|
||||
* @param string $class We'll look for and register aliases for this (real) class name
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public static function applyAliasFor($class)
|
||||
{
|
||||
$class = self::stripFirstBackslash($class);
|
||||
|
||||
if (isset(self::$classAliasesInverse[$class]))
|
||||
{
|
||||
foreach (self::$classAliasesInverse[$class] as $alias)
|
||||
{
|
||||
class_alias($class, $alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload a class based on name.
|
||||
*
|
||||
* @param string $class The class to be loaded.
|
||||
*
|
||||
* @return boolean True if the class was loaded, false otherwise.
|
||||
*
|
||||
* @since 1.7.3
|
||||
*/
|
||||
public static function _autoload($class)
|
||||
{
|
||||
foreach (self::$prefixes as $prefix => $lookup)
|
||||
{
|
||||
$chr = strlen($prefix) < strlen($class) ? $class[strlen($prefix)] : 0;
|
||||
|
||||
if (strpos($class, $prefix) === 0 && ($chr === strtoupper($chr)))
|
||||
{
|
||||
return self::_load(substr($class, strlen($prefix)), $lookup);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a class based on name and lookup array.
|
||||
*
|
||||
* @param string $class The class to be loaded (without prefix).
|
||||
* @param array $lookup The array of base paths to use for finding the class file.
|
||||
*
|
||||
* @return boolean True if the class was loaded, false otherwise.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
private static function _load($class, $lookup)
|
||||
{
|
||||
// Split the class name into parts separated by camelCase.
|
||||
$parts = preg_split('/(?<=[a-z0-9])(?=[A-Z])/x', $class);
|
||||
$partsCount = count($parts);
|
||||
|
||||
foreach ($lookup as $base)
|
||||
{
|
||||
// Generate the path based on the class name parts.
|
||||
$path = realpath($base . '/' . implode('/', array_map('strtolower', $parts)) . '.php');
|
||||
|
||||
// Load the file if it exists and is in the lookup path.
|
||||
if (strpos($path, realpath($base)) === 0 && is_file($path))
|
||||
{
|
||||
$found = (bool) include_once $path;
|
||||
|
||||
if ($found)
|
||||
{
|
||||
self::loadAliasFor($class);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
// Backwards compatibility patch
|
||||
|
||||
// If there is only one part we want to duplicate that part for generating the path.
|
||||
if ($partsCount === 1)
|
||||
{
|
||||
// Generate the path based on the class name parts.
|
||||
$path = realpath($base . '/' . implode('/', array_map('strtolower', array($parts[0], $parts[0]))) . '.php');
|
||||
|
||||
// Load the file if it exists and is in the lookup path.
|
||||
if (strpos($path, realpath($base)) === 0 && is_file($path))
|
||||
{
|
||||
$found = (bool) include_once $path;
|
||||
|
||||
if ($found)
|
||||
{
|
||||
self::loadAliasFor($class);
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the aliases for the given class.
|
||||
*
|
||||
* @param string $class The class.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.8.0
|
||||
*/
|
||||
private static function loadAliasFor($class)
|
||||
{
|
||||
if (!array_key_exists($class, self::$classAliasesInverse))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (self::$classAliasesInverse[$class] as $alias)
|
||||
{
|
||||
// Force auto-load of the alias class
|
||||
class_exists($alias, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the first backslash from the given class if present.
|
||||
*
|
||||
* @param string $class The class to strip the first prefix from.
|
||||
*
|
||||
* @return string The striped class name.
|
||||
*
|
||||
* @since 3.8.0
|
||||
*/
|
||||
private static function stripFirstBackslash($class)
|
||||
{
|
||||
return $class && $class[0] === '\\' ? substr($class, 1) : $class;
|
||||
}
|
||||
}
|
90
libraries/src/Application/AdminApplication.php
Normal file
90
libraries/src/Application/AdminApplication.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Application;
|
||||
|
||||
use Joomla\Application\AbstractWebApplication;
|
||||
use Joomla\Application\Controller\ControllerResolverInterface;
|
||||
use Joomla\Application\SessionAwareWebApplicationInterface;
|
||||
use Joomla\Application\SessionAwareWebApplicationTrait;
|
||||
use Joomla\Application\Web\WebClient;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Router\RouterInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Site application class
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/WebApplication.php
|
||||
*/
|
||||
class AdminApplication extends AbstractWebApplication implements SessionAwareWebApplicationInterface, SessionMessageAwareInterface, IdentityAwareInterface
|
||||
{
|
||||
use IdentityAwareTrait, SessionMessageAwareTrait, SessionAwareWebApplicationTrait;
|
||||
|
||||
/**
|
||||
* The application's controller resolver.
|
||||
*
|
||||
* @var ControllerResolverInterface
|
||||
*/
|
||||
protected $controllerResolver;
|
||||
|
||||
/**
|
||||
* The application's router.
|
||||
*
|
||||
* @var RouterInterface
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param ControllerResolverInterface $controllerResolver The application's controller resolver
|
||||
* @param RouterInterface $router The application's router
|
||||
* @param Input $input An optional argument to provide dependency injection for the application's
|
||||
* input object.
|
||||
* @param Registry $config An optional argument to provide dependency injection for the application's
|
||||
* config object.
|
||||
* @param WebClient $client An optional argument to provide dependency injection for the application's
|
||||
* client object.
|
||||
* @param ResponseInterface $response An optional argument to provide dependency injection for the application's
|
||||
* response object.
|
||||
*/
|
||||
public function __construct(
|
||||
ControllerResolverInterface $controllerResolver,
|
||||
RouterInterface $router,
|
||||
Input $input = null,
|
||||
Registry $config = null,
|
||||
WebClient $client = null,
|
||||
ResponseInterface $response = null
|
||||
)
|
||||
{
|
||||
$this->controllerResolver = $controllerResolver;
|
||||
$this->router = $router;
|
||||
|
||||
// Call the constructor as late as possible (it runs `initialise`).
|
||||
parent::__construct($input, $config, $client, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to run the application routines.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(): void
|
||||
{
|
||||
$route = $this->router->parseRoute($this->get('uri.route'), $this->input->getMethod());
|
||||
|
||||
// Add variables to the input if not already set
|
||||
foreach ($route->getRouteVariables() as $key => $value)
|
||||
{
|
||||
$this->input->def($key, $value);
|
||||
}
|
||||
|
||||
\call_user_func($this->controllerResolver->resolve($route));
|
||||
}
|
||||
}
|
57
libraries/src/Application/IdentityAwareInterface.php
Normal file
57
libraries/src/Application/IdentityAwareInterface.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Application;
|
||||
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
|
||||
interface IdentityAwareInterface
|
||||
{
|
||||
/**
|
||||
* Get the application identity.
|
||||
*
|
||||
* @return User
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getIdentity(): User;
|
||||
|
||||
/**
|
||||
* Allows the application to load a custom or default identity.
|
||||
*
|
||||
* @param User $identity An optional identity object. If omitted, a null user object is created.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function loadIdentity(User $identity = null): IdentityAwareInterface;
|
||||
|
||||
/**
|
||||
* Set the user factory to use.
|
||||
*
|
||||
* @param UserFactoryInterface $userFactory The user factory to use
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function setUserFactory(UserFactoryInterface $userFactory);
|
||||
|
||||
/**
|
||||
* Get the user factory to use.
|
||||
*
|
||||
* @return UserFactoryInterface
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getUserFactory(): UserFactoryInterface;
|
||||
}
|
91
libraries/src/Application/IdentityAwareTrait.php
Normal file
91
libraries/src/Application/IdentityAwareTrait.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Content Management System
|
||||
*
|
||||
* @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Application;
|
||||
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
|
||||
/**
|
||||
* Trait for application classes which are identity (user) aware
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait IdentityAwareTrait
|
||||
{
|
||||
/**
|
||||
* The application identity object.
|
||||
*
|
||||
* @var User
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected $identity;
|
||||
|
||||
/**
|
||||
* UserFactoryInterface
|
||||
*
|
||||
* @var UserFactoryInterface
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private $userFactory;
|
||||
|
||||
/**
|
||||
* Get the application identity.
|
||||
*
|
||||
* @return User
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getIdentity(): User
|
||||
{
|
||||
return $this->identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the application to load a custom or default identity.
|
||||
*
|
||||
* @param User $identity An optional identity object. If omitted, a null user object is created.
|
||||
*
|
||||
* @return IdentityAwareInterface
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function loadIdentity(User $identity = null): IdentityAwareInterface
|
||||
{
|
||||
$this->identity = $identity ?: $this->userFactory->loadUserById(0);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user factory to use.
|
||||
*
|
||||
* @param UserFactoryInterface $userFactory The user factory to use
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function setUserFactory(UserFactoryInterface $userFactory)
|
||||
{
|
||||
$this->userFactory = $userFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user factory to use.
|
||||
*
|
||||
* @return UserFactoryInterface
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getUserFactory(): UserFactoryInterface
|
||||
{
|
||||
return $this->userFactory;
|
||||
}
|
||||
}
|
||||
|
44
libraries/src/Application/SessionMessageAwareInterface.php
Normal file
44
libraries/src/Application/SessionMessageAwareInterface.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Application;
|
||||
|
||||
/**
|
||||
* Application Session Message Aware Interface
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface SessionMessageAwareInterface
|
||||
{
|
||||
const MSG_INFO = 'info';
|
||||
|
||||
/**
|
||||
* Enqueue a system message.
|
||||
*
|
||||
* @param string $msg The message to enqueue.
|
||||
* @param string $type The message type. Default is message.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function enqueueMessage(string $msg, string $type = self::MSG_INFO);
|
||||
|
||||
/**
|
||||
* Get the system message queue.
|
||||
*
|
||||
* @param boolean $clear Clear the messages currently attached to the application object
|
||||
*
|
||||
* @return array The system message queue.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function getMessageQueue(bool $clear = false): array;
|
||||
}
|
88
libraries/src/Application/SessionMessageAwareTrait.php
Normal file
88
libraries/src/Application/SessionMessageAwareTrait.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Application;
|
||||
|
||||
use Joomla\Filter\InputFilter as InputFilterAlias;
|
||||
use Kumwe\CMS\Filter\InputFilter;
|
||||
|
||||
/**
|
||||
* Trait for application classes which are identity (user) aware
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait SessionMessageAwareTrait
|
||||
{
|
||||
/**
|
||||
* Enqueue a system message.
|
||||
*
|
||||
* @param string $msg The message to enqueue.
|
||||
* @param string $type The message type. Default is message.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function enqueueMessage(string $msg, string $type = self::MSG_INFO)
|
||||
{
|
||||
// Don't add empty messages.
|
||||
if ($msg === null || trim($msg) === '')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$inputFilter = InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilterAlias::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilterAlias::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
);
|
||||
|
||||
// Build the message array and apply the HTML InputFilter with the default blacklist to the message
|
||||
$message = array(
|
||||
'message' => $inputFilter->clean($msg, 'html'),
|
||||
'type' => $inputFilter->clean(strtolower($type), 'cmd'),
|
||||
);
|
||||
|
||||
// For empty queue, if messages exists in the session, enqueue them first.
|
||||
$messages = $this->getMessageQueue();
|
||||
|
||||
if (!\in_array($message, $messages))
|
||||
{
|
||||
// Enqueue the message.
|
||||
$messages[] = $message;
|
||||
|
||||
// update the session
|
||||
$this->getSession()->set('application.queue', $messages);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system message queue.
|
||||
*
|
||||
* @param boolean $clear Clear the messages currently attached to the application object
|
||||
*
|
||||
* @return array The system message queue.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getMessageQueue(bool $clear = false): array
|
||||
{
|
||||
// Get messages from Session
|
||||
$sessionQueue = $this->getSession()->get('application.queue', []);
|
||||
|
||||
if ($clear)
|
||||
{
|
||||
$this->getSession()->set('application.queue', []);
|
||||
}
|
||||
|
||||
return $sessionQueue;
|
||||
}
|
||||
}
|
86
libraries/src/Application/SiteApplication.php
Normal file
86
libraries/src/Application/SiteApplication.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Application;
|
||||
|
||||
use Joomla\Application\AbstractWebApplication;
|
||||
use Joomla\Application\Controller\ControllerResolverInterface;
|
||||
use Joomla\Application\Web\WebClient;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\Router\RouterInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Site application class
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/WebApplication.php
|
||||
*/
|
||||
class SiteApplication extends AbstractWebApplication
|
||||
{
|
||||
/**
|
||||
* The application's controller resolver.
|
||||
*
|
||||
* @var ControllerResolverInterface
|
||||
*/
|
||||
protected $controllerResolver;
|
||||
|
||||
/**
|
||||
* The application's router.
|
||||
*
|
||||
* @var RouterInterface
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param ControllerResolverInterface $controllerResolver The application's controller resolver
|
||||
* @param RouterInterface $router The application's router
|
||||
* @param Input $input An optional argument to provide dependency injection for the application's
|
||||
* input object.
|
||||
* @param Registry $config An optional argument to provide dependency injection for the application's
|
||||
* config object.
|
||||
* @param WebClient $client An optional argument to provide dependency injection for the application's
|
||||
* client object.
|
||||
* @param ResponseInterface $response An optional argument to provide dependency injection for the application's
|
||||
* response object.
|
||||
*/
|
||||
public function __construct(
|
||||
ControllerResolverInterface $controllerResolver,
|
||||
RouterInterface $router,
|
||||
Input $input = null,
|
||||
Registry $config = null,
|
||||
WebClient $client = null,
|
||||
ResponseInterface $response = null
|
||||
)
|
||||
{
|
||||
$this->controllerResolver = $controllerResolver;
|
||||
$this->router = $router;
|
||||
|
||||
// Call the constructor as late as possible (it runs `initialise`).
|
||||
parent::__construct($input, $config, $client, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to run the application routines.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function doExecute(): void
|
||||
{
|
||||
$route = $this->router->parseRoute($this->get('uri.route'), $this->input->getMethod());
|
||||
|
||||
// Add variables to the input if not already set
|
||||
foreach ($route->getRouteVariables() as $key => $value)
|
||||
{
|
||||
$this->input->def($key, $value);
|
||||
}
|
||||
|
||||
\call_user_func($this->controllerResolver->resolve($route));
|
||||
}
|
||||
}
|
71
libraries/src/Asset/MixPathPackage.php
Normal file
71
libraries/src/Asset/MixPathPackage.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Asset;
|
||||
|
||||
use Symfony\Component\Asset\Context\ContextInterface;
|
||||
use Symfony\Component\Asset\Package;
|
||||
use Symfony\Component\Asset\PathPackage;
|
||||
use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;
|
||||
|
||||
/**
|
||||
* Extended path package for resolving assets from a Laravel Mix manifest
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Asset/MixPathPackage.php
|
||||
*/
|
||||
class MixPathPackage extends PathPackage
|
||||
{
|
||||
/**
|
||||
* Decorated Package instance
|
||||
*
|
||||
* @var Package
|
||||
*/
|
||||
private $decoratedPackage;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Package $decoratedPackage Decorated Package instance
|
||||
* @param string $basePath The base path to be prepended to relative paths
|
||||
* @param VersionStrategyInterface $versionStrategy The version strategy
|
||||
* @param ContextInterface $context The context
|
||||
*/
|
||||
public function __construct(
|
||||
Package $decoratedPackage,
|
||||
string $basePath,
|
||||
VersionStrategyInterface $versionStrategy,
|
||||
ContextInterface $context = null
|
||||
) {
|
||||
parent::__construct($basePath, $versionStrategy, $context);
|
||||
|
||||
$this->decoratedPackage = $decoratedPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an absolute or root-relative public path.
|
||||
*
|
||||
* @param string $path A path
|
||||
*
|
||||
* @return string The public path
|
||||
*/
|
||||
public function getUrl($path)
|
||||
{
|
||||
if ($this->isAbsoluteUrl($path))
|
||||
{
|
||||
return $path;
|
||||
}
|
||||
|
||||
$versionedPath = $this->getVersionStrategy()->applyVersion("/$path");
|
||||
|
||||
if ($versionedPath === $path)
|
||||
{
|
||||
return $this->decoratedPackage->getUrl($path);
|
||||
}
|
||||
|
||||
return $this->getBasePath() . ltrim($versionedPath, '/');
|
||||
}
|
||||
}
|
63
libraries/src/Autoload/ClassLoader.php
Normal file
63
libraries/src/Autoload/ClassLoader.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Content Management System
|
||||
*
|
||||
* @copyright (C) 2014 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Autoload;
|
||||
|
||||
\defined('_LEXEC') or die;
|
||||
|
||||
use Composer\Autoload\ClassLoader as ComposerClassLoader;
|
||||
|
||||
/**
|
||||
* Decorate Composer ClassLoader for Kumwe!
|
||||
*
|
||||
* For backward compatibility due to class aliasing in the CMS, the loadClass() method was modified to call
|
||||
* the LLoader::applyAliasFor() method.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/**
|
||||
* The Composer class loader
|
||||
*
|
||||
* @var ComposerClassLoader
|
||||
* @since 3.4
|
||||
*/
|
||||
private $loader;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ComposerClassLoader $loader Composer autoloader
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public function __construct(ComposerClassLoader $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return boolean|null True if loaded, null otherwise
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($result = $this->loader->loadClass($class))
|
||||
{
|
||||
\LLoader::applyAliasFor($class);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
91
libraries/src/Controller/DashboardController.php
Normal file
91
libraries/src/Controller/DashboardController.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Uri\Uri;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\View\Admin\DashboardHtmlView;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class DashboardController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var DashboardHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param DashboardHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
*/
|
||||
public function __construct(DashboardHtmlView $view, Input $input = null, AbstractApplication $app = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$task = $this->getInput()->getString('task', '');
|
||||
$id = $this->getInput()->getInt('id', 0);
|
||||
|
||||
$this->view->setActiveDashboard($task);
|
||||
$this->view->setActiveId($id);
|
||||
|
||||
// validate form token
|
||||
if ('access' === $task || 'signup' === $task)
|
||||
{
|
||||
$this->checkToken();
|
||||
}
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow($task))
|
||||
{
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// go to set page
|
||||
$this->_redirect();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
272
libraries/src/Controller/ItemController.php
Normal file
272
libraries/src/Controller/ItemController.php
Normal file
@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Filter\InputFilter as InputFilterAlias;
|
||||
use Joomla\Input\Input;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Date\Date;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\Filter\InputFilter;
|
||||
use Kumwe\CMS\Model\ItemModel;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\ItemHtmlView;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class ItemController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var ItemHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* The model object.
|
||||
*
|
||||
* @var ItemModel
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* @var InputFilter
|
||||
*/
|
||||
private $inputFilter;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ItemModel $model The model object.
|
||||
* @param ItemHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
* @param User|null $user
|
||||
*/
|
||||
public function __construct(
|
||||
ItemModel $model,
|
||||
$view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->model = $model;
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
$this->inputFilter = InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilterAlias::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilterAlias::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$method = $this->getInput()->getMethod();
|
||||
$task = $this->getInput()->getString('task', '');
|
||||
$id = $this->getInput()->getInt('id', 0);
|
||||
|
||||
// if task is delete
|
||||
if ('delete' === $task)
|
||||
{
|
||||
// check that the user does not delete him/her self
|
||||
if ($this->allow('item') && $this->user->get('access.item.delete', false))
|
||||
{
|
||||
if ($id > 0 && $this->model->linked($id))
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('This item is still linked to a menu, first remove it from the menu.', 'error');
|
||||
}
|
||||
elseif ($id > 0 && $this->model->delete($id))
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('Item was deleted!', 'success');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('Item could not be deleted!', 'error');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to delete this item!', 'error');
|
||||
}
|
||||
// go to set page
|
||||
$this->_redirect('items');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('POST' === $method)
|
||||
{
|
||||
// check permissions
|
||||
$update = ($id > 0 && $this->user->get('access.item.update', false));
|
||||
$create = ($id == 0 && $this->user->get('access.item.create', false));
|
||||
|
||||
if ( $create || $update )
|
||||
{
|
||||
$id = $this->setItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating item
|
||||
if ($id == 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create items!', 'error');
|
||||
}
|
||||
// not allowed updating item
|
||||
if ($id > 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to update the item details!', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check permissions
|
||||
$read = ($id > 0 && $this->user->get('access.item.read', false));
|
||||
$create = ($id == 0 && $this->user->get('access.item.create', false));
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('item') && ( $read || $create ))
|
||||
{
|
||||
// set values for view
|
||||
$this->view->setActiveId($id);
|
||||
$this->view->setActiveView('item');
|
||||
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating item
|
||||
if ($id == 0 && !$create)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create items!', 'error');
|
||||
}
|
||||
// not allowed read item
|
||||
if ($id > 0 && !$read)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to read the item details!', 'error');
|
||||
}
|
||||
|
||||
// go to set page
|
||||
$this->_redirect('items');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an item
|
||||
*
|
||||
*
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setItem(): int
|
||||
{
|
||||
// always check the post token
|
||||
$this->checkToken();
|
||||
// get the post
|
||||
$post = $this->getInput()->getInputForRequestMethod();
|
||||
|
||||
// we get all the needed items
|
||||
$tempItem = [];
|
||||
$tempItem['id'] = $post->getInt('item_id', 0);
|
||||
$tempItem['title'] = $post->getString('title', '');
|
||||
$tempItem['fulltext'] = $this->inputFilter->clean($post->getRaw('fulltext', ''), 'html');
|
||||
$tempItem['created_by_alias'] = $post->getString('created_by_alias', '');
|
||||
$tempItem['state'] = $post->getInt('state', 1);
|
||||
$tempItem['metakey'] = $post->getString('metakey', '');
|
||||
$tempItem['metadesc'] = $post->getString('metadesc', '');
|
||||
$tempItem['metadata'] = $post->getString('metadata', '');
|
||||
$tempItem['publish_up'] = $post->getString('publish_up', '');
|
||||
$tempItem['publish_down'] = $post->getString('publish_down', '');
|
||||
$tempItem['featured'] = $post->getInt('featured', 0);
|
||||
|
||||
// check that we have a Title
|
||||
$can_save = true;
|
||||
if (empty($tempItem['title']))
|
||||
{
|
||||
// we show a warning message
|
||||
$tempItem['title'] = '';
|
||||
$this->getApplication()->enqueueMessage('Title field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
// we actually can also not continue if we don't have content
|
||||
if (empty($tempItem['fulltext']))
|
||||
{
|
||||
// we show a warning message
|
||||
$tempItem['fulltext'] = '';
|
||||
$this->getApplication()->enqueueMessage('Content field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
// can we save the item
|
||||
if ($can_save)
|
||||
{
|
||||
/** @var \Kumwe\CMS\User\User $user */
|
||||
$user = Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
|
||||
$user_id = (int) $user->get('id', 0);
|
||||
$today = (new Date())->toSql();
|
||||
|
||||
return $this->model->setItem(
|
||||
$tempItem['id'],
|
||||
$tempItem['title'],
|
||||
$tempItem['fulltext'],
|
||||
$tempItem['state'],
|
||||
$today,
|
||||
$user_id,
|
||||
$tempItem['created_by_alias'],
|
||||
$today,
|
||||
$user_id,
|
||||
$tempItem['publish_up'],
|
||||
$tempItem['publish_down'],
|
||||
$tempItem['metakey'],
|
||||
$tempItem['metadesc'],
|
||||
$tempItem['metadata'],
|
||||
$tempItem['featured']);
|
||||
}
|
||||
|
||||
// add to model the post values
|
||||
$this->model->tempItem = $tempItem;
|
||||
|
||||
return $tempItem['id'];
|
||||
}
|
||||
}
|
94
libraries/src/Controller/ItemsController.php
Normal file
94
libraries/src/Controller/ItemsController.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\ItemsHtmlView;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class ItemsController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var ItemsHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ItemsHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
* @param User|null $user
|
||||
*/
|
||||
public function __construct(
|
||||
ItemsHtmlView $view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$this->view->setActiveView('items');
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('items') && $this->user->get('access.item.read', false))
|
||||
{
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// go to set page
|
||||
$this->_redirect();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
95
libraries/src/Controller/LoginController.php
Normal file
95
libraries/src/Controller/LoginController.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Renderer\RendererInterface;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
use Kumwe\CMS\View\Admin\DashboardHtmlView;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\SiteApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\SiteApplication $app Application object
|
||||
*/
|
||||
class LoginController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* The template renderer.
|
||||
*
|
||||
* @var RendererInterface
|
||||
*/
|
||||
private $renderer;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var DashboardHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param DashboardHtmlView $view The view object.
|
||||
* @param RendererInterface $renderer The template renderer.
|
||||
* @param Input $input The input object.
|
||||
* @param AbstractApplication $app The application object.
|
||||
*/
|
||||
public function __construct(DashboardHtmlView $view, RendererInterface $renderer, Input $input = null, AbstractApplication $app = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->view = $view;
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$task = $this->getInput()->getString('account', null);
|
||||
|
||||
/** @var \Kumwe\CMS\Application\AdminApplication $app */
|
||||
$app = $this->getApplication();
|
||||
|
||||
/** @var \Kumwe\CMS\User\UserFactory $userFactory */
|
||||
$userFactory = $app->getUserFactory();
|
||||
|
||||
// if the user is logged in we go to dashboard
|
||||
if ($userFactory->active())
|
||||
{
|
||||
$this->view->setActiveDashboard('dashboard');
|
||||
$this->view->setActiveId(0);
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
elseif ('signup' === $task)
|
||||
{
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->renderer->render('signup.twig')));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->renderer->render('login.twig')));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
249
libraries/src/Controller/MenuController.php
Normal file
249
libraries/src/Controller/MenuController.php
Normal file
@ -0,0 +1,249 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\Filter\InputFilter;
|
||||
use Kumwe\CMS\Model\MenuModel;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\MenuHtmlView;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class MenuController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var MenuHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* The model object.
|
||||
*
|
||||
* @var MenuModel
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* @var InputFilter
|
||||
*/
|
||||
private $inputFilter;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param MenuModel $model The model object.
|
||||
* @param MenuHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
*/
|
||||
public function __construct(
|
||||
MenuModel $model,
|
||||
MenuHtmlView $view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->model = $model;
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$method = $this->getInput()->getMethod();
|
||||
$task = $this->getInput()->getString('task', '');
|
||||
$id = $this->getInput()->getInt('id', 0);
|
||||
|
||||
// if task is delete
|
||||
if ('delete' === $task)
|
||||
{
|
||||
if ($this->allow('menu') && $this->user->get('access.menu.delete', false))
|
||||
{
|
||||
if ($this->model->delete($id))
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('Menu was deleted!', 'success');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('Menu could not be deleted!', 'error');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to delete this menu!', 'error');
|
||||
}
|
||||
// go to set page
|
||||
$this->_redirect('menus');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('POST' === $method)
|
||||
{
|
||||
// check permissions
|
||||
$update = ($id > 0 && $this->user->get('access.menu.update', false));
|
||||
$create = ($id == 0 && $this->user->get('access.menu.create', false));
|
||||
|
||||
if ( $create || $update )
|
||||
{
|
||||
$id = $this->setItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating menu
|
||||
if ($id == 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create menus!', 'error');
|
||||
}
|
||||
// not allowed updating menu
|
||||
if ($id > 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to update the menu details!', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check permissions
|
||||
$read = ($id > 0 && $this->user->get('access.menu.read', false));
|
||||
$create = ($id == 0 && $this->user->get('access.menu.create', false));
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('menu') && ( $read || $create ))
|
||||
{
|
||||
// set values for view
|
||||
$this->view->setActiveId($id);
|
||||
$this->view->setActiveView('menu');
|
||||
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating menu
|
||||
if ($id == 0 && !$create)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create menus!', 'error');
|
||||
}
|
||||
// not allowed read menu
|
||||
if ($id > 0 && !$read)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to read the menu details!', 'error');
|
||||
}
|
||||
|
||||
// go to set page
|
||||
$this->_redirect('menus');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an item
|
||||
*
|
||||
*
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setItem(): int
|
||||
{
|
||||
// always check the post token
|
||||
$this->checkToken();
|
||||
// get the post
|
||||
$post = $this->getInput()->getInputForRequestMethod();
|
||||
|
||||
// we get all the needed items
|
||||
$tempItem = [];
|
||||
$tempItem['id'] = $post->getInt('menu_id', 0);
|
||||
$tempItem['title'] = $post->getString('title', '');
|
||||
$tempItem['alias'] = $post->getString('alias', '');
|
||||
$tempItem['path'] = $post->getString('path', '');
|
||||
$tempItem['item_id'] = $post->getInt('item_id', 0);
|
||||
$tempItem['published'] = $post->getInt('published', 1);
|
||||
$tempItem['publish_up'] = $post->getString('publish_up', '');
|
||||
$tempItem['publish_down'] = $post->getString('publish_down', '');
|
||||
$tempItem['position'] = $post->getString('position', 'center');
|
||||
$tempItem['home'] = $post->getInt('home', 0);
|
||||
$tempItem['parent_id'] = $post->getInt('parent_id', 0);
|
||||
|
||||
// check that we have a Title
|
||||
$can_save = true;
|
||||
if (empty($tempItem['title']))
|
||||
{
|
||||
// we show a warning message
|
||||
$tempItem['title'] = '';
|
||||
$this->getApplication()->enqueueMessage('Title field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
// we actually can also not continue if we don't have content
|
||||
if (empty($tempItem['item_id']) || $tempItem['item_id'] == 0)
|
||||
{
|
||||
// we show a warning message
|
||||
$tempItem['item_id'] = 0;
|
||||
$this->getApplication()->enqueueMessage('Item field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
|
||||
// can we save the item
|
||||
if ($can_save)
|
||||
{
|
||||
return $this->model->setItem(
|
||||
$tempItem['id'],
|
||||
$tempItem['title'],
|
||||
$tempItem['alias'],
|
||||
$tempItem['item_id'],
|
||||
$tempItem['path'],
|
||||
$tempItem['published'],
|
||||
$tempItem['publish_up'],
|
||||
$tempItem['publish_down'],
|
||||
$tempItem['position'],
|
||||
$tempItem['home'],
|
||||
$tempItem['parent_id']);
|
||||
}
|
||||
|
||||
// add to model the post values
|
||||
$this->model->tempItem = $tempItem;
|
||||
|
||||
return $tempItem['id'];
|
||||
}
|
||||
}
|
94
libraries/src/Controller/MenusController.php
Normal file
94
libraries/src/Controller/MenusController.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\MenusHtmlView;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class MenusController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var MenusHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param MenusHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
* @param User|null $user The user object.
|
||||
*/
|
||||
public function __construct(
|
||||
MenusHtmlView $view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$this->view->setActiveView('menus');
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('menus') && $this->user->get('access.menu.read', false))
|
||||
{
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// go to set page
|
||||
$this->_redirect();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
105
libraries/src/Controller/PageController.php
Normal file
105
libraries/src/Controller/PageController.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Uri\Uri;
|
||||
use Kumwe\CMS\Utilities\StringHelper;
|
||||
use Kumwe\CMS\View\Site\PageHtmlView;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
use Laminas\Diactoros\Response\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\SiteApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\SiteApplication $app Application object
|
||||
*/
|
||||
class PageController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var PageHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PageHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
*/
|
||||
public function __construct(PageHtmlView $view, Input $input = null, AbstractApplication $app = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Disable all cache for now
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
// get the root name
|
||||
$root = $this->getInput()->getString('root', '');
|
||||
// start building the full path
|
||||
$path = [];
|
||||
$path[] = $root;
|
||||
// set a mad depth TODO: we should limit the menu depth to 6 or something
|
||||
$depth = range(1,20);
|
||||
// load the whole path
|
||||
foreach ($depth as $page)
|
||||
{
|
||||
$page = StringHelper::numbers($page);
|
||||
// check if there is a value
|
||||
$result = $this->getInput()->getString($page, false);
|
||||
if ($result)
|
||||
{
|
||||
$path[] = $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
// first false means we are at the end of the line
|
||||
break;
|
||||
}
|
||||
}
|
||||
// set the final path
|
||||
$path = implode('/', $path);
|
||||
|
||||
// if for some reason the view value is administrator
|
||||
if ('administrator' === $root)
|
||||
{
|
||||
// get uri request to get host
|
||||
$uri = new Uri($this->getApplication()->get('uri.request'));
|
||||
|
||||
// Redirect to the administrator area
|
||||
$this->getApplication()->setResponse(new RedirectResponse($uri->getScheme() . '://' . $uri->getHost() . '/administrator/', 301));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->view->setPage($path);
|
||||
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
452
libraries/src/Controller/UserController.php
Normal file
452
libraries/src/Controller/UserController.php
Normal file
@ -0,0 +1,452 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Exception;
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Authentication\Password\BCryptHandler;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Date\Date;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\Model\UserModel;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\UserHtmlView;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class UserController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var UserHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* The model object.
|
||||
*
|
||||
* @var UserModel
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* @var BCryptHandler
|
||||
*/
|
||||
private $secure;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param UserModel $model The model object.
|
||||
* @param UserHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param User|null $user The current user.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
*/
|
||||
public function __construct(
|
||||
UserModel $model,
|
||||
UserHtmlView $view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null,
|
||||
BCryptHandler $secure = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->model = $model;
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
$this->secure = ($secure) ?: new BCryptHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$method = $this->getInput()->getMethod();
|
||||
$task = $this->getInput()->getString('task', '');
|
||||
$id = $this->getInput()->getInt('id', 0);
|
||||
|
||||
// if task is delete
|
||||
if ('delete' === $task)
|
||||
{
|
||||
// check that the user does not delete him/her self
|
||||
if ($this->allow('user') && $this->user->get('access.user.delete', false))
|
||||
{
|
||||
// get the current user being deleted
|
||||
/** @var \Kumwe\CMS\User\User $userBeingDeleted */
|
||||
$userBeingDeleted = Factory::getContainer()->get(UserFactoryInterface::class)->getUser($id);
|
||||
// get the current active user ID
|
||||
$user_id = $this->user->get('id', -1);
|
||||
// is this the same user account as the active user
|
||||
if ($user_id == $id)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You can not delete your own account!', 'warning');
|
||||
}
|
||||
elseif ($userBeingDeleted->get('is_admin', false) && !$this->user->get('is_admin', false))
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You dont have the permission to delete an administrator account!', 'error');
|
||||
}
|
||||
elseif ($this->model->delete($id))
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('User was deleted!', 'success');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('User could not be deleted!', 'error');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to delete this user!', 'error');
|
||||
}
|
||||
// go to set page
|
||||
$this->_redirect('users');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// set the current user ID
|
||||
$user_id = $this->user->get('id', -1);
|
||||
|
||||
if ('POST' === $method)
|
||||
{
|
||||
// always check the post token
|
||||
$this->checkToken();
|
||||
// get the post
|
||||
$post = $this->getInput()->getInputForRequestMethod();
|
||||
|
||||
// we get all the needed items
|
||||
$tempItem = $post->getArray(['groups' => 'INT']);
|
||||
$tempItem['id'] = $post->getInt('user_id', 0);
|
||||
$tempItem['name'] = $post->getString('name', '');
|
||||
$tempItem['username'] = $post->getUsername('username', '');
|
||||
$tempItem['password'] = $post->getString('password', '');
|
||||
$tempItem['password2'] = $post->getString('password2', '');
|
||||
$tempItem['email'] = $post->getString('email', '');
|
||||
$tempItem['block'] = $post->getInt('block', 1);
|
||||
$tempItem['sendEmail'] = $post->getInt('sendEmail', 1);
|
||||
$tempItem['activation'] = $post->getInt('activation', 0);
|
||||
|
||||
// check permissions
|
||||
$update = ($tempItem['id'] > 0 && $this->user->get('access.user.update', false));
|
||||
$create = ($tempItem['id'] == 0 && $this->user->get('access.user.create', false));
|
||||
$selfUpdate = ($tempItem['id'] > 0 && $tempItem['id'] == $user_id);
|
||||
|
||||
if ($create || $update || $selfUpdate)
|
||||
{
|
||||
$id = $this->setItem($tempItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating user
|
||||
if ($id == 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create users!', 'error');
|
||||
}
|
||||
// not allowed updating user
|
||||
if ($id > 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to update the user details!', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check permissions
|
||||
$read = ($id > 0 && $this->user->get('access.user.read', false));
|
||||
$create = ($id == 0 && $this->user->get('access.user.create', false));
|
||||
$selfUpdate = ($id > 0 && $id == $user_id);
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('user') && ($read || $create || $selfUpdate))
|
||||
{
|
||||
// set values for view
|
||||
$this->view->setActiveId($id);
|
||||
$this->view->setActiveView('user');
|
||||
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating user
|
||||
if ($id == 0 && !$create)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create users!', 'error');
|
||||
}
|
||||
// not allowed updating user
|
||||
if ($id > 0 && !$read)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to read the user details!', 'error');
|
||||
}
|
||||
|
||||
// go to set page
|
||||
$this->_redirect('users');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an item
|
||||
*
|
||||
* @param array $tempItem
|
||||
*
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function setItem(array $tempItem): int
|
||||
{
|
||||
$can_save = true;
|
||||
// check that we have a name
|
||||
if (empty($tempItem['name']))
|
||||
{
|
||||
// we show an error message
|
||||
$tempItem['name'] = '';
|
||||
$this->getApplication()->enqueueMessage('Name field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
// check that we have a username
|
||||
if (empty($tempItem['username']))
|
||||
{
|
||||
// we show an error message
|
||||
$tempItem['username'] = '';
|
||||
$this->getApplication()->enqueueMessage('Username field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
// check that we have an email TODO: check that we have a valid email
|
||||
if (empty($tempItem['email']))
|
||||
{
|
||||
// we show an error message
|
||||
$tempItem['email'] = '';
|
||||
$this->getApplication()->enqueueMessage('Email field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
// check passwords
|
||||
if (isset($tempItem['password2']) && $tempItem['password'] != $tempItem['password2'])
|
||||
{
|
||||
// we show an error message
|
||||
$tempItem['password'] = 'xxxxxxxxxx';
|
||||
$tempItem['password2'] = 'xxxxxxxxxx';
|
||||
$this->getApplication()->enqueueMessage('Passwords do not match.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
unset ($tempItem['password2']);
|
||||
// do not set password that has not changed
|
||||
if ($tempItem['password'] === 'xxxxxxxxxx')
|
||||
{
|
||||
if ($tempItem['id'] == 0)
|
||||
{
|
||||
// we show an error message
|
||||
$tempItem['password'] = 'xxxxxxxxxx';
|
||||
$tempItem['password2'] = 'xxxxxxxxxx';
|
||||
$this->getApplication()->enqueueMessage('Passwords not set.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tempItem['password'] = '';
|
||||
}
|
||||
}
|
||||
elseif (strlen($tempItem['password']) < 7)
|
||||
{
|
||||
// we show an error message
|
||||
$tempItem['password'] = 'xxxxxxxxxx';
|
||||
$tempItem['password2'] = 'xxxxxxxxxx';
|
||||
$this->getApplication()->enqueueMessage('Passwords must be longer than 6 characters.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hash the password
|
||||
$tempItem['password'] = $this->secure->hashPassword($tempItem['password']);
|
||||
}
|
||||
|
||||
// can we save the item
|
||||
if ($can_save)
|
||||
{
|
||||
// check that the user does not block him/her self
|
||||
$user_id = $this->user->get('id', -1);
|
||||
$block_status = $tempItem['block'];
|
||||
// this user is the current user
|
||||
if ($user_id == $tempItem['id'])
|
||||
{
|
||||
// don't allow user to block self
|
||||
if ($tempItem['block'] != 0)
|
||||
{
|
||||
// we show a warning message
|
||||
$this->getApplication()->enqueueMessage('You can not block yourself!', 'warning');
|
||||
$tempItem['block'] = 0;
|
||||
}
|
||||
// don't allow user remove self from admin groups
|
||||
if ($this->user->get('is_admin', false))
|
||||
{
|
||||
$admin_groups = $this->user->get('is_admin_groups', []);
|
||||
if (is_array($admin_groups) && count($admin_groups) > 0)
|
||||
{
|
||||
$notice_set_groups = true;
|
||||
foreach ($admin_groups as $admin_group)
|
||||
{
|
||||
if (!is_array($tempItem['groups']) || !in_array($admin_group, $tempItem['groups']))
|
||||
{
|
||||
if ($notice_set_groups)
|
||||
{
|
||||
// we show a warning message
|
||||
$this->getApplication()->enqueueMessage('You can not remove yourself from the administrator group!', 'warning');
|
||||
$notice_set_groups = false;
|
||||
}
|
||||
$tempItem['groups'][] = $admin_group;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we show an error message
|
||||
$this->getApplication()->enqueueMessage('There is a problem with the admin user groups, we can not save the user details.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// can we save the item
|
||||
if ($can_save)
|
||||
{
|
||||
// check that the user will have some groups left
|
||||
if (!is_array($tempItem['groups']) || count($tempItem['groups']) == 0)
|
||||
{
|
||||
// we show a warning message
|
||||
$this->getApplication()->enqueueMessage('You must select at least one group.', 'warning');
|
||||
// this user is the current user
|
||||
if ($user_id == $tempItem['id'])
|
||||
{
|
||||
$tempItem['groups'] = $this->user->get('groups_ids', []);
|
||||
// check if we still have no groups
|
||||
if (count($tempItem['groups']) == 0)
|
||||
{
|
||||
$can_save = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$can_save = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// can we save the item
|
||||
if ($can_save)
|
||||
{
|
||||
// none admin restrictions TODO would like to move this to the database and not hard code it
|
||||
if (!$this->user->get('is_admin', false))
|
||||
{
|
||||
// with existing users
|
||||
if ($tempItem['id'] > 0)
|
||||
{
|
||||
// get the current user being saved
|
||||
/** @var \Kumwe\CMS\User\User $userBeingSaved */
|
||||
$userBeingSaved = Factory::getContainer()->get(UserFactoryInterface::class)->getUser($tempItem['id']);
|
||||
// don't allow block status change by none admin users
|
||||
$block = $userBeingSaved->get('block', 1);
|
||||
$current_posted_block = $tempItem['block'];
|
||||
// if the status changed we revert and give message
|
||||
// we allow block but not un-block
|
||||
if ($block != $current_posted_block && $current_posted_block == 0)
|
||||
{
|
||||
// we show a warning message
|
||||
$this->getApplication()->enqueueMessage('Only the administrator can update user access to system.', 'warning');
|
||||
$tempItem['block'] = 1;
|
||||
}
|
||||
// get current group to see if we must give a notice
|
||||
$groups = $userBeingSaved->get('groups_ids', []);
|
||||
$current_posted_groups = $tempItem['groups'];
|
||||
sort($groups);
|
||||
sort($current_posted_groups);
|
||||
// if the groups changes we give a message
|
||||
if ($groups !== $current_posted_groups)
|
||||
{
|
||||
// we show a warning message
|
||||
$this->getApplication()->enqueueMessage('Only the administrator can update user group selection.', 'warning');
|
||||
}
|
||||
// if the current user being saved is an admin account
|
||||
// we don't allow the following changes
|
||||
if ($userBeingSaved->get('is_admin', false))
|
||||
{
|
||||
// we do not allow password changes of admin accounts
|
||||
$tempItem['password'] = '';
|
||||
// we don't allow username changes
|
||||
$tempItem['username'] = $userBeingSaved->get('username', $tempItem['username']);
|
||||
// we don't allow change of status
|
||||
if ($block != $current_posted_block)
|
||||
{
|
||||
// we show an error message
|
||||
$this->getApplication()->enqueueMessage('Only the administrator can update another administrator account access to system.', 'error');
|
||||
$tempItem['block'] = $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// new users created by none admin must be blocked by default
|
||||
// since only admin can unblock any users
|
||||
$tempItem['block'] = 1;
|
||||
}
|
||||
// only admin can change groups
|
||||
// empty groups will not get updated
|
||||
$tempItem['groups'] = [];
|
||||
}
|
||||
|
||||
$today = (new Date())->toSql();
|
||||
|
||||
return $this->model->setItem(
|
||||
$tempItem['id'],
|
||||
$tempItem['name'],
|
||||
$tempItem['username'],
|
||||
$tempItem['groups'],
|
||||
$tempItem['email'],
|
||||
$tempItem['password'],
|
||||
$tempItem['block'],
|
||||
$tempItem['sendEmail'],
|
||||
$today,
|
||||
$tempItem['activation']);
|
||||
}
|
||||
}
|
||||
|
||||
// add to model the post values
|
||||
$this->model->tempItem = $tempItem;
|
||||
|
||||
return $tempItem['id'];
|
||||
}
|
||||
}
|
262
libraries/src/Controller/UserGroupController.php
Normal file
262
libraries/src/Controller/UserGroupController.php
Normal file
@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 20th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\Model\UsergroupModel;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\UsergroupHtmlView;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class UserGroupController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var UsergroupHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* The model object.
|
||||
*
|
||||
* @var UsergroupModel
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param UsergroupModel $model The model object.
|
||||
* @param UsergroupHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
*/
|
||||
public function __construct(
|
||||
UsergroupModel $model,
|
||||
UsergroupHtmlView $view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->model = $model;
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$method = $this->getInput()->getMethod();
|
||||
$task = $this->getInput()->getString('task', '');
|
||||
$id = $this->getInput()->getInt('id', 0);
|
||||
|
||||
// if task is delete
|
||||
if ('delete' === $task)
|
||||
{
|
||||
if ($this->allow('usergroup') && $this->user->get('access.usergroup.delete', false))
|
||||
{
|
||||
// TODO not ideal to hard code any ID
|
||||
if ($id == 1)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('This is the administrator user group that can not be deleted.', 'error');
|
||||
}
|
||||
elseif ($id > 0 && $this->model->linked($id))
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('This user group is still in use and can therefore no be deleted.', 'error');
|
||||
}
|
||||
elseif ($this->model->delete($id))
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('User group was deleted!', 'success');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('User group could not be deleted!', 'error');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to delete this user group!', 'error');
|
||||
}
|
||||
// go to set page
|
||||
$this->_redirect('usergroups');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('POST' === $method)
|
||||
{
|
||||
// check permissions
|
||||
$update = ($id > 0 && $this->user->get('access.usergroup.update', false));
|
||||
$create = ($id == 0 && $this->user->get('access.usergroup.create', false));
|
||||
|
||||
// TODO not ideal to hard code any ID
|
||||
if ($id == 1 && $update)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('This is the administrator user group that can not change.', 'error');
|
||||
}
|
||||
elseif ( $create || $update )
|
||||
{
|
||||
$id = $this->setItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating user group
|
||||
if ($id == 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create user groups!', 'error');
|
||||
}
|
||||
// not allowed updating user group
|
||||
if ($id > 0)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to update the user group details!', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check permissions
|
||||
$read = ($id > 0 && $this->user->get('access.usergroup.read', false));
|
||||
$create = ($id == 0 && $this->user->get('access.usergroup.create', false));
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('usergroup') && ( $read || $create ))
|
||||
{
|
||||
// set values for view
|
||||
$this->view->setActiveId($id);
|
||||
$this->view->setActiveView('usergroup');
|
||||
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// not allowed creating user group
|
||||
if ($id == 0 && !$create)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to create user groups!', 'error');
|
||||
}
|
||||
// not allowed read user group
|
||||
if ($id > 0 && !$read)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage('You do not have permission to read the user group details!', 'error');
|
||||
}
|
||||
|
||||
// go to set page
|
||||
$this->_redirect('items');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an item
|
||||
*
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setItem(): int
|
||||
{
|
||||
// always check the post token
|
||||
$this->checkToken();
|
||||
// get the post
|
||||
$post = $this->getInput()->getInputForRequestMethod();
|
||||
|
||||
// we get all the needed items
|
||||
$tempItem = $post->getArray(['params' => 'STRING']);;
|
||||
$tempItem['id'] = $post->getInt('usergroup_id', 0);
|
||||
$tempItem['title'] = $post->getString('title', '');
|
||||
|
||||
$can_save = true;
|
||||
// check that we have a name
|
||||
if (empty($tempItem['title']))
|
||||
{
|
||||
// we show a warning message
|
||||
$tempItem['name'] = '';
|
||||
$this->getApplication()->enqueueMessage('User group name field is required.', 'error');
|
||||
$can_save = false;
|
||||
}
|
||||
// set the params
|
||||
$build_params = $this->model->getGroupDefaultsAccess();
|
||||
if (isset($tempItem['params']) && is_array($tempItem['params']) && count($tempItem['params']))
|
||||
{
|
||||
$only = 'CRUD';
|
||||
foreach ($build_params as $n => &$item)
|
||||
{
|
||||
if (isset($tempItem['params'][$item->area]) && strlen($tempItem['params'][$item->area]))
|
||||
{
|
||||
$array_of_access = str_split(strtoupper($tempItem['params'][$item->area]));
|
||||
$access_keeper = [];
|
||||
if ($array_of_access)
|
||||
{
|
||||
foreach ($array_of_access as $char)
|
||||
{
|
||||
if (strpos($only, $char) === false)
|
||||
{
|
||||
$this->getApplication()->enqueueMessage("User group access in ({$item->area} area) had a wrong key ({$char}) so we removed it. Please only use the keys prescribed.", 'warning');
|
||||
}
|
||||
else
|
||||
{
|
||||
$access_keeper[] = $char;
|
||||
}
|
||||
}
|
||||
}
|
||||
$item->access = implode($access_keeper);
|
||||
}
|
||||
}
|
||||
}
|
||||
// update the params
|
||||
$tempItem['params'] = $build_params;
|
||||
|
||||
// can we save the item
|
||||
if ($can_save)
|
||||
{
|
||||
return $this->model->setItem(
|
||||
$tempItem['id'],
|
||||
$tempItem['title'],
|
||||
$tempItem['params']);
|
||||
}
|
||||
|
||||
// add to model the post values
|
||||
$this->model->tempItem = $tempItem;
|
||||
|
||||
return $tempItem['id'];
|
||||
}
|
||||
}
|
94
libraries/src/Controller/UsergroupsController.php
Normal file
94
libraries/src/Controller/UsergroupsController.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 20th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\UsergroupsHtmlView;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class UsergroupsController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var UsergroupsHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param UsergroupsHtmlView $view The view object.
|
||||
* @param Input|null $input The input object.
|
||||
* @param AbstractApplication|null $app The application object.
|
||||
* @param User|null $user
|
||||
*/
|
||||
public function __construct(
|
||||
UsergroupsHtmlView $view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$this->view->setActiveView('usergroups');
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('usergroups') && $this->user->get('access.usergroup.read', false))
|
||||
{
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// go to set page
|
||||
$this->_redirect();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
93
libraries/src/Controller/UsersController.php
Normal file
93
libraries/src/Controller/UsersController.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Joomla\Input\Input;
|
||||
use Kumwe\CMS\Controller\Util\AccessInterface;
|
||||
use Kumwe\CMS\Controller\Util\AccessTrait;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenInterface;
|
||||
use Kumwe\CMS\Controller\Util\CheckTokenTrait;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\UsersHtmlView;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
|
||||
/**
|
||||
* Controller handling the requests
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\AdminApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\AdminApplication $app Application object
|
||||
*/
|
||||
class UsersController extends AbstractController implements AccessInterface, CheckTokenInterface
|
||||
{
|
||||
use AccessTrait, CheckTokenTrait;
|
||||
|
||||
/**
|
||||
* The view object.
|
||||
*
|
||||
* @var UsersHtmlView
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param UsersHtmlView $view The view object.
|
||||
* @param Input $input The input object.
|
||||
* @param AbstractApplication $app The application object.
|
||||
*/
|
||||
public function __construct(
|
||||
UsersHtmlView $view,
|
||||
Input $input = null,
|
||||
AbstractApplication $app = null,
|
||||
User $user = null)
|
||||
{
|
||||
parent::__construct($input, $app);
|
||||
|
||||
$this->view = $view;
|
||||
$this->user = ($user) ?: Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Do not Enable browser caching
|
||||
$this->getApplication()->allowCache(false);
|
||||
|
||||
$this->view->setActiveView('users');
|
||||
|
||||
// check if user is allowed to access
|
||||
if ($this->allow('users') && $this->user->get('access.user.read', false))
|
||||
{
|
||||
$this->getApplication()->setResponse(new HtmlResponse($this->view->render()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// go to set page
|
||||
$this->_redirect();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
28
libraries/src/Controller/Util/AccessInterface.php
Normal file
28
libraries/src/Controller/Util/AccessInterface.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller\Util;
|
||||
|
||||
/**
|
||||
* Class for checking the user access
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface AccessInterface
|
||||
{
|
||||
/**
|
||||
* @param string $task
|
||||
* @param string $default
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function allow(string $task, string $default = ''): bool;
|
||||
}
|
111
libraries/src/Controller/Util/AccessTrait.php
Normal file
111
libraries/src/Controller/Util/AccessTrait.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller\Util;
|
||||
|
||||
use Joomla\Uri\Uri;
|
||||
|
||||
/**
|
||||
* Trait for checking the user access
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait AccessTrait
|
||||
{
|
||||
/**
|
||||
* When access not allowed this is the path to redirect to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $noAccessRedirect = '';
|
||||
|
||||
/**
|
||||
* Check if user is allowed to access this area
|
||||
*
|
||||
* @param string $task
|
||||
* @param string $default
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function allow(string $task = 'post', string $default = ''): bool
|
||||
{
|
||||
// our little access controller TODO: we can do better
|
||||
$has_access = false;
|
||||
|
||||
/** @var \Kumwe\CMS\Application\AdminApplication $app */
|
||||
$app = $this->getApplication();
|
||||
|
||||
/** @var \Kumwe\CMS\User\UserFactory $userFactory */
|
||||
$userFactory = $app->getUserFactory();
|
||||
|
||||
// user actions [logout]
|
||||
if ('logout' === $task)
|
||||
{
|
||||
if ($userFactory->logout())
|
||||
{
|
||||
$this->noAccessRedirect = '/';
|
||||
// clear the message queue
|
||||
$app->getMessageQueue(true);
|
||||
}
|
||||
}
|
||||
// check if this is a user valid
|
||||
elseif ($userFactory->active())
|
||||
{
|
||||
$has_access = true;
|
||||
}
|
||||
// user actions [access, signup]
|
||||
elseif ('access' === $task || 'signup' === $task)
|
||||
{
|
||||
if ('access' === $task)
|
||||
{
|
||||
if ($userFactory->login())
|
||||
{
|
||||
$has_access = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($userFactory->create())
|
||||
{
|
||||
$has_access = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->noAccessRedirect = '/?account=signup';
|
||||
}
|
||||
}
|
||||
|
||||
// we by default always load the dashboard
|
||||
$this->view->setActiveDashboard($default);
|
||||
}
|
||||
|
||||
return $has_access;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $target
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _redirect(string $target = null)
|
||||
{
|
||||
// get uri request to get host
|
||||
$uri = new Uri($this->getApplication()->get('uri.request'));
|
||||
|
||||
// get redirect path
|
||||
$redirect = (!empty($target)) ? $target : $this->noAccessRedirect;
|
||||
// fix the path
|
||||
$path = $uri->getPath();
|
||||
$path = substr($path, 0, strripos($path, '/')) . '/' . $redirect;
|
||||
// redirect to the set area
|
||||
$this->getApplication()->redirect($uri->getScheme() . '://' . $uri->getHost() . $path );
|
||||
}
|
||||
}
|
26
libraries/src/Controller/Util/CheckTokenInterface.php
Normal file
26
libraries/src/Controller/Util/CheckTokenInterface.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller\Util;
|
||||
|
||||
/**
|
||||
* Class for checking the form had a token
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface CheckTokenInterface
|
||||
{
|
||||
/**
|
||||
* Check the token of the form
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkToken(): bool;
|
||||
}
|
36
libraries/src/Controller/Util/CheckTokenTrait.php
Normal file
36
libraries/src/Controller/Util/CheckTokenTrait.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller\Util;
|
||||
|
||||
/**
|
||||
* Class for checking the form had a token
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait CheckTokenTrait
|
||||
{
|
||||
/**
|
||||
* Check the token of the form
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkToken(): bool
|
||||
{
|
||||
$token = $this->getApplication()->getSession()->getToken();
|
||||
$form_token = $this->getInput()->getString($token, 0);
|
||||
|
||||
if ($form_token == 0)
|
||||
{
|
||||
exit('Invalid form token');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
40
libraries/src/Controller/WrongCmsController.php
Normal file
40
libraries/src/Controller/WrongCmsController.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Controller;
|
||||
|
||||
use Joomla\Controller\AbstractController;
|
||||
use Laminas\Diactoros\Response\TextResponse;
|
||||
|
||||
/**
|
||||
* Controller class to display a message to individuals looking for the wrong CMS
|
||||
*
|
||||
* @method \Kumwe\CMS\Application\SiteApplication getApplication() Get the application object.
|
||||
* @property-read \Kumwe\CMS\Application\SiteApplication $app Application object
|
||||
*/
|
||||
class WrongCmsController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* Execute the controller.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function execute(): bool
|
||||
{
|
||||
// Enable browser caching
|
||||
$this->getApplication()->allowCache(true);
|
||||
|
||||
$response = new TextResponse("This isn't the what you're looking for.", 404);
|
||||
|
||||
$this->getApplication()->setResponse($response);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
484
libraries/src/Date/Date.php
Normal file
484
libraries/src/Date/Date.php
Normal file
@ -0,0 +1,484 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Content Management System
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Date;
|
||||
|
||||
use Joomla\Database\DatabaseInterface;
|
||||
use Kumwe\CMS\Factory;
|
||||
|
||||
/**
|
||||
* Date is a class that stores a date and provides logic to manipulate
|
||||
* and render that date in a variety of formats.
|
||||
*
|
||||
* @method Date|bool add(\DateInterval $interval) Adds an amount of days, months, years, hours, minutes and seconds to a Date object.
|
||||
* @method Date|bool sub(\DateInterval $interval) Subtracts an amount of days, months, years, hours, minutes and seconds from a Date object.
|
||||
* @method Date|bool modify(string $modify) Alter the timestamp of this object by incre/decre-menting in a format accepted by strtotime().
|
||||
*
|
||||
* @property-read string $daysinmonth t - Number of days in the given month.
|
||||
* @property-read string $dayofweek N - ISO-8601 numeric representation of the day of the week.
|
||||
* @property-read string $dayofyear z - The day of the year (starting from 0).
|
||||
* @property-read boolean $isleapyear L - Whether it's a leap year.
|
||||
* @property-read string $day d - Day of the month, 2 digits with leading zeros.
|
||||
* @property-read string $hour H - 24-hour format of an hour with leading zeros.
|
||||
* @property-read string $minute i - Minutes with leading zeros.
|
||||
* @property-read string $second s - Seconds with leading zeros.
|
||||
* @property-read string $microsecond u - Microseconds with leading zeros.
|
||||
* @property-read string $month m - Numeric representation of a month, with leading zeros.
|
||||
* @property-read string $ordinal S - English ordinal suffix for the day of the month, 2 characters.
|
||||
* @property-read string $week W - ISO-8601 week number of year, weeks starting on Monday.
|
||||
* @property-read string $year Y - A full numeric representation of a year, 4 digits.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
class Date extends \DateTime
|
||||
{
|
||||
const DAY_ABBR = "\x021\x03";
|
||||
const DAY_NAME = "\x022\x03";
|
||||
const MONTH_ABBR = "\x023\x03";
|
||||
const MONTH_NAME = "\x024\x03";
|
||||
|
||||
/**
|
||||
* The format string to be applied when using the __toString() magic method.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static $format = 'Y-m-d H:i:s';
|
||||
|
||||
/**
|
||||
* Placeholder for a \DateTimeZone object with GMT as the time zone.
|
||||
*
|
||||
* @var object
|
||||
* @since 1.7.0
|
||||
*
|
||||
* @deprecated 5.0 Without replacement
|
||||
*/
|
||||
protected static $gmt;
|
||||
|
||||
/**
|
||||
* Placeholder for a \DateTimeZone object with the default server
|
||||
* time zone as the time zone.
|
||||
*
|
||||
* @var object
|
||||
* @since 1.7.0
|
||||
*
|
||||
* @deprecated 5.0 Without replacement
|
||||
*/
|
||||
protected static $stz;
|
||||
|
||||
/**
|
||||
* The \DateTimeZone object for usage in rending dates as strings.
|
||||
*
|
||||
* @var \DateTimeZone
|
||||
* @since 3.0.0
|
||||
*/
|
||||
protected $tz;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $date String in a format accepted by strtotime(), defaults to "now".
|
||||
* @param mixed $tz Time zone to be used for the date. Might be a string or a DateTimeZone object.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function __construct($date = 'now', $tz = null)
|
||||
{
|
||||
// Create the base GMT and server time zone objects.
|
||||
if (empty(self::$gmt) || empty(self::$stz))
|
||||
{
|
||||
// @TODO: This code block stays here only for B/C, can be removed in 5.0
|
||||
self::$gmt = new \DateTimeZone('GMT');
|
||||
self::$stz = new \DateTimeZone(@date_default_timezone_get());
|
||||
}
|
||||
|
||||
// If the time zone object is not set, attempt to build it.
|
||||
if (!($tz instanceof \DateTimeZone))
|
||||
{
|
||||
if (\is_string($tz))
|
||||
{
|
||||
$tz = new \DateTimeZone($tz);
|
||||
}
|
||||
else
|
||||
{
|
||||
$tz = new \DateTimeZone('UTC');
|
||||
}
|
||||
}
|
||||
|
||||
// Backup active time zone
|
||||
$activeTZ = date_default_timezone_get();
|
||||
|
||||
// Force UTC timezone for correct time handling
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
// If the date is numeric assume a unix timestamp and convert it.
|
||||
$date = is_numeric($date) ? date('c', $date) : $date;
|
||||
|
||||
// Call the DateTime constructor.
|
||||
parent::__construct($date, $tz);
|
||||
|
||||
// Restore previously active timezone
|
||||
date_default_timezone_set($activeTZ);
|
||||
|
||||
// Set the timezone object for access later.
|
||||
$this->tz = $tz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to access properties of the date given by class to the format method.
|
||||
*
|
||||
* @param string $name The name of the property.
|
||||
*
|
||||
* @return mixed A value if the property name is valid, null otherwise.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$value = null;
|
||||
|
||||
switch ($name)
|
||||
{
|
||||
case 'daysinmonth':
|
||||
$value = $this->format('t', true);
|
||||
break;
|
||||
|
||||
case 'dayofweek':
|
||||
$value = $this->format('N', true);
|
||||
break;
|
||||
|
||||
case 'dayofyear':
|
||||
$value = $this->format('z', true);
|
||||
break;
|
||||
|
||||
case 'isleapyear':
|
||||
$value = (boolean) $this->format('L', true);
|
||||
break;
|
||||
|
||||
case 'day':
|
||||
$value = $this->format('d', true);
|
||||
break;
|
||||
|
||||
case 'hour':
|
||||
$value = $this->format('H', true);
|
||||
break;
|
||||
|
||||
case 'minute':
|
||||
$value = $this->format('i', true);
|
||||
break;
|
||||
|
||||
case 'second':
|
||||
$value = $this->format('s', true);
|
||||
break;
|
||||
|
||||
case 'month':
|
||||
$value = $this->format('m', true);
|
||||
break;
|
||||
|
||||
case 'ordinal':
|
||||
$value = $this->format('S', true);
|
||||
break;
|
||||
|
||||
case 'week':
|
||||
$value = $this->format('W', true);
|
||||
break;
|
||||
|
||||
case 'year':
|
||||
$value = $this->format('Y', true);
|
||||
break;
|
||||
|
||||
default:
|
||||
$trace = debug_backtrace();
|
||||
trigger_error(
|
||||
'Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'],
|
||||
E_USER_NOTICE
|
||||
);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to render the date object in the format specified in the public
|
||||
* static member Date::$format.
|
||||
*
|
||||
* @return string The date as a formatted string.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) parent::format(self::$format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for new Date().
|
||||
*
|
||||
* @param string $date String in a format accepted by strtotime(), defaults to "now".
|
||||
* @param mixed $tz Time zone to be used for the date.
|
||||
*
|
||||
* @return Date
|
||||
*
|
||||
* @since 1.7.3
|
||||
*/
|
||||
public static function getInstance($date = 'now', $tz = null)
|
||||
{
|
||||
return new static($date, $tz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates day of week number to a string.
|
||||
*
|
||||
* @param integer $day The numeric day of the week.
|
||||
* @param boolean $abbr Return the abbreviated day string?
|
||||
*
|
||||
* @return string The day of the week.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function dayToString($day, $abbr = false)
|
||||
{
|
||||
switch ($day)
|
||||
{
|
||||
case 0:
|
||||
return $abbr ? 'Sun' : 'Sunday';
|
||||
case 1:
|
||||
return $abbr ? 'Mon' : 'Monday';
|
||||
case 2:
|
||||
return $abbr ? 'Tue' : 'Tuesday';
|
||||
case 3:
|
||||
return $abbr ? 'Wed' : 'Wednesday';
|
||||
case 4:
|
||||
return $abbr ? 'Thu' : 'Thursday';
|
||||
case 5:
|
||||
return $abbr ? 'Fri' : 'Friday';
|
||||
case 6:
|
||||
return $abbr ? 'Sat' : 'Saturday';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date as a formatted string in a local calendar.
|
||||
*
|
||||
* @param string $format The date format specification string (see {@link PHP_MANUAL#date})
|
||||
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
|
||||
* @param boolean $translate True to translate localised strings
|
||||
*
|
||||
* @return string The date string in the specified format format.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function calendar($format, $local = false, $translate = true)
|
||||
{
|
||||
return $this->format($format, $local, $translate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date as a formatted string.
|
||||
*
|
||||
* @param string $format The date format specification string (see {@link PHP_MANUAL#date})
|
||||
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
|
||||
* @param boolean $translate True to translate localised strings
|
||||
*
|
||||
* @return string The date string in the specified format format.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function format($format, $local = false, $translate = true)
|
||||
{
|
||||
if ($translate)
|
||||
{
|
||||
// Do string replacements for date format options that can be translated.
|
||||
$format = preg_replace('/(^|[^\\\])D/', "\\1" . self::DAY_ABBR, $format);
|
||||
$format = preg_replace('/(^|[^\\\])l/', "\\1" . self::DAY_NAME, $format);
|
||||
$format = preg_replace('/(^|[^\\\])M/', "\\1" . self::MONTH_ABBR, $format);
|
||||
$format = preg_replace('/(^|[^\\\])F/', "\\1" . self::MONTH_NAME, $format);
|
||||
}
|
||||
|
||||
// If the returned time should not be local use UTC.
|
||||
if ($local == false)
|
||||
{
|
||||
parent::setTimezone(new \DateTimeZone('UTC'));
|
||||
}
|
||||
|
||||
// Format the date.
|
||||
$return = parent::format($format);
|
||||
|
||||
if ($translate)
|
||||
{
|
||||
// Manually modify the month and day strings in the formatted time.
|
||||
if (strpos($return, self::DAY_ABBR) !== false)
|
||||
{
|
||||
$return = str_replace(self::DAY_ABBR, $this->dayToString(parent::format('w'), true), $return);
|
||||
}
|
||||
|
||||
if (strpos($return, self::DAY_NAME) !== false)
|
||||
{
|
||||
$return = str_replace(self::DAY_NAME, $this->dayToString(parent::format('w')), $return);
|
||||
}
|
||||
|
||||
if (strpos($return, self::MONTH_ABBR) !== false)
|
||||
{
|
||||
$return = str_replace(self::MONTH_ABBR, $this->monthToString(parent::format('n'), true), $return);
|
||||
}
|
||||
|
||||
if (strpos($return, self::MONTH_NAME) !== false)
|
||||
{
|
||||
$return = str_replace(self::MONTH_NAME, $this->monthToString(parent::format('n')), $return);
|
||||
}
|
||||
}
|
||||
|
||||
if ($local == false && $this->tz !== null)
|
||||
{
|
||||
parent::setTimezone($this->tz);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time offset from GMT in hours or seconds.
|
||||
*
|
||||
* @param boolean $hours True to return the value in hours.
|
||||
*
|
||||
* @return float The time offset from GMT either in hours or in seconds.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function getOffsetFromGmt($hours = false)
|
||||
{
|
||||
return (float) $hours ? ($this->tz->getOffset($this) / 3600) : $this->tz->getOffset($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates month number to a string.
|
||||
*
|
||||
* @param integer $month The numeric month of the year.
|
||||
* @param boolean $abbr If true, return the abbreviated month string
|
||||
*
|
||||
* @return string The month of the year.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function monthToString($month, $abbr = false)
|
||||
{
|
||||
switch ($month)
|
||||
{
|
||||
case 1:
|
||||
return $abbr ? 'Jan' : 'January'; //
|
||||
case 2:
|
||||
return $abbr ? 'Feb' : 'February';
|
||||
case 3:
|
||||
return $abbr ? 'Mar' : 'March';
|
||||
case 4:
|
||||
return $abbr ? 'Apr' : 'April';
|
||||
case 5:
|
||||
return 'May';
|
||||
case 6:
|
||||
return $abbr ? 'Jun' : 'June';
|
||||
case 7:
|
||||
return $abbr ? 'Jul' : 'July';
|
||||
case 8:
|
||||
return $abbr ? 'Aug' : 'August';
|
||||
case 9:
|
||||
return $abbr ? 'Sep' : 'September';
|
||||
case 10:
|
||||
return $abbr ? 'Oct' : 'October';
|
||||
case 11:
|
||||
return $abbr ? 'Nov' : 'November';
|
||||
case 12:
|
||||
return $abbr ? 'Dec' : 'December';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to wrap the setTimezone() function and set the internal time zone object.
|
||||
*
|
||||
* @param \DateTimeZone $tz The new \DateTimeZone object.
|
||||
*
|
||||
* @return Date
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @note This method can't be type hinted due to a PHP bug: https://bugs.php.net/bug.php?id=61483
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function setTimezone($tz)
|
||||
{
|
||||
$this->tz = $tz;
|
||||
|
||||
return parent::setTimezone($tz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date as an ISO 8601 string. IETF RFC 3339 defines the ISO 8601 format
|
||||
* and it can be found at the IETF Web site.
|
||||
*
|
||||
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
|
||||
*
|
||||
* @return string The date string in ISO 8601 format.
|
||||
*
|
||||
* @link http://www.ietf.org/rfc/rfc3339.txt
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function toISO8601($local = false)
|
||||
{
|
||||
return $this->format(\DateTimeInterface::RFC3339, $local, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date as an SQL datetime string.
|
||||
*
|
||||
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
|
||||
* @param DatabaseInterface $db The database driver or null to use Factory::getDbo()
|
||||
*
|
||||
* @return string The date string in SQL datetime format.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 2.5.0
|
||||
* @link http://dev.mysql.com/doc/refman/5.0/en/datetime.html
|
||||
*/
|
||||
public function toSql($local = false, DatabaseInterface $db = null)
|
||||
{
|
||||
if ($db === null)
|
||||
{
|
||||
/** @var \Joomla\Database\DatabaseInterface $db */
|
||||
$db = Factory::getContainer()->get(DatabaseInterface::class);
|
||||
}
|
||||
|
||||
return $this->format($db->getDateFormat(), $local, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date as an RFC 822 string. IETF RFC 2822 supercedes RFC 822 and its definition
|
||||
* can be found at the IETF Web site.
|
||||
*
|
||||
* @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
|
||||
*
|
||||
* @return string The date string in RFC 822 format.
|
||||
*
|
||||
* @link http://www.ietf.org/rfc/rfc2822.txt
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function toRFC822($local = false)
|
||||
{
|
||||
return $this->format(\DateTimeInterface::RFC2822, $local, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date as UNIX time stamp.
|
||||
*
|
||||
* @return integer The date as a UNIX timestamp.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function toUnix()
|
||||
{
|
||||
return (int) parent::format('U');
|
||||
}
|
||||
}
|
195
libraries/src/EventListener/ErrorSubscriber.php
Normal file
195
libraries/src/EventListener/ErrorSubscriber.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\EventListener;
|
||||
|
||||
use Joomla\Application\ApplicationEvents;
|
||||
use Joomla\Application\Event\ApplicationErrorEvent;
|
||||
use Joomla\Console\ConsoleEvents;
|
||||
use Joomla\Console\Event\ApplicationErrorEvent as ConsoleApplicationErrorEvent;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
use Kumwe\CMS\Application\SiteApplication;
|
||||
use Joomla\Renderer\RendererInterface;
|
||||
use Joomla\Router\Exception\MethodNotAllowedException;
|
||||
use Joomla\Router\Exception\RouteNotFoundException;
|
||||
use Laminas\Diactoros\Response\HtmlResponse;
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
|
||||
/**
|
||||
* Error handling event subscriber
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/EventListener/ErrorSubscriber.php
|
||||
*/
|
||||
class ErrorSubscriber implements SubscriberInterface, LoggerAwareInterface
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/**
|
||||
* Layout renderer
|
||||
*
|
||||
* @var RendererInterface
|
||||
*/
|
||||
private $renderer;
|
||||
|
||||
/**
|
||||
* Event subscriber constructor.
|
||||
*
|
||||
* @param RendererInterface $renderer Layout renderer
|
||||
*/
|
||||
public function __construct(RendererInterface $renderer)
|
||||
{
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of events this subscriber will listen to.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
ApplicationEvents::ERROR => 'handleWebError',
|
||||
ConsoleEvents::APPLICATION_ERROR => 'handleConsoleError',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle console application errors.
|
||||
*
|
||||
* @param ConsoleApplicationErrorEvent $event Event object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handleConsoleError(ConsoleApplicationErrorEvent $event): void
|
||||
{
|
||||
$this->logError($event->getError());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle web application errors.
|
||||
*
|
||||
* @param ApplicationErrorEvent $event Event object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handleWebError(ApplicationErrorEvent $event): void
|
||||
{
|
||||
/** @var SiteApplication $app */
|
||||
$app = $event->getApplication();
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case $event->getError() instanceof MethodNotAllowedException :
|
||||
// Log the error for reference
|
||||
$this->logger->error(
|
||||
sprintf('Route `%s` not supported by method `%s`', $app->get('uri.route'), $app->input->getMethod()),
|
||||
['exception' => $event->getError()]
|
||||
);
|
||||
|
||||
$this->prepareResponse($event);
|
||||
|
||||
$app->setHeader('Allow', implode(', ', $event->getError()->getAllowedMethods()));
|
||||
|
||||
break;
|
||||
|
||||
case $event->getError() instanceof RouteNotFoundException :
|
||||
// Log the error for reference
|
||||
$this->logger->error(
|
||||
sprintf('Route `%s` not found', $app->get('uri.route')),
|
||||
['exception' => $event->getError()]
|
||||
);
|
||||
|
||||
$this->prepareResponse($event);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->logError($event->getError());
|
||||
|
||||
$this->prepareResponse($event);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the error.
|
||||
*
|
||||
* @param \Throwable $throwable The error being processed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function logError(\Throwable $throwable): void
|
||||
{
|
||||
$this->logger->error(
|
||||
sprintf('Uncaught Throwable of type %s caught.', \get_class($throwable)),
|
||||
['exception' => $throwable]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the response for the event
|
||||
*
|
||||
* @param ApplicationErrorEvent $event Event object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function prepareResponse(ApplicationErrorEvent $event): void
|
||||
{
|
||||
/** @var SiteApplication $app */
|
||||
$app = $event->getApplication();
|
||||
|
||||
$app->allowCache(false);
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case $app->input->getString('_format', 'html') === 'json' :
|
||||
case $app->mimeType === 'application/json' :
|
||||
case $app->getResponse() instanceof JsonResponse :
|
||||
$data = [
|
||||
'code' => $event->getError()->getCode(),
|
||||
'message' => $event->getError()->getMessage(),
|
||||
'error' => true,
|
||||
];
|
||||
|
||||
$response = new JsonResponse($data);
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
$response = new HtmlResponse(
|
||||
$this->renderer->render('exception.twig', ['exception' => $event->getError()])
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($event->getError()->getCode())
|
||||
{
|
||||
case 404 :
|
||||
$response = $response->withStatus(404);
|
||||
|
||||
break;
|
||||
|
||||
case 405 :
|
||||
$response = $response->withStatus(405);
|
||||
|
||||
break;
|
||||
|
||||
case 500 :
|
||||
default :
|
||||
$response = $response->withStatus(500);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$app->setResponse($response);
|
||||
}
|
||||
}
|
301
libraries/src/Factory.php
Normal file
301
libraries/src/Factory.php
Normal file
@ -0,0 +1,301 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 3rd April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS;
|
||||
|
||||
\defined('LPATH_PLATFORM') or die;
|
||||
|
||||
use Joomla\Application\WebApplicationInterface;
|
||||
use Joomla\Database\Service\DatabaseProvider;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\Registry\Registry;
|
||||
use PHPMailer\PHPMailer\Exception as phpmailerException;
|
||||
|
||||
/**
|
||||
* Kumwe Platform Factory class.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* SOURCE: https://github.com/joomla/joomla-cms/blob/4.1-dev/libraries/src/Factory.php#L39
|
||||
*/
|
||||
abstract class Factory
|
||||
{
|
||||
/**
|
||||
* Global application object
|
||||
*
|
||||
* @var WebApplicationInterface
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static $application = null;
|
||||
|
||||
/**
|
||||
* Global configuration object
|
||||
*
|
||||
* @var \LConfig
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static $config = null;
|
||||
|
||||
/**
|
||||
* Global container object
|
||||
*
|
||||
* @var Container
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static $container = null;
|
||||
|
||||
/**
|
||||
* Global mailer object
|
||||
*
|
||||
* @var Mail
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static $mailer = null;
|
||||
|
||||
/**
|
||||
* Get the global application object. When the global application doesn't exist, an exception is thrown.
|
||||
*
|
||||
* @return WebApplicationInterface object
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getApplication() : WebApplicationInterface
|
||||
{
|
||||
if (!self::$application)
|
||||
{
|
||||
throw new \Exception('Failed to start application', 500);
|
||||
}
|
||||
|
||||
return self::$application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a container object
|
||||
*
|
||||
* Returns the global service container object, only creating it if it doesn't already exist.
|
||||
*
|
||||
* This method is only suggested for use in code whose responsibility is to create new services
|
||||
* and needs to be able to resolve the dependencies, and should therefore only be used when the
|
||||
* container is not accessible by other means. Valid uses of this method include:
|
||||
*
|
||||
* - A static `getInstance()` method calling a factory service from the container,
|
||||
* see `Joomla\CMS\Toolbar\Toolbar::getInstance()` as an example
|
||||
* - An application front controller loading and executing the Joomla application class,
|
||||
* see the `cli/joomla.php` file as an example
|
||||
* - Retrieving optional constructor dependencies when not injected into a class during a transitional
|
||||
* period to retain backward compatibility, in this case a deprecation notice should also be emitted to
|
||||
* notify developers of changes needed in their code
|
||||
*
|
||||
* This method is not suggested for use as a one-for-one replacement of static calls, such as
|
||||
* replacing calls to `Factory::getDbo()` with calls to `Factory::getContainer()->get('db')`, code
|
||||
* should be refactored to support dependency injection instead of making this change.
|
||||
*
|
||||
* @return Container
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public static function getContainer(): Container
|
||||
{
|
||||
if (!self::$container)
|
||||
{
|
||||
self::$container = self::createContainer();
|
||||
}
|
||||
|
||||
return self::$container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mailer object.
|
||||
*
|
||||
* Returns the global {@link Mail} object, only creating it if it doesn't already exist.
|
||||
*
|
||||
* @return Mail object
|
||||
*
|
||||
* @see Mail
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static function getMailer()
|
||||
{
|
||||
if (!self::$mailer)
|
||||
{
|
||||
self::$mailer = self::createMailer();
|
||||
}
|
||||
|
||||
$copy = clone self::$mailer;
|
||||
|
||||
return $copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a container object
|
||||
*
|
||||
* @return Container
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected static function createContainer(): Container
|
||||
{
|
||||
return (new Container)
|
||||
->registerServiceProvider(new Service\ConfigurationProvider(LPATH_CONFIGURATION . '/config.php'))
|
||||
->registerServiceProvider(new Service\SessionProvider)
|
||||
->registerServiceProvider(new Service\UserProvider)
|
||||
->registerServiceProvider(new Service\InputProvider)
|
||||
->registerServiceProvider(new DatabaseProvider)
|
||||
->registerServiceProvider(new Service\EventProvider)
|
||||
->registerServiceProvider(new Service\HttpProvider)
|
||||
->registerServiceProvider(new Service\LoggingProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a configuration object
|
||||
*
|
||||
* Returns the global {@link \JConfig} object, only creating it if it doesn't already exist.
|
||||
*
|
||||
* @param string $file The path to the configuration file
|
||||
* @param string $type The type of the configuration file
|
||||
* @param string $namespace The namespace of the configuration file
|
||||
*
|
||||
* @return Registry
|
||||
*
|
||||
* @see Registry
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public static function getConfig($file = null, $type = 'PHP', $namespace = '')
|
||||
{
|
||||
/**
|
||||
* If there is an application object, fetch the configuration from there.
|
||||
* Check it's not null because LanguagesModel can make it null and if it's null
|
||||
* we would want to re-init it from configuration.php.
|
||||
*/
|
||||
if (self::$application && self::$application->getConfig() !== null)
|
||||
{
|
||||
return self::$application->getConfig();
|
||||
}
|
||||
|
||||
if (!self::$config)
|
||||
{
|
||||
if ($file === null)
|
||||
{
|
||||
$file = JPATH_CONFIGURATION . '/config.php';
|
||||
}
|
||||
|
||||
self::$config = self::createConfig($file, $type, $namespace);
|
||||
}
|
||||
|
||||
return self::$config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a configuration object
|
||||
*
|
||||
* @param string $file The path to the configuration file.
|
||||
* @param string $type The type of the configuration file.
|
||||
* @param string $namespace The namespace of the configuration file.
|
||||
*
|
||||
* @return Registry
|
||||
*
|
||||
* @see Registry
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function createConfig($file, $type = 'PHP', $namespace = '')
|
||||
{
|
||||
if (is_file($file))
|
||||
{
|
||||
include_once $file;
|
||||
}
|
||||
|
||||
// Create the registry with a default namespace of config
|
||||
$registry = new Registry;
|
||||
|
||||
// Sanitize the namespace.
|
||||
$namespace = ucfirst((string) preg_replace('/[^A-Z_]/i', '', $namespace));
|
||||
|
||||
// Build the config name.
|
||||
$name = 'LConfig' . $namespace;
|
||||
|
||||
// Handle the PHP configuration type.
|
||||
if ($type === 'PHP' && class_exists($name))
|
||||
{
|
||||
// Create the LConfig object
|
||||
$config = new $name;
|
||||
|
||||
// Load the configuration values into the registry
|
||||
$registry->loadObject($config);
|
||||
}
|
||||
|
||||
return $registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mailer object
|
||||
*
|
||||
* @return Mail object
|
||||
*
|
||||
* @see Mail
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function createMailer()
|
||||
{
|
||||
// $conf = self::getConfig();
|
||||
//
|
||||
// $smtpauth = ($conf->get('smtpauth') == 0) ? null : 1;
|
||||
// $smtpuser = $conf->get('smtpuser');
|
||||
// $smtppass = $conf->get('smtppass');
|
||||
// $smtphost = $conf->get('smtphost');
|
||||
// $smtpsecure = $conf->get('smtpsecure');
|
||||
// $smtpport = $conf->get('smtpport');
|
||||
// $mailfrom = $conf->get('mailfrom');
|
||||
// $fromname = $conf->get('fromname');
|
||||
// $mailer = $conf->get('mailer');
|
||||
//
|
||||
// // Create a Mail object
|
||||
// $mail = Mail::getInstance();
|
||||
//
|
||||
// // Clean the email address
|
||||
// $mailfrom = MailHelper::cleanLine($mailfrom);
|
||||
//
|
||||
// // Set default sender without Reply-to if the mailfrom is a valid address
|
||||
// if (MailHelper::isEmailAddress($mailfrom))
|
||||
// {
|
||||
// // Wrap in try/catch to catch phpmailerExceptions if it is throwing them
|
||||
// try
|
||||
// {
|
||||
// // Check for a false return value if exception throwing is disabled
|
||||
// if ($mail->setFrom($mailfrom, MailHelper::cleanLine($fromname), false) === false)
|
||||
// {
|
||||
// Log::add(__METHOD__ . '() could not set the sender data.', Log::WARNING, 'mail');
|
||||
// }
|
||||
// }
|
||||
// catch (phpmailerException $e)
|
||||
// {
|
||||
// Log::add(__METHOD__ . '() could not set the sender data.', Log::WARNING, 'mail');
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Default mailer is to use PHP's mail function
|
||||
// switch ($mailer)
|
||||
// {
|
||||
// case 'smtp':
|
||||
// $mail->useSmtp($smtpauth, $smtphost, $smtpuser, $smtppass, $smtpsecure, $smtpport);
|
||||
// break;
|
||||
//
|
||||
// case 'sendmail':
|
||||
// $mail->isSendmail();
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// $mail->isMail();
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// return $mail;
|
||||
}
|
||||
}
|
527
libraries/src/Filter/InputFilter.php
Normal file
527
libraries/src/Filter/InputFilter.php
Normal file
@ -0,0 +1,527 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Content Management System
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Filter;
|
||||
|
||||
use Kumwe\CMS\String\PunycodeHelper;
|
||||
use Joomla\Filter\InputFilter as BaseInputFilter;
|
||||
|
||||
/**
|
||||
* InputFilter is a class for filtering input from any data source
|
||||
*
|
||||
* Forked from the php input filter library by: Daniel Morris <dan@rootcube.com>
|
||||
* Original Contributors: Gianpaolo Racca, Ghislain Picard, Marco Wandschneider, Chris Tobin and Andrew Eddie.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
class InputFilter extends BaseInputFilter
|
||||
{
|
||||
/**
|
||||
* An array containing a list of extensions for files that are typically
|
||||
* executable directly in the webserver context, potentially resulting in code executions
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public const FORBIDDEN_FILE_EXTENSIONS = [
|
||||
'php', 'phps', 'pht', 'phtml', 'php3', 'php4', 'php5', 'php6', 'php7', 'asp',
|
||||
'php8', 'phar', 'inc', 'pl', 'cgi', 'fcgi', 'java', 'jar', 'py', 'aspx'
|
||||
];
|
||||
|
||||
/**
|
||||
* A flag for Unicode Supplementary Characters (4-byte Unicode character) stripping.
|
||||
*
|
||||
* @var integer
|
||||
* @since 3.5
|
||||
*/
|
||||
private $stripUSC = 0;
|
||||
|
||||
/**
|
||||
* A container for InputFilter instances.
|
||||
*
|
||||
* @var InputFilter[]
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected static $instances = array();
|
||||
/**
|
||||
* Constructor for inputFilter class. Only first parameter is required.
|
||||
*
|
||||
* @param array $tagsArray List of user-defined tags
|
||||
* @param array $attrArray List of user-defined attributes
|
||||
* @param integer $tagsMethod The constant static::ONLY_ALLOW_DEFINED_TAGS or static::BLOCK_DEFINED_TAGS
|
||||
* @param integer $attrMethod The constant static::ONLY_ALLOW_DEFINED_ATTRIBUTES or static::BLOCK_DEFINED_ATTRIBUTES
|
||||
* @param integer $xssAuto Only auto clean essentials = 0, Allow clean blocked tags/attributes = 1
|
||||
* @param integer $stripUSC Strip 4-byte unicode characters = 1, no strip = 0
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function __construct($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1, $stripUSC = 0)
|
||||
{
|
||||
parent::__construct($tagsArray, $attrArray, $tagsMethod, $attrMethod, $xssAuto);
|
||||
|
||||
// Assign member variables
|
||||
$this->stripUSC = $stripUSC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input filter object, only creating it if it doesn't already exist.
|
||||
*
|
||||
* @param array $tagsArray List of user-defined tags
|
||||
* @param array $attrArray List of user-defined attributes
|
||||
* @param integer $tagsMethod The constant static::ONLY_ALLOW_DEFINED_TAGS or static::BLOCK_DEFINED_TAGS
|
||||
* @param integer $attrMethod The constant static::ONLY_ALLOW_DEFINED_ATTRIBUTES or static::BLOCK_DEFINED_ATTRIBUTES
|
||||
* @param integer $xssAuto Only auto clean essentials = 0, Allow clean blocked tags/attributes = 1
|
||||
* @param integer $stripUSC Strip 4-byte unicode characters = 1, no strip = 0
|
||||
*
|
||||
* @return InputFilter The InputFilter object.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static function getInstance($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1, $stripUSC = 0)
|
||||
{
|
||||
$sig = md5(serialize(array($tagsArray, $attrArray, $tagsMethod, $attrMethod, $xssAuto)));
|
||||
|
||||
if (empty(self::$instances[$sig]))
|
||||
{
|
||||
self::$instances[$sig] = new InputFilter($tagsArray, $attrArray, $tagsMethod, $attrMethod, $xssAuto, $stripUSC);
|
||||
}
|
||||
|
||||
return self::$instances[$sig];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be called by another php script. Processes for XSS and
|
||||
* specified bad code.
|
||||
*
|
||||
* @param mixed $source Input string/array-of-string to be 'cleaned'
|
||||
* @param string $type The return type for the variable:
|
||||
* INT: An integer, or an array of integers,
|
||||
* UINT: An unsigned integer, or an array of unsigned integers,
|
||||
* FLOAT: A floating point number, or an array of floating point numbers,
|
||||
* BOOLEAN: A boolean value,
|
||||
* WORD: A string containing A-Z or underscores only (not case sensitive),
|
||||
* ALNUM: A string containing A-Z or 0-9 only (not case sensitive),
|
||||
* CMD: A string containing A-Z, 0-9, underscores, periods or hyphens (not case sensitive),
|
||||
* BASE64: A string containing A-Z, 0-9, forward slashes, plus or equals (not case sensitive),
|
||||
* STRING: A fully decoded and sanitised string (default),
|
||||
* HTML: A sanitised string,
|
||||
* ARRAY: An array,
|
||||
* PATH: A sanitised file path, or an array of sanitised file paths,
|
||||
* TRIM: A string trimmed from normal, non-breaking and multibyte spaces
|
||||
* USERNAME: Do not use (use an application specific filter),
|
||||
* RAW: The raw string is returned with no filtering,
|
||||
* unknown: An unknown filter will act like STRING. If the input is an array it will return an
|
||||
* array of fully decoded and sanitised strings.
|
||||
*
|
||||
* @return mixed 'Cleaned' version of input parameter
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function clean($source, $type = 'string')
|
||||
{
|
||||
// Strip Unicode Supplementary Characters when requested to do so
|
||||
if ($this->stripUSC)
|
||||
{
|
||||
// Alternatively: preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xE2\xAF\x91", $source) but it'd be slower.
|
||||
$source = $this->stripUSC($source);
|
||||
}
|
||||
|
||||
return parent::clean($source, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to punyencode utf8 mail when saving content
|
||||
*
|
||||
* @param string $text The strings to encode
|
||||
*
|
||||
* @return string The punyencoded mail
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public function emailToPunycode($text)
|
||||
{
|
||||
$pattern = '/(("mailto:)+[\w\.\-\+]+\@[^"?]+\.+[^."?]+("|\?))/';
|
||||
|
||||
if (preg_match_all($pattern, $text, $matches))
|
||||
{
|
||||
foreach ($matches[0] as $match)
|
||||
{
|
||||
$match = (string) str_replace(array('?', '"'), '', $match);
|
||||
$text = (string) str_replace($match, PunycodeHelper::emailToPunycode($match), $text);
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an uploaded for suspicious naming and potential PHP contents which could indicate a hacking attempt.
|
||||
*
|
||||
* The options you can define are:
|
||||
* null_byte Prevent files with a null byte in their name (buffer overflow attack)
|
||||
* forbidden_extensions Do not allow these strings anywhere in the file's extension
|
||||
* php_tag_in_content Do not allow `<?php` tag in content
|
||||
* phar_stub_in_content Do not allow the `__HALT_COMPILER()` phar stub in content
|
||||
* shorttag_in_content Do not allow short tag `<?` in content
|
||||
* shorttag_extensions Which file extensions to scan for short tags in content
|
||||
* fobidden_ext_in_content Do not allow forbidden_extensions anywhere in content
|
||||
* php_ext_content_extensions Which file extensions to scan for .php in content
|
||||
*
|
||||
* This code is an adaptation and improvement of Admin Tools' UploadShield feature,
|
||||
* relicensed and contributed by its author.
|
||||
*
|
||||
* @param array $file An uploaded file descriptor
|
||||
* @param array $options The scanner options (see the code for details)
|
||||
*
|
||||
* @return boolean True of the file is safe
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public static function isSafeFile($file, $options = array())
|
||||
{
|
||||
$defaultOptions = array(
|
||||
|
||||
// Null byte in file name
|
||||
'null_byte' => true,
|
||||
|
||||
// Forbidden string in extension (e.g. php matched .php, .xxx.php, .php.xxx and so on)
|
||||
'forbidden_extensions' => self::FORBIDDEN_FILE_EXTENSIONS,
|
||||
|
||||
// <?php tag in file contents
|
||||
'php_tag_in_content' => true,
|
||||
|
||||
// <? tag in file contents
|
||||
'shorttag_in_content' => true,
|
||||
|
||||
// __HALT_COMPILER()
|
||||
'phar_stub_in_content' => true,
|
||||
|
||||
// Which file extensions to scan for short tags
|
||||
'shorttag_extensions' => array(
|
||||
'inc', 'phps', 'class', 'php3', 'php4', 'php5', 'php6', 'php7', 'php8', 'txt', 'dat', 'tpl', 'tmpl',
|
||||
),
|
||||
|
||||
// Forbidden extensions anywhere in the content
|
||||
'fobidden_ext_in_content' => true,
|
||||
|
||||
// Which file extensions to scan for .php in the content
|
||||
'php_ext_content_extensions' => array('zip', 'rar', 'tar', 'gz', 'tgz', 'bz2', 'tbz', 'jpa'),
|
||||
);
|
||||
|
||||
$options = array_merge($defaultOptions, $options);
|
||||
|
||||
// Make sure we can scan nested file descriptors
|
||||
$descriptors = $file;
|
||||
|
||||
if (isset($file['name']) && isset($file['tmp_name']))
|
||||
{
|
||||
$descriptors = static::decodeFileData(
|
||||
array(
|
||||
$file['name'],
|
||||
$file['type'],
|
||||
$file['tmp_name'],
|
||||
$file['error'],
|
||||
$file['size'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Handle non-nested descriptors (single files)
|
||||
if (isset($descriptors['name']))
|
||||
{
|
||||
$descriptors = array($descriptors);
|
||||
}
|
||||
|
||||
// Scan all descriptors detected
|
||||
foreach ($descriptors as $fileDescriptor)
|
||||
{
|
||||
if (!isset($fileDescriptor['name']))
|
||||
{
|
||||
// This is a nested descriptor. We have to recurse.
|
||||
if (!static::isSafeFile($fileDescriptor, $options))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$tempNames = $fileDescriptor['tmp_name'];
|
||||
$intendedNames = $fileDescriptor['name'];
|
||||
|
||||
if (!\is_array($tempNames))
|
||||
{
|
||||
$tempNames = array($tempNames);
|
||||
}
|
||||
|
||||
if (!\is_array($intendedNames))
|
||||
{
|
||||
$intendedNames = array($intendedNames);
|
||||
}
|
||||
|
||||
$len = \count($tempNames);
|
||||
|
||||
for ($i = 0; $i < $len; $i++)
|
||||
{
|
||||
$tempName = array_shift($tempNames);
|
||||
$intendedName = array_shift($intendedNames);
|
||||
|
||||
// 1. Null byte check
|
||||
if ($options['null_byte'])
|
||||
{
|
||||
if (strstr($intendedName, "\x00"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. PHP-in-extension check (.php, .php.xxx[.yyy[.zzz[...]]], .xxx[.yyy[.zzz[...]]].php)
|
||||
if (!empty($options['forbidden_extensions']))
|
||||
{
|
||||
$explodedName = explode('.', $intendedName);
|
||||
$explodedName = array_reverse($explodedName);
|
||||
array_pop($explodedName);
|
||||
$explodedName = array_map('strtolower', $explodedName);
|
||||
|
||||
/*
|
||||
* DO NOT USE array_intersect HERE! array_intersect expects the two arrays to
|
||||
* be set, i.e. they should have unique values.
|
||||
*/
|
||||
foreach ($options['forbidden_extensions'] as $ext)
|
||||
{
|
||||
if (\in_array($ext, $explodedName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. File contents scanner (PHP tag in file contents)
|
||||
if ($options['php_tag_in_content']
|
||||
|| $options['shorttag_in_content'] || $options['phar_stub_in_content']
|
||||
|| ($options['fobidden_ext_in_content'] && !empty($options['forbidden_extensions'])))
|
||||
{
|
||||
$fp = strlen($tempName) ? @fopen($tempName, 'r') : false;
|
||||
|
||||
if ($fp !== false)
|
||||
{
|
||||
$data = '';
|
||||
|
||||
while (!feof($fp))
|
||||
{
|
||||
$data .= @fread($fp, 131072);
|
||||
|
||||
if ($options['php_tag_in_content'] && stripos($data, '<?php') !== false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($options['phar_stub_in_content'] && stripos($data, '__HALT_COMPILER()') !== false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($options['shorttag_in_content'])
|
||||
{
|
||||
$suspiciousExtensions = $options['shorttag_extensions'];
|
||||
|
||||
if (empty($suspiciousExtensions))
|
||||
{
|
||||
$suspiciousExtensions = array(
|
||||
'inc', 'phps', 'class', 'php3', 'php4', 'txt', 'dat', 'tpl', 'tmpl',
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* DO NOT USE array_intersect HERE! array_intersect expects the two arrays to
|
||||
* be set, i.e. they should have unique values.
|
||||
*/
|
||||
$collide = false;
|
||||
|
||||
foreach ($suspiciousExtensions as $ext)
|
||||
{
|
||||
if (\in_array($ext, $explodedName))
|
||||
{
|
||||
$collide = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($collide)
|
||||
{
|
||||
// These are suspicious text files which may have the short tag (<?) in them
|
||||
if (strstr($data, '<?'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($options['fobidden_ext_in_content'] && !empty($options['forbidden_extensions']))
|
||||
{
|
||||
$suspiciousExtensions = $options['php_ext_content_extensions'];
|
||||
|
||||
if (empty($suspiciousExtensions))
|
||||
{
|
||||
$suspiciousExtensions = array(
|
||||
'zip', 'rar', 'tar', 'gz', 'tgz', 'bz2', 'tbz', 'jpa',
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* DO NOT USE array_intersect HERE! array_intersect expects the two arrays to
|
||||
* be set, i.e. they should have unique values.
|
||||
*/
|
||||
$collide = false;
|
||||
|
||||
foreach ($suspiciousExtensions as $ext)
|
||||
{
|
||||
if (\in_array($ext, $explodedName))
|
||||
{
|
||||
$collide = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($collide)
|
||||
{
|
||||
/*
|
||||
* These are suspicious text files which may have an executable
|
||||
* file extension in them
|
||||
*/
|
||||
foreach ($options['forbidden_extensions'] as $ext)
|
||||
{
|
||||
if (strstr($data, '.' . $ext))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This makes sure that we don't accidentally skip a <?php tag if it's across
|
||||
* a read boundary, even on multibyte strings
|
||||
*/
|
||||
$data = substr($data, -10);
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to decode a file data array.
|
||||
*
|
||||
* @param array $data The data array to decode.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
protected static function decodeFileData(array $data)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
if (\is_array($data[0]))
|
||||
{
|
||||
foreach ($data[0] as $k => $v)
|
||||
{
|
||||
$result[$k] = static::decodeFileData(array($data[0][$k], $data[1][$k], $data[2][$k], $data[3][$k], $data[4][$k]));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return array('name' => $data[0], 'type' => $data[1], 'tmp_name' => $data[2], 'error' => $data[3], 'size' => $data[4]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to convert to plaintext
|
||||
*
|
||||
* @param string $source The source string.
|
||||
*
|
||||
* @return string Plaintext string
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
protected function decode($source)
|
||||
{
|
||||
static $ttr;
|
||||
|
||||
if (!\is_array($ttr))
|
||||
{
|
||||
// Entity decode
|
||||
$trans_tbl = get_html_translation_table(HTML_ENTITIES, ENT_COMPAT, 'ISO-8859-1');
|
||||
|
||||
foreach ($trans_tbl as $k => $v)
|
||||
{
|
||||
$ttr[$v] = utf8_encode($k);
|
||||
}
|
||||
}
|
||||
|
||||
$source = strtr($source, $ttr);
|
||||
|
||||
// Convert decimal
|
||||
$source = preg_replace_callback(
|
||||
'/&#(\d+);/m',
|
||||
function ($m) {
|
||||
return utf8_encode(\chr($m[1]));
|
||||
},
|
||||
$source
|
||||
);
|
||||
|
||||
// Convert hex
|
||||
$source = preg_replace_callback(
|
||||
'/&#x([a-f0-9]+);/mi',
|
||||
function ($m) {
|
||||
return utf8_encode(\chr('0x' . $m[1]));
|
||||
},
|
||||
$source
|
||||
);
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively strip Unicode Supplementary Characters from the source. Not: objects cannot be filtered.
|
||||
*
|
||||
* @param mixed $source The data to filter
|
||||
*
|
||||
* @return mixed The filtered result
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
protected function stripUSC($source)
|
||||
{
|
||||
if (\is_object($source))
|
||||
{
|
||||
return $source;
|
||||
}
|
||||
|
||||
if (\is_array($source))
|
||||
{
|
||||
$filteredArray = array();
|
||||
|
||||
foreach ($source as $k => $v)
|
||||
{
|
||||
$filteredArray[$k] = $this->stripUSC($v);
|
||||
}
|
||||
|
||||
return $filteredArray;
|
||||
}
|
||||
|
||||
return preg_replace('/[\xF0-\xF7].../s', "\xE2\xAF\x91", $source);
|
||||
}
|
||||
}
|
47
libraries/src/Model/DashboardModel.php
Normal file
47
libraries/src/Model/DashboardModel.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Model/PackageModel.php
|
||||
*/
|
||||
class DashboardModel implements DatabaseModelInterface
|
||||
{
|
||||
use DatabaseModelTrait;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an active dashboard template name
|
||||
*
|
||||
* @param string $dashboardName The dashboard to lookup
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getDashboard(string $dashboardName): string
|
||||
{
|
||||
return 'dashboard.twig'; // only one at this time
|
||||
}
|
||||
}
|
287
libraries/src/Model/ItemModel.php
Normal file
287
libraries/src/Model/ItemModel.php
Normal file
@ -0,0 +1,287 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
use Kumwe\CMS\Date\Date;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class ItemModel implements DatabaseModelInterface
|
||||
{
|
||||
use DatabaseModelTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $tempItem;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $title
|
||||
* @param string $introtext
|
||||
* @param string $fulltext
|
||||
* @param int $state
|
||||
* @param string $created
|
||||
* @param int $createdBy
|
||||
* @param string $createdByAlias
|
||||
* @param string $modified
|
||||
* @param int $modifiedBy
|
||||
* @param string $publishUp
|
||||
* @param string $publishDown
|
||||
* @param string $metakey
|
||||
* @param string $metadesc
|
||||
* @param string $metadata
|
||||
* @param int $featured
|
||||
*
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setItem(
|
||||
int $id,
|
||||
string $title,
|
||||
string $fulltext,
|
||||
int $state,
|
||||
string $created,
|
||||
int $createdBy,
|
||||
string $createdByAlias,
|
||||
string $modified,
|
||||
int $modifiedBy,
|
||||
string $publishUp,
|
||||
string $publishDown,
|
||||
string $metakey,
|
||||
string $metadesc,
|
||||
string $metadata,
|
||||
int $featured): int
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
// extract the intro text
|
||||
$introtext = '';
|
||||
if (strpos($fulltext, '<p>intro-text</p>'))
|
||||
{
|
||||
$bucket = explode('<p>intro-text</p>', $fulltext);
|
||||
$introtext = array_shift($bucket);
|
||||
$fulltext = implode('', $bucket);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'title' => (string) $title,
|
||||
'introtext' => (string) $introtext,
|
||||
'fulltext' => (string) $fulltext,
|
||||
'state' => (int) $state,
|
||||
'created' => (string) $created,
|
||||
'created_by' => (int) $createdBy,
|
||||
'created_by_alias' => (string) $createdByAlias,
|
||||
'modified' => (string) $modified,
|
||||
'modified_by' => (int) $modifiedBy,
|
||||
'publish_up' => (string) (empty($publishUp)) ? '0000-00-00 00:00:00' : (new Date($publishUp))->toSql(),
|
||||
'publish_down' => (string) (empty($publishDown)) ? '0000-00-00 00:00:00' : (new Date($publishDown))->toSql(),
|
||||
'metakey' => (string) $metakey,
|
||||
'metadesc' => (string) $metadesc,
|
||||
'metadata' => (string) $metadata,
|
||||
'featured' => (int) $featured
|
||||
];
|
||||
|
||||
// if we have ID update
|
||||
if ($id > 0)
|
||||
{
|
||||
$data['id'] = (int) $id;
|
||||
// remove what can not now be set
|
||||
unset($data['created']);
|
||||
unset($data['created_by']);
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->updateObject('#__item', $data, 'id');
|
||||
}
|
||||
catch (\RuntimeException $exception)
|
||||
{
|
||||
throw new \RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
|
||||
return $id;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove what can not now be set
|
||||
$data['modified'] = '0000-00-00 00:00:00';
|
||||
$data['modified_by'] = 0;
|
||||
// we don't have any params for now
|
||||
$data['params'] = '';
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->insertObject('#__item', $data);
|
||||
}
|
||||
catch (\RuntimeException $exception)
|
||||
{
|
||||
throw new \RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
|
||||
return $db->insertid();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item
|
||||
*
|
||||
* @param int|null $id
|
||||
*
|
||||
* @return \stdClass
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getItem(?int $id): \stdClass
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// default object (use posted values if set)
|
||||
if (is_array($this->tempItem))
|
||||
{
|
||||
$default = (object) $this->tempItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
$default = new \stdClass();
|
||||
}
|
||||
// to be sure ;)
|
||||
$default->today_date = (new Date())->toSql();
|
||||
$default->post_key = "?task=create";
|
||||
$default->state = 1;
|
||||
|
||||
// we return the default if id not correct
|
||||
if (!is_numeric($id))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__item'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER)
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$result = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// we ignore this and just return an empty object
|
||||
}
|
||||
|
||||
if (isset($result) && $result instanceof \stdClass)
|
||||
{
|
||||
$result->post_key = "?id=$id&task=edit";
|
||||
$result->today_date = $default->today_date;
|
||||
// check if we have intro text we add it to full text
|
||||
if (!empty($result->introtext))
|
||||
{
|
||||
$result->fulltext = $result->introtext . '<p>intro-text</p>' . $result->fulltext;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function linked(int $id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// first check if this item is linked to menu
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('title'))
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where($db->quoteName('item_id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
|
||||
try
|
||||
{
|
||||
$menu = $db->setQuery($query)->loadResult();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// not linked... or something
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($menu)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(int $id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
// Purge the session
|
||||
$query = $db->getQuery(true)
|
||||
->delete($db->quoteName('#__item'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
try
|
||||
{
|
||||
$db->setQuery($query)->execute();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// delete failed
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
54
libraries/src/Model/ItemsModel.php
Normal file
54
libraries/src/Model/ItemsModel.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class ItemsModel implements DatabaseModelInterface
|
||||
{
|
||||
use DatabaseModelTrait;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__item'));
|
||||
|
||||
return $db->setQuery($query)->loadObjectList('id');
|
||||
}
|
||||
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
}
|
353
libraries/src/Model/MenuModel.php
Normal file
353
libraries/src/Model/MenuModel.php
Normal file
@ -0,0 +1,353 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
use Kumwe\CMS\Date\Date;
|
||||
use Kumwe\CMS\Model\Util\MenuInterface;
|
||||
use Kumwe\CMS\Model\Util\SelectMenuTrait;
|
||||
use Kumwe\CMS\Model\Util\UniqueInterface;
|
||||
use Kumwe\CMS\Model\Util\UniqueMenuAliasTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class MenuModel implements DatabaseModelInterface, UniqueInterface, MenuInterface
|
||||
{
|
||||
use DatabaseModelTrait, UniqueMenuAliasTrait, SelectMenuTrait;
|
||||
|
||||
/**
|
||||
* Active id
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $id = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $tempItem;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $title
|
||||
* @param string $alias
|
||||
* @param int $itemId
|
||||
* @param string $path
|
||||
* @param int $published
|
||||
* @param string $publishUp
|
||||
* @param string $publishDown
|
||||
* @param string $position
|
||||
* @param int $home
|
||||
* @param int $parent
|
||||
*
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setItem(
|
||||
int $id,
|
||||
string $title,
|
||||
string $alias,
|
||||
int $itemId,
|
||||
string $path,
|
||||
int $published,
|
||||
string $publishUp,
|
||||
string $publishDown,
|
||||
string $position,
|
||||
int $home,
|
||||
int $parent): int
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
// set the alias if not set
|
||||
$alias = (empty($alias)) ? $title : $alias;
|
||||
$alias = $this->unique($id, $alias, $parent);
|
||||
// set the path
|
||||
$path = $this->getPath($alias, $parent);
|
||||
|
||||
$data = [
|
||||
'title' => (string) $title,
|
||||
'alias' => (string) $alias,
|
||||
'path' => (string) $path,
|
||||
'item_id' => (int) $itemId,
|
||||
'published' => (int) $published,
|
||||
'publish_up' => (string) (empty($publishUp)) ? '0000-00-00 00:00:00' : (new Date($publishUp))->toSql(),
|
||||
'publish_down' => (string) (empty($publishDown)) ? '0000-00-00 00:00:00' : (new Date($publishDown))->toSql(),
|
||||
'home' => (int) $home,
|
||||
'parent_id' => (int) $parent
|
||||
];
|
||||
|
||||
// we set position in params
|
||||
$data['params'] = json_encode(['position' => $position]);
|
||||
|
||||
// if we have ID update
|
||||
if ($id > 0)
|
||||
{
|
||||
// set active ID
|
||||
$data['id'] = (int) $id;
|
||||
$this->id = (int) $id;
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->updateObject('#__menu', $data, 'id');
|
||||
}
|
||||
catch (\RuntimeException $exception)
|
||||
{
|
||||
throw new \RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->insertObject('#__menu', $data);
|
||||
}
|
||||
catch (\RuntimeException $exception)
|
||||
{
|
||||
throw new \RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
|
||||
$id = $db->insertid();
|
||||
}
|
||||
|
||||
// check if we have another home set
|
||||
if ($data->home == 1)
|
||||
{
|
||||
$this->setHome($id);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all published items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(array('id', 'title')))
|
||||
->from($db->quoteName('#__item'))
|
||||
->where('state = 1');
|
||||
|
||||
return $db->setQuery($query)->loadObjectList('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item
|
||||
*
|
||||
* @param int|null $id
|
||||
*
|
||||
* @return \stdClass
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getItem(?int $id): \stdClass
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// default object (use posted values if set)
|
||||
if (is_array($this->tempItem))
|
||||
{
|
||||
$default = (object) $this->tempItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
$default = new \stdClass();
|
||||
}
|
||||
// to be sure ;)
|
||||
$default->today_date = (new Date())->toSql();
|
||||
$default->post_key = "?task=create";
|
||||
$default->published = 1;
|
||||
$default->home = 0;
|
||||
|
||||
// we return the default if id not correct
|
||||
if (!is_numeric($id))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER)
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$result = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// we ignore this and just return an empty object
|
||||
}
|
||||
|
||||
if (isset($result) && $result instanceof \stdClass)
|
||||
{
|
||||
$result->post_key = "?id=$id&task=edit";
|
||||
$result->today_date = $default->today_date;
|
||||
// set the position
|
||||
$result->params = json_decode($result->params);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(int $id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// Purge the session
|
||||
$query = $db->getQuery(true)
|
||||
->delete($db->quoteName('#__menu'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
try
|
||||
{
|
||||
$db->setQuery($query)->execute();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// delete failed
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that we have only one home
|
||||
*
|
||||
* @param $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function setHome($id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// Purge the session
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__menu'))
|
||||
->set($db->quoteName('home') . ' = 0')
|
||||
->where($db->quoteName('id') . ' != :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
try
|
||||
{
|
||||
$db->setQuery($query)->execute();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// delete failed
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* get path
|
||||
*
|
||||
* @param string $alias
|
||||
* @param int $parent
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getPath(string $alias, int $parent): string
|
||||
{
|
||||
// alias bucket
|
||||
$bucket = [];
|
||||
$bucket[] = $alias;
|
||||
$parent = $this->getParent($parent);
|
||||
// make sure to get all path aliases TODO: we should limit the menu depth to 6 or something
|
||||
while (isset($parent->alias))
|
||||
{
|
||||
// load the alias
|
||||
$bucket[] = $parent->alias;
|
||||
// get the next parent
|
||||
$parent = $this->getParent($parent->parent_id);
|
||||
}
|
||||
// now return the path
|
||||
return implode('/', array_reverse($bucket));
|
||||
}
|
||||
|
||||
/**
|
||||
* get parent
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return \stdClass
|
||||
*/
|
||||
private function getParent(int $id): \stdClass
|
||||
{
|
||||
if ($id > 0)
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id)
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$parent = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// we ignore this and just return an empty object
|
||||
}
|
||||
|
||||
// return only if found
|
||||
if (isset($parent) && $parent instanceof \stdClass)
|
||||
{
|
||||
return $parent;
|
||||
}
|
||||
}
|
||||
return new \stdClass();
|
||||
}
|
||||
}
|
62
libraries/src/Model/MenusModel.php
Normal file
62
libraries/src/Model/MenusModel.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class MenusModel implements DatabaseModelInterface
|
||||
{
|
||||
use DatabaseModelTrait;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('a.*')
|
||||
->select($db->quoteName(array('t.title'), array('item_title')))
|
||||
->from($db->quoteName('#__menu', 'a'))
|
||||
->join('INNER', $db->quoteName('#__item', 't'), 'a.item_id = t.id');
|
||||
|
||||
return $db->setQuery($query)->loadObjectList('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
}
|
98
libraries/src/Model/PageModel.php
Normal file
98
libraries/src/Model/PageModel.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
use Kumwe\CMS\Model\Util\MenuInterface;
|
||||
use Kumwe\CMS\Model\Util\PageInterface;
|
||||
use Kumwe\CMS\Model\Util\HomeMenuInterface;
|
||||
use Kumwe\CMS\Model\Util\HomeMenuTrait;
|
||||
use Kumwe\CMS\Model\Util\SiteMenuTrait;
|
||||
use Kumwe\CMS\Model\Util\SitePageTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class PageModel implements DatabaseModelInterface, MenuInterface, PageInterface, HomeMenuInterface
|
||||
{
|
||||
use DatabaseModelTrait, HomeMenuTrait, SiteMenuTrait, SitePageTrait;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get all date needed for the view
|
||||
*
|
||||
* @param string|null $page
|
||||
*
|
||||
* @return array The data needed
|
||||
*/
|
||||
public function getData(?string $page): array
|
||||
{
|
||||
// set the defaults
|
||||
$data = (object) [
|
||||
// main title
|
||||
'title' => 'Error',
|
||||
// menus
|
||||
'menus' => [],
|
||||
// menu ID
|
||||
'menu_id' => 0,
|
||||
// is this the home page
|
||||
'menu_home' => false,
|
||||
// home page title
|
||||
'home_menu_title' => 'Home'
|
||||
];
|
||||
// we check if we have a home page
|
||||
$home_page = $this->getHomePage();
|
||||
// get the page data
|
||||
if (empty($page) && isset($home_page->item_id) && $home_page->item_id > 0)
|
||||
{
|
||||
// this is the home menu
|
||||
$data = $this->getPageItemById($home_page->item_id);
|
||||
$data->menu_home = true;
|
||||
}
|
||||
elseif (!empty($page))
|
||||
{
|
||||
$data = $this->getPageItemByPath($page);
|
||||
}
|
||||
// load the home menu title
|
||||
if (isset($home_page->title))
|
||||
{
|
||||
$data->home_menu_title = $home_page->title;
|
||||
}
|
||||
// check if we found any data
|
||||
if (isset($data->id))
|
||||
{
|
||||
// check if we have intro text we add it to full text
|
||||
if (!empty($data->introtext))
|
||||
{
|
||||
$data->fulltext = $data->introtext . $data->fulltext;
|
||||
}
|
||||
}
|
||||
|
||||
// set the menus if possible
|
||||
if (isset($data->menu_id) && $data->menu_id > 0)
|
||||
{
|
||||
$data->menus = $this->getMenus($data->menu_id);
|
||||
}
|
||||
|
||||
return (array) $data;
|
||||
}
|
||||
}
|
337
libraries/src/Model/UserModel.php
Normal file
337
libraries/src/Model/UserModel.php
Normal file
@ -0,0 +1,337 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
use Kumwe\CMS\Date\Date;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsInterface;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsTrait;
|
||||
use Exception;
|
||||
use RuntimeException;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class UserModel implements DatabaseModelInterface, GetUsergroupsInterface
|
||||
{
|
||||
use DatabaseModelTrait, GetUsergroupsTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $tempItem;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver|null $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db = null)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $name
|
||||
* @param string $username
|
||||
* @param array $groups
|
||||
* @param string $email
|
||||
* @param string $password
|
||||
* @param int $block
|
||||
* @param int $sendEmail
|
||||
* @param string $registerDate
|
||||
* @param int $activation
|
||||
*
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public function setItem(
|
||||
int $id,
|
||||
string $name,
|
||||
string $username,
|
||||
array $groups,
|
||||
string $email,
|
||||
string $password,
|
||||
int $block,
|
||||
int $sendEmail,
|
||||
string $registerDate,
|
||||
int $activation): int
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$data = [
|
||||
'name' => (string) $name,
|
||||
'username' => (string) $username,
|
||||
'email' => (string) $email,
|
||||
'block' => (int) $block,
|
||||
'sendEmail' => (int) $sendEmail,
|
||||
'registerDate' => (string) (empty($registerDate)) ? (new Date())->toSql() : (new Date($registerDate))->toSql(),
|
||||
'activation' => (int) $activation
|
||||
];
|
||||
|
||||
// only update password if set
|
||||
if (!empty($password) && strlen($password) > 6)
|
||||
{
|
||||
$data['password'] = (string) $password;
|
||||
}
|
||||
|
||||
// if we have ID update
|
||||
if ($id > 0)
|
||||
{
|
||||
$data['id'] = (int) $id;
|
||||
// we remove registration date when we update the user
|
||||
unset($data['registerDate']);
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->updateObject('#__users', $data, 'id');
|
||||
}
|
||||
catch (RuntimeException $exception)
|
||||
{
|
||||
throw new RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't have any params for now
|
||||
$data['params'] = '';
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->insertObject('#__users', $data);
|
||||
}
|
||||
catch (RuntimeException $exception)
|
||||
{
|
||||
throw new RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
|
||||
$id = $db->insertid();
|
||||
}
|
||||
|
||||
// update the group linked to this user
|
||||
// only if there are groups
|
||||
if (count($groups) > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->setGroups($id, $groups);
|
||||
}
|
||||
catch (RuntimeException $exception)
|
||||
{
|
||||
throw new RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add groups for this user
|
||||
*
|
||||
* @param int $id
|
||||
* @param array $groups
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
private function setGroups(int $id, array $groups): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// add the new groups
|
||||
$query = $db->getQuery(true)
|
||||
->insert($db->quoteName('#__user_usergroup_map'))
|
||||
->columns($db->quoteName(['user_id', 'group_id']));
|
||||
// Insert values.
|
||||
foreach ($groups as $group)
|
||||
{
|
||||
$query->values(implode(',', [(int) $id, (int) $group]));
|
||||
}
|
||||
// execute the update/change
|
||||
try
|
||||
{
|
||||
// delete link to groups
|
||||
if ($this->deleteGroups($id))
|
||||
{
|
||||
// add the new groups
|
||||
$db->setQuery($query)->execute();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
throw new RuntimeException($e->getMessage(), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item
|
||||
*
|
||||
* @param int|null $id
|
||||
*
|
||||
* @return stdClass
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getItem(?int $id): stdClass
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// default object (use posted values if set)
|
||||
if (is_array($this->tempItem))
|
||||
{
|
||||
$default = (object) $this->tempItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
$default = new stdClass();
|
||||
}
|
||||
// to be sure ;)
|
||||
$default->today_date = (new Date())->toSql();
|
||||
$default->post_key = "?task=create";
|
||||
$default->block = 0;
|
||||
$default->activation = 1;
|
||||
$default->sendEmail = 1;
|
||||
// always remove password
|
||||
$default->password = 'xxxxxxxxxx';
|
||||
$default->password2 = 'xxxxxxxxxx';
|
||||
|
||||
// we return the default if id not correct
|
||||
if (!is_numeric($id))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__users'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER)
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$result = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
// we ignore this and just return an empty object
|
||||
}
|
||||
|
||||
if (isset($result) && $result instanceof stdClass && isset($result->id))
|
||||
{
|
||||
$result->post_key = "?id=$id&task=edit";
|
||||
$result->today_date = $default->today_date;
|
||||
// always remove password
|
||||
$result->password = $default->password;
|
||||
$result->password2 = $default->password2;
|
||||
|
||||
// Initialise some variables
|
||||
$query = $db->getQuery(true)
|
||||
->select('m.group_id')
|
||||
->from($db->quoteName('#__user_usergroup_map', 'm'))
|
||||
->where($db->quoteName('m.user_id') . ' = :user_id')
|
||||
->bind(':user_id', $result->id, ParameterType::INTEGER);
|
||||
|
||||
try
|
||||
{
|
||||
// we just load the ID's
|
||||
$result->groups = $db->setQuery($query)->loadColumn();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
// we ignore this and just return result
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function delete(int $id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// Delete the user from the database
|
||||
$query = $db->getQuery(true)
|
||||
->delete($db->quoteName('#__users'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
try
|
||||
{
|
||||
// delete link to groups
|
||||
if ($this->deleteGroups($id))
|
||||
{
|
||||
// delete user
|
||||
$db->setQuery($query)->execute();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
throw new RuntimeException($e->getMessage(), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete all groups form this user
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deleteGroups(int $id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// Delete the user from the database
|
||||
$query = $db->getQuery(true)
|
||||
->delete($db->quoteName('#__user_usergroup_map'))
|
||||
->where($db->quoteName('user_id') . ' = :user_id')
|
||||
->bind(':user_id', $id, ParameterType::INTEGER);
|
||||
try
|
||||
{
|
||||
$db->setQuery($query)->execute();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
throw new RuntimeException($e->getMessage(), 404);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
239
libraries/src/Model/UsergroupModel.php
Normal file
239
libraries/src/Model/UsergroupModel.php
Normal file
@ -0,0 +1,239 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 21th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsInterface;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class UsergroupModel implements DatabaseModelInterface, GetUsergroupsInterface
|
||||
{
|
||||
use DatabaseModelTrait, GetUsergroupsTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $tempItem;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $title
|
||||
* @param array $params
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function setItem(
|
||||
int $id,
|
||||
string $title,
|
||||
array $params): int
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
if (count($params) > 0)
|
||||
{
|
||||
$params = json_encode($params);
|
||||
}
|
||||
else
|
||||
{
|
||||
$params = '';
|
||||
}
|
||||
|
||||
$data = [
|
||||
'title' => (string) $title,
|
||||
'params' => (string) $params
|
||||
];
|
||||
|
||||
// if we have ID update
|
||||
if ($id > 0)
|
||||
{
|
||||
$data['id'] = (int) $id;
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->updateObject('#__usergroups', $data, 'id');
|
||||
}
|
||||
catch (\RuntimeException $exception)
|
||||
{
|
||||
throw new \RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
|
||||
return $id;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// change to object
|
||||
$data = (object) $data;
|
||||
|
||||
try
|
||||
{
|
||||
$db->insertObject('#__usergroups', $data);
|
||||
}
|
||||
catch (\RuntimeException $exception)
|
||||
{
|
||||
throw new \RuntimeException($exception->getMessage(), 404);
|
||||
}
|
||||
|
||||
return $db->insertid();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item
|
||||
*
|
||||
* @param int|null $id
|
||||
*
|
||||
* @return \stdClass
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getItem(?int $id): \stdClass
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// default object (use posted values if set)
|
||||
if (is_array($this->tempItem))
|
||||
{
|
||||
$default = (object) $this->tempItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
$default = new \stdClass();
|
||||
$default->params = $this->getGroupDefaultsAccess();
|
||||
}
|
||||
|
||||
// we return the default if id not correct
|
||||
if (!is_numeric($id))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__usergroups'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER)
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$result = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// we ignore this and just return an empty object
|
||||
}
|
||||
|
||||
if (isset($result) && $result instanceof \stdClass)
|
||||
{
|
||||
$result->post_key = "?id=$id&task=edit";
|
||||
|
||||
// make sure to set the params
|
||||
$result->params = json_decode($result->params);
|
||||
// We set an empty default
|
||||
if (!is_array($result->params))
|
||||
{
|
||||
$result->params = $this->getGroupDefaultsAccess();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(int $id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// Purge the session
|
||||
$query = $db->getQuery(true)
|
||||
->delete($db->quoteName('#__usergroups'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
try
|
||||
{
|
||||
$db->setQuery($query)->execute();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// delete failed
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function linked(int $id): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
// first check if this item is linked to menu
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('user_id'))
|
||||
->from($db->quoteName('#__user_usergroup_map'))
|
||||
->where($db->quoteName('group_id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
|
||||
try
|
||||
{
|
||||
$users = $db->setQuery($query)->loadColumn();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// not linked... or something
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($users)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
50
libraries/src/Model/UsergroupsModel.php
Normal file
50
libraries/src/Model/UsergroupsModel.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 21th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsInterface;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class UsergroupsModel implements DatabaseModelInterface, GetUsergroupsInterface
|
||||
{
|
||||
use DatabaseModelTrait, GetUsergroupsTrait;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->getUsergroups();
|
||||
}
|
||||
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
}
|
67
libraries/src/Model/UsersModel.php
Normal file
67
libraries/src/Model/UsersModel.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model;
|
||||
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Model\DatabaseModelInterface;
|
||||
use Joomla\Model\DatabaseModelTrait;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsInterface;
|
||||
use Kumwe\CMS\Model\Util\GetUsergroupsTrait;
|
||||
|
||||
/**
|
||||
* Model class
|
||||
*/
|
||||
class UsersModel implements DatabaseModelInterface, GetUsergroupsInterface
|
||||
{
|
||||
use DatabaseModelTrait, GetUsergroupsTrait;
|
||||
|
||||
/**
|
||||
* Instantiate the model.
|
||||
*
|
||||
* @param DatabaseDriver $db The database adapter.
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db)
|
||||
{
|
||||
$this->setDb($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('*')
|
||||
->from($db->quoteName('#__users'));
|
||||
|
||||
$users = $db->setQuery($query)->loadObjectList('id');
|
||||
|
||||
// add groups
|
||||
if ($users)
|
||||
{
|
||||
foreach ($users as $id => &$user)
|
||||
{
|
||||
$user->groups = $this->getUsergroups($id);
|
||||
}
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
public function setLayout(string $name): string
|
||||
{
|
||||
return $name . '.twig';
|
||||
}
|
||||
}
|
37
libraries/src/Model/Util/GetUsergroupsInterface.php
Normal file
37
libraries/src/Model/Util/GetUsergroupsInterface.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 23th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
/**
|
||||
* Class for all user groups
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface GetUsergroupsInterface
|
||||
{
|
||||
/**
|
||||
* Get all user groups
|
||||
*
|
||||
* @param int|null $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUsergroups(?int $id = null): array;
|
||||
|
||||
/**
|
||||
* Get the group default full access values
|
||||
*
|
||||
* @param string $access
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupDefaultsAccess(string $access = 'CRUD'): array;
|
||||
}
|
103
libraries/src/Model/Util/GetUsergroupsTrait.php
Normal file
103
libraries/src/Model/Util/GetUsergroupsTrait.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 23th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
use Joomla\Database\ParameterType;
|
||||
use Kumwe\CMS\Utilities\StringHelper;
|
||||
use RuntimeException;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class for all user groups
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @method getDb()
|
||||
*/
|
||||
trait GetUsergroupsTrait
|
||||
{
|
||||
/**
|
||||
* Get all user groups
|
||||
*
|
||||
* @param int|null $id user ID
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUsergroups(?int $id = null): array
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('g.*')
|
||||
->from($db->quoteName('#__usergroups', 'g'));
|
||||
|
||||
if ($id > 0)
|
||||
{
|
||||
$query
|
||||
->join('INNER', $db->quoteName('#__user_usergroup_map', 'm'), 'g.id = m.group_id')
|
||||
->where($db->quoteName('m.user_id') . ' = :user_id')
|
||||
->bind(':user_id', $id, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$groups = $db->setQuery($query)->loadObjectList('id');
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
throw new RuntimeException($e->getMessage(), 404);
|
||||
}
|
||||
|
||||
if (is_array($groups) && count($groups) > 0)
|
||||
{
|
||||
foreach ($groups as $n => &$group)
|
||||
{
|
||||
$group->params = json_decode($group->params);
|
||||
// We set an empty default
|
||||
if (!is_array($group->params))
|
||||
{
|
||||
$group->params = $this->getGroupDefaultsAccess();
|
||||
}
|
||||
}
|
||||
return $groups;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the group default full access values
|
||||
*
|
||||
* @param string $access
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupDefaultsAccess(string $access = ''): array
|
||||
{
|
||||
return [
|
||||
(object) [
|
||||
'area' => 'user',
|
||||
'access' => $access
|
||||
],
|
||||
(object) [
|
||||
'area' => 'usergroup',
|
||||
'access' => $access
|
||||
],
|
||||
(object) [
|
||||
'area' => 'menu',
|
||||
'access' => $access
|
||||
],
|
||||
(object) [
|
||||
'area' => 'item',
|
||||
'access' => $access
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
24
libraries/src/Model/Util/HomeMenuInterface.php
Normal file
24
libraries/src/Model/Util/HomeMenuInterface.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 21th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
/**
|
||||
* Class for getting the home page
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface HomeMenuInterface
|
||||
{
|
||||
/**
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getHomePage(): \stdClass;
|
||||
}
|
51
libraries/src/Model/Util/HomeMenuTrait.php
Normal file
51
libraries/src/Model/Util/HomeMenuTrait.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 21th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
/**
|
||||
* Trait for getting home menu
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait HomeMenuTrait
|
||||
{
|
||||
/**
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function getHomePage(): \stdClass
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('a.*')
|
||||
->from($db->quoteName('#__menu', 'a'))
|
||||
->where($db->quoteName('a.parent_id') . ' = 0')
|
||||
->where($db->quoteName('a.published') . ' = 1')
|
||||
->where($db->quoteName('a.home') . ' = 1')
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$home = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
return new \stdClass();
|
||||
}
|
||||
|
||||
if ($home)
|
||||
{
|
||||
return $home;
|
||||
}
|
||||
|
||||
return new \stdClass();
|
||||
}
|
||||
}
|
28
libraries/src/Model/Util/MenuInterface.php
Normal file
28
libraries/src/Model/Util/MenuInterface.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
/**
|
||||
* Class for getting menu items
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface MenuInterface
|
||||
{
|
||||
/**
|
||||
* Get all menu items
|
||||
*
|
||||
* @param int $active
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMenus(int $active = 0): array;
|
||||
}
|
41
libraries/src/Model/Util/PageInterface.php
Normal file
41
libraries/src/Model/Util/PageInterface.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
/**
|
||||
* Class for getting page data
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface PageInterface
|
||||
{
|
||||
/**
|
||||
* Get page data
|
||||
*
|
||||
* @param string $path The page path
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getPageItemByPath(string $path): \stdClass;
|
||||
|
||||
/**
|
||||
* Get page data
|
||||
*
|
||||
* @param int $item The item id
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getPageItemById(int $item): \stdClass;
|
||||
}
|
54
libraries/src/Model/Util/SelectMenuTrait.php
Normal file
54
libraries/src/Model/Util/SelectMenuTrait.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 21th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
use Joomla\Database\ParameterType;
|
||||
|
||||
/**
|
||||
* Trait for getting menu items
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait SelectMenuTrait
|
||||
{
|
||||
/**
|
||||
* Get all menu items
|
||||
*
|
||||
* @param int $active
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMenus(int $active = 0): array
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
if (empty($active) && !empty($this->id))
|
||||
{
|
||||
$active = $this->id;
|
||||
}
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(array('id', 'title')))
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where('published = 1')
|
||||
->where('home = 0');
|
||||
|
||||
// we need to remove the active menu
|
||||
if ($active > 0)
|
||||
{
|
||||
$query
|
||||
->where($db->quoteName('id') . ' != :id')
|
||||
->bind(':id', $active, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
return $db->setQuery($query)->loadObjectList('id');
|
||||
}
|
||||
}
|
70
libraries/src/Model/Util/SiteMenuTrait.php
Normal file
70
libraries/src/Model/Util/SiteMenuTrait.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
/**
|
||||
* Trait for getting menu items
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait SiteMenuTrait
|
||||
{
|
||||
/**
|
||||
* Get all menu items that are root and published and not home page
|
||||
*
|
||||
* @param int $active
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMenus(int $active = 0): array
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('a.*')
|
||||
->from($db->quoteName('#__menu', 'a'))
|
||||
->where($db->quoteName('a.published') . ' = 1')
|
||||
->where($db->quoteName('a.home') . ' = 0');
|
||||
|
||||
try
|
||||
{
|
||||
$menus = $db->setQuery($query)->loadObjectList();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($menus)
|
||||
{
|
||||
$bucket = [];
|
||||
foreach ($menus as $menu)
|
||||
{
|
||||
$row = [];
|
||||
// set the details
|
||||
$row['id'] = $menu->id;
|
||||
$row['title'] = $menu->title;
|
||||
$row['path'] = $menu->path;
|
||||
$row['parent'] = $menu->parent_id;
|
||||
// set position
|
||||
$params = (isset($menu->params) && strpos($menu->params, 'position') !== false) ? json_decode($menu->params) : null;
|
||||
// default is center
|
||||
$row['position'] = (is_object($params) && isset($params->position)) ? $params->position : 'center';
|
||||
|
||||
// add to our bucket
|
||||
$bucket[] = $row;
|
||||
}
|
||||
return $bucket;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
103
libraries/src/Model/Util/SitePageTrait.php
Normal file
103
libraries/src/Model/Util/SitePageTrait.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 18th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
use Joomla\Database\ParameterType;
|
||||
|
||||
/**
|
||||
* Trait for getting page data
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait SitePageTrait
|
||||
{
|
||||
/**
|
||||
* Get page data
|
||||
*
|
||||
* @param string $path The page path
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getPageItemByPath(string $path): \stdClass
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('i.*')
|
||||
->select($db->quoteName(array('m.id'), array('menu_id')))
|
||||
->from($db->quoteName('#__menu', 'm'))
|
||||
->join('INNER', $db->quoteName('#__item', 'i'), 'm.item_id = i.id')
|
||||
->where($db->quoteName('i.state') . ' >= 1')
|
||||
->where($db->quoteName('m.published') . ' = 1')
|
||||
->where($db->quoteName('m.path') . ' = :path')
|
||||
->bind(':path', $path)
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$page = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
return new \stdClass();
|
||||
}
|
||||
|
||||
if ($page)
|
||||
{
|
||||
return $page;
|
||||
}
|
||||
|
||||
return new \stdClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page data
|
||||
*
|
||||
* @param int $item The item id
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getPageItemById(int $item): \stdClass
|
||||
{
|
||||
$db = $this->getDb();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select('i.*')
|
||||
->select($db->quoteName(array('m.id'), array('menu_id')))
|
||||
->from($db->quoteName('#__item', 'i'))
|
||||
->join('INNER', $db->quoteName('#__menu', 'm'), 'i.id = m.item_id')
|
||||
->where($db->quoteName('m.published') . ' = 1')
|
||||
->where($db->quoteName('i.state') . ' >= 1')
|
||||
->where($db->quoteName('i.id') . ' = :id')
|
||||
->bind(':id', $item, ParameterType::INTEGER)
|
||||
->setLimit(1);
|
||||
|
||||
try
|
||||
{
|
||||
$page = $db->setQuery($query)->loadObject();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
return new \stdClass();
|
||||
}
|
||||
|
||||
if ($page)
|
||||
{
|
||||
return $page;
|
||||
}
|
||||
|
||||
return new \stdClass();
|
||||
}
|
||||
}
|
44
libraries/src/Model/Util/UniqueInterface.php
Normal file
44
libraries/src/Model/Util/UniqueInterface.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 21th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
/**
|
||||
* Class for getting unique string
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface UniqueInterface
|
||||
{
|
||||
/**
|
||||
* Get a unique string
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $value
|
||||
* @param int $parent
|
||||
* @param string $key
|
||||
* @param string $spacer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function unique(int $id, string $value, int $parent = -1, string $key = 'alias', string $spacer = '-'): string;
|
||||
|
||||
/**
|
||||
* Check if an any key exist with same parent
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $value
|
||||
* @param string $key
|
||||
* @param int $parent
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exist(int $id, string $value, string $key = 'alias', int $parent = -1): bool;
|
||||
}
|
103
libraries/src/Model/Util/UniqueMenuAliasTrait.php
Normal file
103
libraries/src/Model/Util/UniqueMenuAliasTrait.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 21th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Model\Util;
|
||||
|
||||
use Joomla\Database\ParameterType;
|
||||
|
||||
/**
|
||||
* Trait for getting unique string
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
trait UniqueMenuAliasTrait
|
||||
{
|
||||
/**
|
||||
* Get a unique string
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $value
|
||||
* @param int $parent
|
||||
* @param string $key
|
||||
* @param string $spacer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function unique(int $id, string $value, int $parent = -1, string $key = 'alias', string $spacer = '-'): string
|
||||
{
|
||||
// start building the value
|
||||
$value = str_replace($spacer, ' ', $value);
|
||||
$value = preg_replace('/\s+/', $spacer, strtolower(preg_replace("/[^A-Za-z0-9\- ]/", '', $value)));
|
||||
// set a counter
|
||||
$counter = 2;
|
||||
// set original tracker
|
||||
$original = $value;
|
||||
// check if we found any with the same alias
|
||||
while ($this->exist($id, $value, $key, $parent))
|
||||
{
|
||||
$value = $original . '-' . $counter;
|
||||
$counter++;
|
||||
}
|
||||
// return the unique value (on this parent layer)
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an any key exist with same parent
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $value
|
||||
* @param string $key
|
||||
* @param int $parent
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exist(int $id, string $value, string $key = 'alias', int $parent = -1): bool
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$query = $db->getQuery(true)
|
||||
->select('id')
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where($db->quoteName($key) . " = :$key")
|
||||
->bind(":$key", $value)
|
||||
->setLimit(1);
|
||||
|
||||
// only add the id item exist
|
||||
if ($parent >= 0)
|
||||
{
|
||||
$query
|
||||
->where($db->quoteName('parent_id') . ' = :parent_id')
|
||||
->bind(':parent_id', $parent, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
// only add the id item exist
|
||||
if ($id > 0)
|
||||
{
|
||||
$query
|
||||
->where($db->quoteName('id') . ' != :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$result = $db->setQuery($query)->loadResult();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// we ignore this and just return an empty object
|
||||
}
|
||||
|
||||
if (isset($result) && $result > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
62
libraries/src/Renderer/ApplicationContext.php
Normal file
62
libraries/src/Renderer/ApplicationContext.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Renderer;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Application\AbstractWebApplication;
|
||||
use Symfony\Component\Asset\Context\ContextInterface;
|
||||
|
||||
/**
|
||||
* Joomla! application aware context
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Renderer/ApplicationContext.php
|
||||
*/
|
||||
class ApplicationContext implements ContextInterface
|
||||
{
|
||||
/**
|
||||
* Application object
|
||||
*
|
||||
* @var AbstractApplication
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param AbstractApplication $app The application object
|
||||
*/
|
||||
public function __construct(AbstractApplication $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base path.
|
||||
*
|
||||
* @return string The base path
|
||||
*/
|
||||
public function getBasePath()
|
||||
{
|
||||
return rtrim($this->app->get('uri.base.path'), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the request is secure or not.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSecure()
|
||||
{
|
||||
if ($this->app instanceof AbstractWebApplication)
|
||||
{
|
||||
return $this->app->isSslConnection();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
67
libraries/src/Renderer/FrameworkExtension.php
Normal file
67
libraries/src/Renderer/FrameworkExtension.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Renderer;
|
||||
|
||||
use Symfony\Component\Asset\Packages;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
/**
|
||||
* Framework site's Twig extension class
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Renderer/FrameworkExtension.php
|
||||
*/
|
||||
class FrameworkExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* Returns a list of filters to add to the existing list
|
||||
*
|
||||
* @return TwigFilter[] An array of TwigFilter instances
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return [
|
||||
new TwigFilter('get_class', 'get_class'),
|
||||
new TwigFilter('strip_root_path', [$this, 'stripRootPath']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of functions to add to the existing list.
|
||||
*
|
||||
* @return TwigFunction[] An array of TwigFunction instances
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new TwigFunction('asset', [Packages::class, 'getUrl']),
|
||||
new TwigFunction('preload', [FrameworkTwigRuntime::class, 'preloadAsset']),
|
||||
new TwigFunction('request_uri', [FrameworkTwigRuntime::class, 'getRequestUri']),
|
||||
new TwigFunction('route', [FrameworkTwigRuntime::class, 'getRouteUri']),
|
||||
new TwigFunction('sri', [FrameworkTwigRuntime::class, 'getSriAttributes'], ['is_safe' => ['html']]),
|
||||
new TwigFunction('message_queue', [FrameworkTwigRuntime::class, 'getMessageQueue']),
|
||||
new TwigFunction('user_array', [FrameworkTwigRuntime::class, 'getUserArray']),
|
||||
new TwigFunction('user', [FrameworkTwigRuntime::class, 'getUser']),
|
||||
new TwigFunction('token', [FrameworkTwigRuntime::class, 'getToken']),
|
||||
new TwigFunction('shorten_string', [FrameworkTwigRuntime::class, 'shortenString']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the application root path defined by the constant "JPATH_ROOT"
|
||||
*
|
||||
* @param string $string The string to process
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function stripRootPath(string $string): string
|
||||
{
|
||||
return str_replace(JPATH_ROOT . DIRECTORY_SEPARATOR, '', $string);
|
||||
}
|
||||
}
|
278
libraries/src/Renderer/FrameworkTwigRuntime.php
Normal file
278
libraries/src/Renderer/FrameworkTwigRuntime.php
Normal file
@ -0,0 +1,278 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Renderer;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\Preload\PreloadManager;
|
||||
use Joomla\Session\SessionInterface;
|
||||
use Kumwe\CMS\Factory;
|
||||
use Kumwe\CMS\User\User;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
|
||||
/**
|
||||
* Twig runtime class
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Renderer/FrameworkTwigRuntime.php
|
||||
*/
|
||||
class FrameworkTwigRuntime
|
||||
{
|
||||
/**
|
||||
* Application object
|
||||
*
|
||||
* @var AbstractApplication
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* The HTTP/2 preload manager
|
||||
*
|
||||
* @var PreloadManager
|
||||
*/
|
||||
private $preloadManager;
|
||||
|
||||
/**
|
||||
* The SRI manifest data
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
private $sriManifestData;
|
||||
|
||||
/**
|
||||
* The path to the SRI manifest data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $sriManifestPath;
|
||||
|
||||
/**
|
||||
* @var SessionInterface|null
|
||||
*/
|
||||
private $session;
|
||||
|
||||
/**
|
||||
* @var User|null
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param AbstractApplication $app The application object
|
||||
* @param PreloadManager $preloadManager The HTTP/2 preload manager
|
||||
* @param string $sriManifestPath The path to the SRI manifest data
|
||||
* @param SessionInterface|null $session The session object
|
||||
*/
|
||||
public function __construct(
|
||||
AbstractApplication $app,
|
||||
PreloadManager $preloadManager,
|
||||
string $sriManifestPath,
|
||||
SessionInterface $session = null)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->preloadManager = $preloadManager;
|
||||
$this->sriManifestPath = $sriManifestPath;
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current URI
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestUri(): string
|
||||
{
|
||||
return $this->app->get('uri.request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URI for a route
|
||||
*
|
||||
* @param string $route Route to get the path for
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteUri(string $route = ''): string
|
||||
{
|
||||
return $this->app->get('uri.base.path') . $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full URL for a route
|
||||
*
|
||||
* @param string $route Route to get the URL for
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteUrl(string $route = ''): string
|
||||
{
|
||||
return $this->app->get('uri.base.host') . $this->getRouteUri($route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get form Token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getToken(): string
|
||||
{
|
||||
if ($this->session instanceof SessionInterface)
|
||||
{
|
||||
return $this->session->getToken();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorten a string
|
||||
*
|
||||
* @input string The you would like to shorten
|
||||
*
|
||||
* @returns string on success
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function shortenString($string, $length = 100)
|
||||
{
|
||||
if (is_string($string) && strlen($string) > $length)
|
||||
{
|
||||
$initial = strlen($string);
|
||||
$words = preg_split('/([\s\n\r]+)/', $string, null, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$words_count = count((array)$words);
|
||||
|
||||
$word_length = 0;
|
||||
$last_word = 0;
|
||||
for (; $last_word < $words_count; ++$last_word)
|
||||
{
|
||||
$word_length += strlen($words[$last_word]);
|
||||
if ($word_length > $length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$newString = implode(array_slice($words, 0, $last_word));
|
||||
return trim($newString) . '...';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user as array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUserArray(): array
|
||||
{
|
||||
if (!$this->user instanceof User)
|
||||
{
|
||||
/** @var \Kumwe\CMS\User\User $user */
|
||||
$this->user = Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
// check again
|
||||
if ($this->user instanceof User && method_exists($this->user, 'toArray'))
|
||||
{
|
||||
return $this->user->toArray();
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getUser(string $key = 'name', $default = '')
|
||||
{
|
||||
if (!$this->user instanceof User)
|
||||
{
|
||||
/** @var \Kumwe\CMS\User\User $user */
|
||||
$this->user = Factory::getContainer()->get(UserFactoryInterface::class)->getUser();
|
||||
}
|
||||
// check again
|
||||
if ($this->user instanceof User)
|
||||
{
|
||||
return $this->user->get($key, $default);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any messages in the queue
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessageQueue(): array
|
||||
{
|
||||
if (method_exists($this->app, 'getMessageQueue'))
|
||||
{
|
||||
return $this->app->getMessageQueue(true);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SRI attributes for an asset
|
||||
*
|
||||
* @param string $path A public path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSriAttributes(string $path): string
|
||||
{
|
||||
if ($this->sriManifestData === null)
|
||||
{
|
||||
if (!file_exists($this->sriManifestPath))
|
||||
{
|
||||
throw new \RuntimeException(sprintf('SRI manifest file "%s" does not exist.', $this->sriManifestPath));
|
||||
}
|
||||
|
||||
$sriManifestContents = file_get_contents($this->sriManifestPath);
|
||||
|
||||
if ($sriManifestContents === false)
|
||||
{
|
||||
throw new \RuntimeException(sprintf('Could not read SRI manifest file "%s".', $this->sriManifestPath));
|
||||
}
|
||||
|
||||
$this->sriManifestData = json_decode($sriManifestContents, true);
|
||||
|
||||
if (0 < json_last_error())
|
||||
{
|
||||
throw new \RuntimeException(sprintf('Error parsing JSON from SRI manifest file "%s" - %s', $this->sriManifestPath, json_last_error_msg()));
|
||||
}
|
||||
}
|
||||
|
||||
$assetKey = "/$path";
|
||||
|
||||
if (!isset($this->sriManifestData[$assetKey]))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$attributes = '';
|
||||
|
||||
foreach ($this->sriManifestData[$assetKey] as $key => $value)
|
||||
{
|
||||
$attributes .= ' ' . $key . '="' . $value . '"';
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload a resource
|
||||
*
|
||||
* @param string $uri The URI for the resource to preload
|
||||
* @param string $linkType The preload method to apply
|
||||
* @param array $attributes The attributes of this link (e.g. "array('as' => true)", "array('pr' => 0.5)")
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function preloadAsset(string $uri, string $linkType = 'preload', array $attributes = []): string
|
||||
{
|
||||
$this->preloadManager->link($uri, $linkType, $attributes);
|
||||
|
||||
return $uri;
|
||||
}
|
||||
}
|
103
libraries/src/Service/AdminApplicationProvider.php
Normal file
103
libraries/src/Service/AdminApplicationProvider.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\Application\AbstractWebApplication;
|
||||
use Joomla\Application\Controller\ControllerResolverInterface;
|
||||
use Joomla\Application\Web\WebClient;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
|
||||
use Joomla\Session\SessionInterface;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\Application\AdminApplication;
|
||||
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Router\RouterInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Admin Application service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/ApplicationProvider.php
|
||||
*/
|
||||
class AdminApplicationProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
/*
|
||||
* Application Classes
|
||||
*/
|
||||
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(AdminApplication::class, AbstractWebApplication::class)
|
||||
->share(AbstractWebApplication::class, [$this, 'getAdminApplicationClassService']);
|
||||
|
||||
/*
|
||||
* Application Helpers and Dependencies
|
||||
*/
|
||||
$container->share(WebClient::class, [$this, 'getWebClientService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WebApplication class service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return AdminApplication
|
||||
*/
|
||||
public function getAdminApplicationClassService(Container $container): AdminApplication
|
||||
{
|
||||
/** @var \Kumwe\CMS\Application\AdminApplication $application */
|
||||
$application = new AdminApplication(
|
||||
$container->get(ControllerResolverInterface::class),
|
||||
$container->get(RouterInterface::class),
|
||||
$container->get(Input::class),
|
||||
$container->get('config'),
|
||||
$container->get(WebClient::class)
|
||||
);
|
||||
|
||||
$application->httpVersion = '2';
|
||||
|
||||
// Inject extra services
|
||||
$application->setDispatcher($container->get(DispatcherInterface::class));
|
||||
$application->setLogger($container->get(LoggerInterface::class));
|
||||
$application->setSession($container->get(SessionInterface::class));
|
||||
$application->setUserFactory($container->get(UserFactoryInterface::class));
|
||||
|
||||
return $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the web client service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return WebClient
|
||||
*/
|
||||
public function getWebClientService(Container $container): WebClient
|
||||
{
|
||||
/** @var Input $input */
|
||||
$input = $container->get(Input::class);
|
||||
$userAgent = $input->server->getString('HTTP_USER_AGENT', '');
|
||||
$acceptEncoding = $input->server->getString('HTTP_ACCEPT_ENCODING', '');
|
||||
$acceptLanguage = $input->server->getString('HTTP_ACCEPT_LANGUAGE', '');
|
||||
|
||||
return new WebClient($userAgent, $acceptEncoding, $acceptLanguage);
|
||||
}
|
||||
}
|
605
libraries/src/Service/AdminMVCProvider.php
Normal file
605
libraries/src/Service/AdminMVCProvider.php
Normal file
@ -0,0 +1,605 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 14th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\Application\Controller\ContainerControllerResolver;
|
||||
use Joomla\Application\Controller\ControllerResolverInterface;
|
||||
use Joomla\Database\DatabaseInterface;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
use Kumwe\CMS\Controller\DashboardController;
|
||||
use Kumwe\CMS\Controller\ItemsController;
|
||||
use Kumwe\CMS\Controller\ItemController;
|
||||
use Kumwe\CMS\Controller\LoginController;
|
||||
use Kumwe\CMS\Controller\MenuController;
|
||||
use Kumwe\CMS\Controller\MenusController;
|
||||
use Kumwe\CMS\Controller\UserController;
|
||||
use Kumwe\CMS\Controller\UsersController;
|
||||
use Kumwe\CMS\Controller\UserGroupController;
|
||||
use Kumwe\CMS\Controller\UsergroupsController;
|
||||
use Kumwe\CMS\Controller\WrongCmsController;
|
||||
use Kumwe\CMS\Model\DashboardModel;
|
||||
use Kumwe\CMS\Model\ItemsModel;
|
||||
use Kumwe\CMS\Model\ItemModel;
|
||||
use Kumwe\CMS\Model\MenusModel;
|
||||
use Kumwe\CMS\Model\MenuModel;
|
||||
use Kumwe\CMS\Model\UserModel;
|
||||
use Kumwe\CMS\Model\UsersModel;
|
||||
use Kumwe\CMS\Model\UsergroupModel;
|
||||
use Kumwe\CMS\Model\UsergroupsModel;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Kumwe\CMS\View\Admin\DashboardHtmlView;
|
||||
use Kumwe\CMS\View\Admin\ItemsHtmlView;
|
||||
use Kumwe\CMS\View\Admin\ItemHtmlView;
|
||||
use Kumwe\CMS\View\Admin\MenuHtmlView;
|
||||
use Kumwe\CMS\View\Admin\MenusHtmlView;
|
||||
use Kumwe\CMS\View\Admin\UserHtmlView;
|
||||
use Kumwe\CMS\View\Admin\UsersHtmlView;
|
||||
use Kumwe\CMS\View\Admin\UsergroupHtmlView;
|
||||
use Kumwe\CMS\View\Admin\UsergroupsHtmlView;
|
||||
use Kumwe\CMS\Application\AdminApplication;
|
||||
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Renderer\RendererInterface;
|
||||
|
||||
/**
|
||||
* Model View Controller service provider
|
||||
*/
|
||||
class AdminMVCProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(ContainerControllerResolver::class, ControllerResolverInterface::class)
|
||||
->share(ControllerResolverInterface::class, [$this, 'getControllerResolverService']);
|
||||
|
||||
// Controllers
|
||||
$container->alias(DashboardController::class, 'controller.dashboard')
|
||||
->share('controller.dashboard', [$this, 'getControllerDashboardService'], true);
|
||||
|
||||
$container->alias(UsersController::class, 'controller.users')
|
||||
->share('controller.users', [$this, 'getControllerUsersService'], true);
|
||||
|
||||
$container->alias(UserController::class, 'controller.user')
|
||||
->share('controller.user', [$this, 'getControllerUserService'], true);
|
||||
|
||||
$container->alias(UsergroupsController::class, 'controller.usergroups')
|
||||
->share('controller.usergroups', [$this, 'getControllerUsergroupsService'], true);
|
||||
|
||||
$container->alias(UsergroupController::class, 'controller.usergroup')
|
||||
->share('controller.usergroup', [$this, 'getControllerUsergroupService'], true);
|
||||
|
||||
$container->alias(MenusController::class, 'controller.menus')
|
||||
->share('controller.menus', [$this, 'getControllerMenusService'], true);
|
||||
|
||||
$container->alias(MenuController::class, 'controller.menu')
|
||||
->share('controller.menu', [$this, 'getControllerMenuService'], true);
|
||||
|
||||
$container->alias(ItemsController::class, 'controller.items')
|
||||
->share('controller.items', [$this, 'getControllerItemsService'], true);
|
||||
|
||||
$container->alias(ItemController::class, 'controller.item')
|
||||
->share('controller.item', [$this, 'getControllerItemService'], true);
|
||||
|
||||
$container->alias(LoginController::class, 'controller.login')
|
||||
->share('controller.login', [$this, 'getControllerLoginService'], true);
|
||||
|
||||
$container->alias(WrongCmsController::class, 'controller.wrong.cms')
|
||||
->share('controller.wrong.cms', [$this, 'getControllerWrongCmsService'], true);
|
||||
|
||||
// Models
|
||||
$container->alias(DashboardModel::class, 'model.dashboard')
|
||||
->share('model.dashboard', [$this, 'getModelDashboardService'], true);
|
||||
|
||||
$container->alias(UsersModel::class, 'model.users')
|
||||
->share('model.users', [$this, 'getModelUsersService'], true);
|
||||
|
||||
$container->alias(UserModel::class, 'model.user')
|
||||
->share('model.user', [$this, 'getModelUserService'], true);
|
||||
|
||||
$container->alias(UsergroupsModel::class, 'model.usergroups')
|
||||
->share('model.usergroups', [$this, 'getModelUsergroupsService'], true);
|
||||
|
||||
$container->alias(UsergroupModel::class, 'model.usergroup')
|
||||
->share('model.usergroup', [$this, 'getModelUsergroupService'], true);
|
||||
|
||||
$container->alias(MenusModel::class, 'model.menus')
|
||||
->share('model.menus', [$this, 'getModelMenusService'], true);
|
||||
|
||||
$container->alias(MenuModel::class, 'model.menu')
|
||||
->share('model.menu', [$this, 'getModelMenuService'], true);
|
||||
|
||||
$container->alias(ItemsModel::class, 'model.items')
|
||||
->share('model.items', [$this, 'getModelItemsService'], true);
|
||||
|
||||
$container->alias(ItemModel::class, 'model.item')
|
||||
->share('model.item', [$this, 'getModelItemService'], true);
|
||||
|
||||
// Views
|
||||
$container->alias(DashboardHtmlView::class, 'view.dashboard.html')
|
||||
->share('view.dashboard.html', [$this, 'getViewDashboardHtmlService'], true);
|
||||
|
||||
$container->alias(UsersHtmlView::class, 'view.users.html')
|
||||
->share('view.users.html', [$this, 'getViewUsersHtmlService'], true);
|
||||
|
||||
$container->alias(UserHtmlView::class, 'view.user.html')
|
||||
->share('view.user.html', [$this, 'getViewUserHtmlService'], true);
|
||||
|
||||
$container->alias(UsergroupsHtmlView::class, 'view.usergroups.html')
|
||||
->share('view.usergroups.html', [$this, 'getViewUsergroupsHtmlService'], true);
|
||||
|
||||
$container->alias(UsergroupHtmlView::class, 'view.usergroup.html')
|
||||
->share('view.usergroup.html', [$this, 'getViewUsergroupHtmlService'], true);
|
||||
|
||||
$container->alias(MenusHtmlView::class, 'view.menus.html')
|
||||
->share('view.menus.html', [$this, 'getViewMenusHtmlService'], true);
|
||||
|
||||
$container->alias(MenuHtmlView::class, 'view.menu.html')
|
||||
->share('view.menu.html', [$this, 'getViewMenuHtmlService'], true);
|
||||
|
||||
$container->alias(ItemsHtmlView::class, 'view.items.html')
|
||||
->share('view.items.html', [$this, 'getViewItemsHtmlService'], true);
|
||||
|
||||
$container->alias(ItemHtmlView::class, 'view.item.html')
|
||||
->share('view.item.html', [$this, 'getViewItemHtmlService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the controller resolver service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ControllerResolverInterface
|
||||
*/
|
||||
public function getControllerResolverService(Container $container): ControllerResolverInterface
|
||||
{
|
||||
return new ContainerControllerResolver($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.login` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return LoginController
|
||||
*/
|
||||
public function getControllerLoginService(Container $container): LoginController
|
||||
{
|
||||
return new LoginController(
|
||||
$container->get(DashboardHtmlView::class),
|
||||
$container->get(RendererInterface::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.wrong.cms` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return WrongCmsController
|
||||
*/
|
||||
public function getControllerWrongCmsService(Container $container): WrongCmsController
|
||||
{
|
||||
return new WrongCmsController(
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.dashboard` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return DashboardController
|
||||
*/
|
||||
public function getControllerDashboardService(Container $container): DashboardController
|
||||
{
|
||||
return new DashboardController(
|
||||
$container->get(DashboardHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.dashboard` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return DashboardModel
|
||||
*/
|
||||
public function getModelDashboardService(Container $container): DashboardModel
|
||||
{
|
||||
return new DashboardModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.dashboard.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return DashboardHtmlView
|
||||
*/
|
||||
public function getViewDashboardHtmlService(Container $container): DashboardHtmlView
|
||||
{
|
||||
return new DashboardHtmlView(
|
||||
$container->get('model.dashboard'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.users` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsersController
|
||||
*/
|
||||
public function getControllerUsersService(Container $container): UsersController
|
||||
{
|
||||
return new UsersController(
|
||||
$container->get(UsersHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.users` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsersModel
|
||||
*/
|
||||
public function getModelUsersService(Container $container): UsersModel
|
||||
{
|
||||
return new UsersModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.users.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsersHtmlView
|
||||
*/
|
||||
public function getViewUsersHtmlService(Container $container): UsersHtmlView
|
||||
{
|
||||
return new UsersHtmlView(
|
||||
$container->get('model.users'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.user` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UserController
|
||||
*/
|
||||
public function getControllerUserService(Container $container): UserController
|
||||
{
|
||||
return new UserController(
|
||||
$container->get(UserModel::class),
|
||||
$container->get(UserHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.user` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UserModel
|
||||
*/
|
||||
public function getModelUserService(Container $container): UserModel
|
||||
{
|
||||
return new UserModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.user.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UserHtmlView
|
||||
*/
|
||||
public function getViewUserHtmlService(Container $container): UserHtmlView
|
||||
{
|
||||
return new UserHtmlView(
|
||||
$container->get('model.user'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.usergroups` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsergroupsController
|
||||
*/
|
||||
public function getControllerUsergroupsService(Container $container): UsergroupsController
|
||||
{
|
||||
return new UsergroupsController(
|
||||
$container->get(UsergroupsHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.usergroups` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsergroupsModel
|
||||
*/
|
||||
public function getModelUsergroupsService(Container $container): UsergroupsModel
|
||||
{
|
||||
return new UsergroupsModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.usergroups.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsergroupsHtmlView
|
||||
*/
|
||||
public function getViewUsergroupsHtmlService(Container $container): UsergroupsHtmlView
|
||||
{
|
||||
return new UsergroupsHtmlView(
|
||||
$container->get('model.usergroups'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.usergroup` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsergroupController
|
||||
*/
|
||||
public function getControllerUsergroupService(Container $container): UsergroupController
|
||||
{
|
||||
return new UsergroupController(
|
||||
$container->get(UsergroupModel::class),
|
||||
$container->get(UsergroupHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.usergroup` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsergroupModel
|
||||
*/
|
||||
public function getModelUsergroupService(Container $container): UsergroupModel
|
||||
{
|
||||
return new UsergroupModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.usergroup.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UsergroupHtmlView
|
||||
*/
|
||||
public function getViewUsergroupHtmlService(Container $container): UsergroupHtmlView
|
||||
{
|
||||
return new UsergroupHtmlView(
|
||||
$container->get('model.usergroup'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.menus` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return MenusController
|
||||
*/
|
||||
public function getControllerMenusService(Container $container): MenusController
|
||||
{
|
||||
return new MenusController(
|
||||
$container->get(MenusHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.menus` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return MenusModel
|
||||
*/
|
||||
public function getModelMenusService(Container $container): MenusModel
|
||||
{
|
||||
return new MenusModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.menus.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return MenusHtmlView
|
||||
*/
|
||||
public function getViewMenusHtmlService(Container $container): MenusHtmlView
|
||||
{
|
||||
return new MenusHtmlView(
|
||||
$container->get('model.menus'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.menu` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return MenuController
|
||||
*/
|
||||
public function getControllerMenuService(Container $container): MenuController
|
||||
{
|
||||
return new MenuController(
|
||||
$container->get(MenuModel::class),
|
||||
$container->get(MenuHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.menu` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return MenuModel
|
||||
*/
|
||||
public function getModelMenuService(Container $container): MenuModel
|
||||
{
|
||||
return new MenuModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.menu.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return MenuHtmlView
|
||||
*/
|
||||
public function getViewMenuHtmlService(Container $container): MenuHtmlView
|
||||
{
|
||||
return new MenuHtmlView(
|
||||
$container->get('model.menu'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.items` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ItemsController
|
||||
*/
|
||||
public function getControllerItemsService(Container $container): ItemsController
|
||||
{
|
||||
return new ItemsController(
|
||||
$container->get(ItemsHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.items` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ItemsModel
|
||||
*/
|
||||
public function getModelItemsService(Container $container): ItemsModel
|
||||
{
|
||||
return new ItemsModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.items.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ItemsHtmlView
|
||||
*/
|
||||
public function getViewItemsHtmlService(Container $container): ItemsHtmlView
|
||||
{
|
||||
return new ItemsHtmlView(
|
||||
$container->get('model.items'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.item` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ItemController
|
||||
*/
|
||||
public function getControllerItemService(Container $container): ItemController
|
||||
{
|
||||
return new ItemController(
|
||||
$container->get(ItemModel::class),
|
||||
$container->get(ItemHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(AdminApplication::class),
|
||||
$container->get(UserFactoryInterface::class)->getUser()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.item` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ItemModel
|
||||
*/
|
||||
public function getModelItemService(Container $container): ItemModel
|
||||
{
|
||||
return new ItemModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.item.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ItemHtmlView
|
||||
*/
|
||||
public function getViewItemHtmlService(Container $container): ItemHtmlView
|
||||
{
|
||||
return new ItemHtmlView(
|
||||
$container->get('model.item'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
}
|
108
libraries/src/Service/AdminRouterProvider.php
Normal file
108
libraries/src/Service/AdminRouterProvider.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 14th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
use Kumwe\CMS\Controller\DashboardController;
|
||||
use Kumwe\CMS\Controller\LoginController;
|
||||
use Kumwe\CMS\Controller\ItemsController;
|
||||
use Kumwe\CMS\Controller\ItemController;
|
||||
use Kumwe\CMS\Controller\MenuController;
|
||||
use Kumwe\CMS\Controller\MenusController;
|
||||
use Kumwe\CMS\Controller\UserController;
|
||||
use Kumwe\CMS\Controller\UsersController;
|
||||
use Kumwe\CMS\Controller\UserGroupController;
|
||||
use Kumwe\CMS\Controller\UsergroupsController;
|
||||
|
||||
use Joomla\Router\Router;
|
||||
use Joomla\Router\RouterInterface;
|
||||
|
||||
/**
|
||||
* Application service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/ApplicationProvider.php
|
||||
*/
|
||||
class AdminRouterProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(RouterInterface::class, 'application.router')
|
||||
->alias(Router::class, 'application.router')
|
||||
->share('application.router', [$this, 'getApplicationRouterService']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `application.router` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return RouterInterface
|
||||
*/
|
||||
public function getApplicationRouterService(Container $container): RouterInterface
|
||||
{
|
||||
$router = new Router;
|
||||
|
||||
/**
|
||||
* CMS Admin Panels
|
||||
**/
|
||||
$router->all(
|
||||
'/index.php/dashboard',
|
||||
DashboardController::class
|
||||
);
|
||||
$router->get(
|
||||
'/index.php/users',
|
||||
UsersController::class
|
||||
);
|
||||
$router->all(
|
||||
'/index.php/user',
|
||||
UserController::class
|
||||
);
|
||||
$router->get(
|
||||
'/index.php/usergroups',
|
||||
UsergroupsController::class
|
||||
);
|
||||
$router->all(
|
||||
'/index.php/usergroup',
|
||||
UsergroupController::class
|
||||
);
|
||||
$router->get(
|
||||
'/index.php/menus',
|
||||
MenusController::class
|
||||
);
|
||||
$router->all(
|
||||
'/index.php/menu',
|
||||
MenuController::class
|
||||
);
|
||||
$router->get(
|
||||
'/index.php/items',
|
||||
ItemsController::class
|
||||
);
|
||||
$router->all(
|
||||
'/index.php/item',
|
||||
ItemController::class
|
||||
);
|
||||
$router->get(
|
||||
'/*',
|
||||
LoginController::class
|
||||
);
|
||||
|
||||
return $router;
|
||||
}
|
||||
}
|
314
libraries/src/Service/AdminTemplatingProvider.php
Normal file
314
libraries/src/Service/AdminTemplatingProvider.php
Normal file
@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Session\SessionInterface;
|
||||
use Kumwe\CMS\Asset\MixPathPackage;
|
||||
use Kumwe\CMS\Renderer\ApplicationContext;
|
||||
use Kumwe\CMS\Renderer\FrameworkExtension;
|
||||
use Kumwe\CMS\Renderer\FrameworkTwigRuntime;
|
||||
use Joomla\Preload\PreloadManager;
|
||||
use Joomla\Renderer\RendererInterface;
|
||||
use Joomla\Renderer\TwigRenderer;
|
||||
use Symfony\Component\Asset\Packages;
|
||||
use Symfony\Component\Asset\PathPackage;
|
||||
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
|
||||
use Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy;
|
||||
use Twig\Cache\CacheInterface;
|
||||
use Twig\Cache\FilesystemCache;
|
||||
use Twig\Cache\NullCache;
|
||||
use Twig\Environment;
|
||||
use Twig\Extension\DebugExtension;
|
||||
use Twig\Extension\ProfilerExtension;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
use Twig\Loader\LoaderInterface;
|
||||
use Twig\Profiler\Profile;
|
||||
use Twig\RuntimeLoader\ContainerRuntimeLoader;
|
||||
|
||||
/**
|
||||
* Templating service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/TemplatingProvider.php
|
||||
*/
|
||||
class AdminTemplatingProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->alias(Packages::class, 'asset.packages')
|
||||
->share('asset.packages', [$this, 'getAssetPackagesService'], true);
|
||||
|
||||
$container->alias(RendererInterface::class, 'renderer')
|
||||
->alias(TwigRenderer::class, 'renderer')
|
||||
->share('renderer', [$this, 'getRendererService'], true);
|
||||
|
||||
$container->alias(CacheInterface::class, 'twig.cache')
|
||||
->alias(\Twig_CacheInterface::class, 'twig.cache')
|
||||
->share('twig.cache', [$this, 'getTwigCacheService'], true);
|
||||
|
||||
$container->alias(Environment::class, 'twig.environment')
|
||||
->alias(\Twig_Environment::class, 'twig.environment')
|
||||
->share('twig.environment', [$this, 'getTwigEnvironmentService'], true);
|
||||
|
||||
$container->alias(DebugExtension::class, 'twig.extension.debug')
|
||||
->alias(\Twig_Extension_Debug::class, 'twig.extension.debug')
|
||||
->share('twig.extension.debug', [$this, 'getTwigExtensionDebugService'], true);
|
||||
|
||||
$container->alias(FrameworkExtension::class, 'twig.extension.framework')
|
||||
->share('twig.extension.framework', [$this, 'getTwigExtensionFrameworkService'], true);
|
||||
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(ProfilerExtension::class, 'twig.extension.profiler')
|
||||
->alias(\Twig_Extension_Profiler::class, 'twig.extension.profiler')
|
||||
->share('twig.extension.profiler', [$this, 'getTwigExtensionProfilerService']);
|
||||
|
||||
$container->alias(LoaderInterface::class, 'twig.loader')
|
||||
->alias(\Twig_LoaderInterface::class, 'twig.loader')
|
||||
->share('twig.loader', [$this, 'getTwigLoaderService'], true);
|
||||
|
||||
$container->alias(Profile::class, 'twig.profiler.profile')
|
||||
->alias(\Twig_Profiler_Profile::class, 'twig.profiler.profile')
|
||||
->share('twig.profiler.profile', [$this, 'getTwigProfilerProfileService'], true);
|
||||
|
||||
$container->alias(FrameworkTwigRuntime::class, 'twig.runtime.framework')
|
||||
->share('twig.runtime.framework', [$this, 'getTwigRuntimeFrameworkService'], true);
|
||||
|
||||
$container->alias(ContainerRuntimeLoader::class, 'twig.runtime.loader')
|
||||
->alias(\Twig_ContainerRuntimeLoader::class, 'twig.runtime.loader')
|
||||
->share('twig.runtime.loader', [$this, 'getTwigRuntimeLoaderService'], true);
|
||||
|
||||
$this->tagTwigExtensions($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `asset.packages` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Packages
|
||||
*/
|
||||
public function getAssetPackagesService(Container $container): Packages
|
||||
{
|
||||
/** @var AbstractApplication $app */
|
||||
$app = $container->get(AbstractApplication::class);
|
||||
|
||||
$context = new ApplicationContext($app);
|
||||
|
||||
$mediaPath = $app->get('uri.media.path', '/media/');
|
||||
|
||||
$defaultPackage = new PathPackage($mediaPath, new EmptyVersionStrategy, $context);
|
||||
|
||||
$mixStrategy = new MixPathPackage(
|
||||
$defaultPackage,
|
||||
$mediaPath,
|
||||
new JsonManifestVersionStrategy(LPATH_ROOT . '/media/mix-manifest.json'),
|
||||
$context
|
||||
);
|
||||
|
||||
return new Packages(
|
||||
$defaultPackage,
|
||||
[
|
||||
'mix' => $mixStrategy,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `renderer` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function getRendererService(Container $container): RendererInterface
|
||||
{
|
||||
return new TwigRenderer($container->get('twig.environment'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.cache` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return \Twig_CacheInterface
|
||||
*/
|
||||
public function getTwigCacheService(Container $container): \Twig_CacheInterface
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
// Pull down the renderer config
|
||||
$cacheEnabled = $config->get('template.cache.enabled', false);
|
||||
$cachePath = $config->get('template.cache.path', 'cache/twig');
|
||||
$debug = $config->get('template.debug', false);
|
||||
|
||||
if ($debug === false && $cacheEnabled !== false)
|
||||
{
|
||||
return new FilesystemCache(LPATH_ROOT . '/' . $cachePath);
|
||||
}
|
||||
|
||||
return new NullCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.environment` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Environment
|
||||
*/
|
||||
public function getTwigEnvironmentService(Container $container): Environment
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
$debug = $config->get('template.debug', false);
|
||||
|
||||
$environment = new Environment(
|
||||
$container->get('twig.loader'),
|
||||
['debug' => $debug]
|
||||
);
|
||||
|
||||
// Add the runtime loader
|
||||
$environment->addRuntimeLoader($container->get('twig.runtime.loader'));
|
||||
|
||||
// Set up the environment's caching service
|
||||
$environment->setCache($container->get('twig.cache'));
|
||||
|
||||
// Add the Twig extensions
|
||||
$environment->setExtensions($container->getTagged('twig.extension'));
|
||||
|
||||
// Add a global tracking the debug states
|
||||
$environment->addGlobal('appDebug', $config->get('debug', false));
|
||||
$environment->addGlobal('fwDebug', $debug);
|
||||
|
||||
return $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.extension.debug` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return DebugExtension
|
||||
*/
|
||||
public function getTwigExtensionDebugService(Container $container): DebugExtension
|
||||
{
|
||||
return new DebugExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.extension.framework` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return FrameworkExtension
|
||||
*/
|
||||
public function getTwigExtensionFrameworkService(Container $container): FrameworkExtension
|
||||
{
|
||||
return new FrameworkExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.extension.profiler` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ProfilerExtension
|
||||
*/
|
||||
public function getTwigExtensionProfilerService(Container $container): ProfilerExtension
|
||||
{
|
||||
return new ProfilerExtension($container->get('twig.profiler.profile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.loader` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return \Twig_LoaderInterface
|
||||
*/
|
||||
public function getTwigLoaderService(Container $container): \Twig_LoaderInterface
|
||||
{
|
||||
return new FilesystemLoader([LPATH_TEMPLATES]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.profiler.profile` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Profile
|
||||
*/
|
||||
public function getTwigProfilerProfileService(Container $container): Profile
|
||||
{
|
||||
return new Profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.runtime.framework` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return FrameworkTwigRuntime
|
||||
*/
|
||||
public function getTwigRuntimeFrameworkService(Container $container): FrameworkTwigRuntime
|
||||
{
|
||||
return new FrameworkTwigRuntime(
|
||||
$container->get(AbstractApplication::class),
|
||||
$container->get(PreloadManager::class),
|
||||
LPATH_ROOT . '/media/sri-manifest.json',
|
||||
$container->get(SessionInterface::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.runtime.loader` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ContainerRuntimeLoader
|
||||
*/
|
||||
public function getTwigRuntimeLoaderService(Container $container): ContainerRuntimeLoader
|
||||
{
|
||||
return new ContainerRuntimeLoader($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag services which are Twig extensions
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function tagTwigExtensions(Container $container): void
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
$debug = $config->get('template.debug', false);
|
||||
|
||||
$twigExtensions = ['twig.extension.framework'];
|
||||
|
||||
if ($debug)
|
||||
{
|
||||
$twigExtensions[] = 'twig.extension.debug';
|
||||
}
|
||||
|
||||
$container->tag('twig.extension', $twigExtensions);
|
||||
}
|
||||
}
|
80
libraries/src/Service/ConfigurationProvider.php
Normal file
80
libraries/src/Service/ConfigurationProvider.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
/**
|
||||
* Configuration service provider
|
||||
*/
|
||||
class ConfigurationProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Configuration instance
|
||||
*
|
||||
* @var Registry
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $file Path to the config file.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct(string $file)
|
||||
{
|
||||
// Verify the configuration exists and is readable.
|
||||
if (!is_readable($file))
|
||||
{
|
||||
throw new \RuntimeException('Configuration file does not exist or is unreadable.');
|
||||
}
|
||||
|
||||
// load the class
|
||||
include_once $file;
|
||||
$this->config = new Registry(new \LConfig());
|
||||
|
||||
// Set database values based on config values
|
||||
$this->config->loadObject( (object) [
|
||||
'database' => [
|
||||
'driver' => $this->config->get('dbtype'),
|
||||
'host' => $this->config->get('host'),
|
||||
'port' => $this->config->get('port', ''),
|
||||
'user' => $this->config->get('user'),
|
||||
'password' => $this->config->get('password'),
|
||||
'database' => $this->config->get('db'),
|
||||
'prefix' => $this->config->get('dbprefix')
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->share(
|
||||
'config',
|
||||
function (): Registry
|
||||
{
|
||||
return $this->config;
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
75
libraries/src/Service/EventProvider.php
Normal file
75
libraries/src/Service/EventProvider.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\Dispatcher;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Kumwe\CMS\EventListener\ErrorSubscriber;
|
||||
use Joomla\Renderer\RendererInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Event service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/EventProvider.php
|
||||
*/
|
||||
class EventProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(Dispatcher::class, DispatcherInterface::class)
|
||||
->share(DispatcherInterface::class, [$this, 'getDispatcherService']);
|
||||
|
||||
$container->share(ErrorSubscriber::class, [$this, 'getErrorSubscriber'], true)
|
||||
->tag('event.subscriber', [ErrorSubscriber::class]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DispatcherInterface service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return DispatcherInterface
|
||||
*/
|
||||
public function getDispatcherService(Container $container): DispatcherInterface
|
||||
{
|
||||
$dispatcher = new Dispatcher;
|
||||
|
||||
foreach ($container->getTagged('event.subscriber') as $subscriber)
|
||||
{
|
||||
$dispatcher->addSubscriber($subscriber);
|
||||
}
|
||||
|
||||
return $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ErrorSubscriber service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ErrorSubscriber
|
||||
*/
|
||||
public function getErrorSubscriber(Container $container): ErrorSubscriber
|
||||
{
|
||||
$subscriber = new ErrorSubscriber($container->get(RendererInterface::class));
|
||||
$subscriber->setLogger($container->get(LoggerInterface::class));
|
||||
|
||||
return $subscriber;
|
||||
}
|
||||
}
|
64
libraries/src/Service/HttpProvider.php
Normal file
64
libraries/src/Service/HttpProvider.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Http\Http;
|
||||
use Joomla\Http\HttpFactory;
|
||||
|
||||
/**
|
||||
* HTTP service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/HttpProvider.php
|
||||
*/
|
||||
class HttpProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->alias(Http::class, 'http')
|
||||
->share('http', [$this, 'getHttpService'], true);
|
||||
|
||||
$container->alias(HttpFactory::class, 'http.factory')
|
||||
->share('http.factory', [$this, 'getHttpFactoryService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `http` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Http
|
||||
*/
|
||||
public function getHttpService(Container $container): Http
|
||||
{
|
||||
/** @var HttpFactory $factory */
|
||||
$factory = $container->get('http.factory');
|
||||
|
||||
return $factory->getHttp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `http.factory` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return HttpFactory
|
||||
*/
|
||||
public function getHttpFactoryService(Container $container): HttpFactory
|
||||
{
|
||||
return new HttpFactory;
|
||||
}
|
||||
}
|
46
libraries/src/Service/InputProvider.php
Normal file
46
libraries/src/Service/InputProvider.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 14th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
use Joomla\Input\Input;
|
||||
|
||||
/**
|
||||
* Input service provider
|
||||
*/
|
||||
class InputProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->share(Input::class, [$this, 'getInputClassService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Input class service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Input
|
||||
*/
|
||||
public function getInputClassService(Container $container): Input
|
||||
{
|
||||
return new Input($_REQUEST);
|
||||
}
|
||||
}
|
132
libraries/src/Service/LoggingProvider.php
Normal file
132
libraries/src/Service/LoggingProvider.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Processor\PsrLogMessageProcessor;
|
||||
use Monolog\Processor\WebProcessor;
|
||||
|
||||
/**
|
||||
* Logging service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/LoggingProvider.php
|
||||
*/
|
||||
class LoggingProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
/*
|
||||
* Monolog Handlers
|
||||
*/
|
||||
$container->share('monolog.handler.application', [$this, 'getMonologHandlerApplicationService'], true);
|
||||
|
||||
/*
|
||||
* Monolog Processors
|
||||
*/
|
||||
$container->share('monolog.processor.psr3', [$this, 'getMonologProcessorPsr3Service'], true);
|
||||
$container->share('monolog.processor.web', [$this, 'getMonologProcessorWebService'], true);
|
||||
|
||||
/*
|
||||
* Application Loggers
|
||||
*/
|
||||
$container->share('monolog.logger.application.cli', [$this, 'getMonologLoggerApplicationCliService'], true);
|
||||
$container->share('monolog.logger.application.web', [$this, 'getMonologLoggerApplicationWebService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `monolog.handler.application` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return StreamHandler
|
||||
*/
|
||||
public function getMonologHandlerApplicationService(Container $container): StreamHandler
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
$level = strtoupper($config->get('log.application', $config->get('log.level', 'error')));
|
||||
|
||||
return new StreamHandler(LPATH_ROOT . '/logs/framework.log', \constant('\\Monolog\\Logger::' . $level));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `monolog.logger.application.cli` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Logger
|
||||
*/
|
||||
public function getMonologLoggerApplicationCliService(Container $container): Logger
|
||||
{
|
||||
return new Logger(
|
||||
'Framework',
|
||||
[
|
||||
$container->get('monolog.handler.application'),
|
||||
],
|
||||
[
|
||||
$container->get('monolog.processor.psr3'),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `monolog.logger.application.web` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Logger
|
||||
*/
|
||||
public function getMonologLoggerApplicationWebService(Container $container): Logger
|
||||
{
|
||||
return new Logger(
|
||||
'Framework',
|
||||
[
|
||||
$container->get('monolog.handler.application'),
|
||||
],
|
||||
[
|
||||
$container->get('monolog.processor.psr3'),
|
||||
$container->get('monolog.processor.web'),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `monolog.processor.psr3` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return PsrLogMessageProcessor
|
||||
*/
|
||||
public function getMonologProcessorPsr3Service(Container $container): PsrLogMessageProcessor
|
||||
{
|
||||
return new PsrLogMessageProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `monolog.processor.web` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return WebProcessor
|
||||
*/
|
||||
public function getMonologProcessorWebService(Container $container): WebProcessor
|
||||
{
|
||||
return new WebProcessor;
|
||||
}
|
||||
}
|
126
libraries/src/Service/SessionProvider.php
Normal file
126
libraries/src/Service/SessionProvider.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\Database\DatabaseInterface;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\Dispatcher;
|
||||
use Joomla\Session\Session;
|
||||
use Joomla\Session\SessionInterface;
|
||||
use Joomla\Session\Storage\NativeStorage as SessionNativeStorage;
|
||||
use Joomla\Session\StorageInterface;
|
||||
use Joomla\Session\Handler\DatabaseHandler as SessionDatabaseHandler;
|
||||
use Joomla\Session\HandlerInterface;
|
||||
use Kumwe\CMS\Session\MetadataManager;
|
||||
|
||||
/**
|
||||
* Session service provider
|
||||
*/
|
||||
class SessionProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->alias(SessionDatabaseHandler::class, HandlerInterface::class)
|
||||
->share(HandlerInterface::class, [$this, 'getSessionDatabaseHandlerClassService'], true);
|
||||
|
||||
$container->alias(SessionNativeStorage::class, StorageInterface::class)
|
||||
->share(StorageInterface::class, [$this, 'getSessionNativeStorageClassService'], true);
|
||||
|
||||
$container->alias(Session::class, SessionInterface::class)
|
||||
->share(SessionInterface::class, [$this, 'getSessionClassService'], true);
|
||||
|
||||
$container->alias(MetadataManager::class, MetadataManager::class)
|
||||
->share(MetadataManager::class, [$this, 'getMetadataManagerClassService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the session metadata manager service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return MetadataManager
|
||||
*/
|
||||
public function getMetadataManagerClassService(Container $container): MetadataManager
|
||||
{
|
||||
return new MetadataManager(
|
||||
$container->get(DatabaseInterface::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `admin.session` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return SessionInterface
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getSessionClassService(Container $container): SessionInterface
|
||||
{
|
||||
/** @var \Joomla\Session\Session; $session */
|
||||
$session = new Session($container->get(SessionNativeStorage::class), $container->get(Dispatcher::class));
|
||||
|
||||
// Start session if not already started
|
||||
if (empty($session->getId()))
|
||||
{
|
||||
$session->start();
|
||||
}
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Session Database Handler service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return HandlerInterface
|
||||
*/
|
||||
public function getSessionDatabaseHandlerClassService(Container $container): HandlerInterface
|
||||
{
|
||||
return new SessionDatabaseHandler($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `admin.session` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return StorageInterface
|
||||
*/
|
||||
public function getSessionNativeStorageClassService(Container $container): StorageInterface
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
// Generate a session name. (not secure enough)
|
||||
$name = md5('kumweAdmin');
|
||||
|
||||
// Calculate the session lifetime.
|
||||
$lifetime = $config->get('lifetime') ? $config->get('lifetime') * 60 : 900;
|
||||
|
||||
// Initialize the options for the Session object.
|
||||
$options = [
|
||||
'name' => $name,
|
||||
'expire' => $lifetime
|
||||
];
|
||||
|
||||
return new SessionNativeStorage($container->get(SessionDatabaseHandler::class), $options);
|
||||
}
|
||||
}
|
265
libraries/src/Service/SiteApplicationProvider.php
Normal file
265
libraries/src/Service/SiteApplicationProvider.php
Normal file
@ -0,0 +1,265 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\Application\AbstractWebApplication;
|
||||
use Joomla\Application\Controller\ContainerControllerResolver;
|
||||
use Joomla\Application\Controller\ControllerResolverInterface;
|
||||
use Joomla\Application\Web\WebClient;
|
||||
use Joomla\Database\DatabaseInterface;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
|
||||
use Kumwe\CMS\Controller\WrongCmsController;
|
||||
use Kumwe\CMS\Controller\PageController;
|
||||
use Kumwe\CMS\Model\PageModel;
|
||||
use Kumwe\CMS\Utilities\StringHelper;
|
||||
use Kumwe\CMS\View\Site\PageHtmlView;
|
||||
use Kumwe\CMS\Application\SiteApplication;
|
||||
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Router\Route;
|
||||
use Joomla\Router\Router;
|
||||
use Joomla\Router\RouterInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Site Application service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/ApplicationProvider.php
|
||||
*/
|
||||
class SiteApplicationProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
/*
|
||||
* Application Classes
|
||||
*/
|
||||
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(SiteApplication::class, AbstractWebApplication::class)
|
||||
->share(AbstractWebApplication::class, [$this, 'getSiteApplicationClassService']);
|
||||
|
||||
/*
|
||||
* Application Helpers and Dependencies
|
||||
*/
|
||||
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(ContainerControllerResolver::class, ControllerResolverInterface::class)
|
||||
->share(ControllerResolverInterface::class, [$this, 'getControllerResolverService']);
|
||||
|
||||
$container->share(WebClient::class, [$this, 'getWebClientService'], true);
|
||||
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(RouterInterface::class, 'application.router')
|
||||
->alias(Router::class, 'application.router')
|
||||
->share('application.router', [$this, 'getApplicationRouterService']);
|
||||
|
||||
/*
|
||||
* MVC Layer
|
||||
*/
|
||||
|
||||
// Controllers
|
||||
$container->alias(PageController::class, 'controller.page')
|
||||
->share('controller.page', [$this, 'getControllerPageService'], true);
|
||||
|
||||
$container->alias(WrongCmsController::class, 'controller.wrong.cms')
|
||||
->share('controller.wrong.cms', [$this, 'getControllerWrongCmsService'], true);
|
||||
|
||||
// Models
|
||||
$container->alias(PageModel::class, 'model.page')
|
||||
->share('model.page', [$this, 'getModelPageService'], true);
|
||||
|
||||
// Views
|
||||
$container->alias(PageHtmlView::class, 'view.page.html')
|
||||
->share('view.page.html', [$this, 'getViewPageHtmlService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `application.router` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return RouterInterface
|
||||
*/
|
||||
public function getApplicationRouterService(Container $container): RouterInterface
|
||||
{
|
||||
$router = new Router;
|
||||
|
||||
/*
|
||||
* CMS Admin Panels
|
||||
*/
|
||||
$router->get(
|
||||
'/wp-admin',
|
||||
WrongCmsController::class
|
||||
);
|
||||
|
||||
$router->get(
|
||||
'/wp-admin/*',
|
||||
WrongCmsController::class
|
||||
);
|
||||
|
||||
$router->get(
|
||||
'wp-login.php',
|
||||
WrongCmsController::class
|
||||
);
|
||||
|
||||
/*
|
||||
* Web routes
|
||||
*/
|
||||
$router->addRoute(new Route(['GET', 'HEAD'], '/', PageController::class));
|
||||
|
||||
// dynamic pages
|
||||
$pages = '/:root';
|
||||
$router->get(
|
||||
$pages,
|
||||
PageController::class
|
||||
);
|
||||
// set a mad depth TODO: we should limit the menu depth to 6 or something
|
||||
$depth = range(1,20);
|
||||
foreach ($depth as $page)
|
||||
{
|
||||
$page = StringHelper::numbers($page);
|
||||
$pages .= "/:$page";
|
||||
$router->get(
|
||||
$pages,
|
||||
PageController::class
|
||||
);
|
||||
}
|
||||
|
||||
return $router;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.page` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return PageController
|
||||
*/
|
||||
public function getControllerPageService(Container $container): PageController
|
||||
{
|
||||
return new PageController(
|
||||
$container->get(PageHtmlView::class),
|
||||
$container->get(Input::class),
|
||||
$container->get(SiteApplication::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `controller.wrong.cms` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return WrongCmsController
|
||||
*/
|
||||
public function getControllerWrongCmsService(Container $container): WrongCmsController
|
||||
{
|
||||
return new WrongCmsController(
|
||||
$container->get(Input::class),
|
||||
$container->get(SiteApplication::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `model.page` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return PageModel
|
||||
*/
|
||||
public function getModelPageService(Container $container): PageModel
|
||||
{
|
||||
return new PageModel($container->get(DatabaseInterface::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WebApplication class service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return SiteApplication
|
||||
*/
|
||||
public function getSiteApplicationClassService(Container $container): SiteApplication
|
||||
{
|
||||
$application = new SiteApplication(
|
||||
$container->get(ControllerResolverInterface::class),
|
||||
$container->get(RouterInterface::class),
|
||||
$container->get(Input::class),
|
||||
$container->get('config'),
|
||||
$container->get(WebClient::class)
|
||||
);
|
||||
|
||||
$application->httpVersion = '2';
|
||||
|
||||
// Inject extra services
|
||||
$application->setDispatcher($container->get(DispatcherInterface::class));
|
||||
$application->setLogger($container->get(LoggerInterface::class));
|
||||
|
||||
return $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the controller resolver service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ControllerResolverInterface
|
||||
*/
|
||||
public function getControllerResolverService(Container $container): ControllerResolverInterface
|
||||
{
|
||||
return new ContainerControllerResolver($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `view.page.html` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return PageHtmlView
|
||||
*/
|
||||
public function getViewPageHtmlService(Container $container): PageHtmlView
|
||||
{
|
||||
$view = new PageHtmlView(
|
||||
$container->get('model.page'),
|
||||
$container->get('renderer')
|
||||
);
|
||||
|
||||
$view->setLayout('page.twig');
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the web client service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return WebClient
|
||||
*/
|
||||
public function getWebClientService(Container $container): WebClient
|
||||
{
|
||||
/** @var Input $input */
|
||||
$input = $container->get(Input::class);
|
||||
$userAgent = $input->server->getString('HTTP_USER_AGENT', '');
|
||||
$acceptEncoding = $input->server->getString('HTTP_ACCEPT_ENCODING', '');
|
||||
$acceptLanguage = $input->server->getString('HTTP_ACCEPT_LANGUAGE', '');
|
||||
|
||||
return new WebClient($userAgent, $acceptEncoding, $acceptLanguage);
|
||||
}
|
||||
}
|
313
libraries/src/Service/SiteTemplatingProvider.php
Normal file
313
libraries/src/Service/SiteTemplatingProvider.php
Normal file
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Framework Website
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 Open Source Matters, Inc. All rights reserved.
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\Application\AbstractApplication;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Session\SessionInterface;
|
||||
use Kumwe\CMS\Asset\MixPathPackage;
|
||||
use Kumwe\CMS\Renderer\ApplicationContext;
|
||||
use Kumwe\CMS\Renderer\FrameworkExtension;
|
||||
use Kumwe\CMS\Renderer\FrameworkTwigRuntime;
|
||||
use Joomla\Preload\PreloadManager;
|
||||
use Joomla\Renderer\RendererInterface;
|
||||
use Joomla\Renderer\TwigRenderer;
|
||||
use Symfony\Component\Asset\Packages;
|
||||
use Symfony\Component\Asset\PathPackage;
|
||||
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
|
||||
use Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy;
|
||||
use Twig\Cache\CacheInterface;
|
||||
use Twig\Cache\FilesystemCache;
|
||||
use Twig\Cache\NullCache;
|
||||
use Twig\Environment;
|
||||
use Twig\Extension\DebugExtension;
|
||||
use Twig\Extension\ProfilerExtension;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
use Twig\Loader\LoaderInterface;
|
||||
use Twig\Profiler\Profile;
|
||||
use Twig\RuntimeLoader\ContainerRuntimeLoader;
|
||||
|
||||
/**
|
||||
* Templating service provider
|
||||
* source: https://github.com/joomla/framework.joomla.org/blob/master/src/Service/TemplatingProvider.php
|
||||
*/
|
||||
class SiteTemplatingProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->alias(Packages::class, 'asset.packages')
|
||||
->share('asset.packages', [$this, 'getAssetPackagesService'], true);
|
||||
|
||||
$container->alias(RendererInterface::class, 'renderer')
|
||||
->alias(TwigRenderer::class, 'renderer')
|
||||
->share('renderer', [$this, 'getRendererService'], true);
|
||||
|
||||
$container->alias(CacheInterface::class, 'twig.cache')
|
||||
->alias(\Twig_CacheInterface::class, 'twig.cache')
|
||||
->share('twig.cache', [$this, 'getTwigCacheService'], true);
|
||||
|
||||
$container->alias(Environment::class, 'twig.environment')
|
||||
->alias(\Twig_Environment::class, 'twig.environment')
|
||||
->share('twig.environment', [$this, 'getTwigEnvironmentService'], true);
|
||||
|
||||
$container->alias(DebugExtension::class, 'twig.extension.debug')
|
||||
->alias(\Twig_Extension_Debug::class, 'twig.extension.debug')
|
||||
->share('twig.extension.debug', [$this, 'getTwigExtensionDebugService'], true);
|
||||
|
||||
$container->alias(FrameworkExtension::class, 'twig.extension.framework')
|
||||
->share('twig.extension.framework', [$this, 'getTwigExtensionFrameworkService'], true);
|
||||
|
||||
// This service cannot be protected as it is decorated when the debug bar is available
|
||||
$container->alias(ProfilerExtension::class, 'twig.extension.profiler')
|
||||
->alias(\Twig_Extension_Profiler::class, 'twig.extension.profiler')
|
||||
->share('twig.extension.profiler', [$this, 'getTwigExtensionProfilerService']);
|
||||
|
||||
$container->alias(LoaderInterface::class, 'twig.loader')
|
||||
->alias(\Twig_LoaderInterface::class, 'twig.loader')
|
||||
->share('twig.loader', [$this, 'getTwigLoaderService'], true);
|
||||
|
||||
$container->alias(Profile::class, 'twig.profiler.profile')
|
||||
->alias(\Twig_Profiler_Profile::class, 'twig.profiler.profile')
|
||||
->share('twig.profiler.profile', [$this, 'getTwigProfilerProfileService'], true);
|
||||
|
||||
$container->alias(FrameworkTwigRuntime::class, 'twig.runtime.framework')
|
||||
->share('twig.runtime.framework', [$this, 'getTwigRuntimeFrameworkService'], true);
|
||||
|
||||
$container->alias(ContainerRuntimeLoader::class, 'twig.runtime.loader')
|
||||
->alias(\Twig_ContainerRuntimeLoader::class, 'twig.runtime.loader')
|
||||
->share('twig.runtime.loader', [$this, 'getTwigRuntimeLoaderService'], true);
|
||||
|
||||
$this->tagTwigExtensions($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `asset.packages` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Packages
|
||||
*/
|
||||
public function getAssetPackagesService(Container $container): Packages
|
||||
{
|
||||
/** @var AbstractApplication $app */
|
||||
$app = $container->get(AbstractApplication::class);
|
||||
|
||||
$context = new ApplicationContext($app);
|
||||
|
||||
$mediaPath = $app->get('uri.media.path', '/media/');
|
||||
|
||||
$defaultPackage = new PathPackage($mediaPath, new EmptyVersionStrategy, $context);
|
||||
|
||||
$mixStrategy = new MixPathPackage(
|
||||
$defaultPackage,
|
||||
$mediaPath,
|
||||
new JsonManifestVersionStrategy(LPATH_ROOT . '/media/mix-manifest.json'),
|
||||
$context
|
||||
);
|
||||
|
||||
return new Packages(
|
||||
$defaultPackage,
|
||||
[
|
||||
'mix' => $mixStrategy,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `renderer` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return RendererInterface
|
||||
*/
|
||||
public function getRendererService(Container $container): RendererInterface
|
||||
{
|
||||
return new TwigRenderer($container->get('twig.environment'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.cache` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return \Twig_CacheInterface
|
||||
*/
|
||||
public function getTwigCacheService(Container $container): \Twig_CacheInterface
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
// Pull down the renderer config
|
||||
$cacheEnabled = $config->get('template.cache.enabled', false);
|
||||
$cachePath = $config->get('template.cache.path', 'cache/twig');
|
||||
$debug = $config->get('template.debug', false);
|
||||
|
||||
if ($debug === false && $cacheEnabled !== false)
|
||||
{
|
||||
return new FilesystemCache(LPATH_ROOT . '/' . $cachePath);
|
||||
}
|
||||
|
||||
return new NullCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.environment` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Environment
|
||||
*/
|
||||
public function getTwigEnvironmentService(Container $container): Environment
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
$debug = $config->get('template.debug', false);
|
||||
|
||||
$environment = new Environment(
|
||||
$container->get('twig.loader'),
|
||||
['debug' => $debug]
|
||||
);
|
||||
|
||||
// Add the runtime loader
|
||||
$environment->addRuntimeLoader($container->get('twig.runtime.loader'));
|
||||
|
||||
// Set up the environment's caching service
|
||||
$environment->setCache($container->get('twig.cache'));
|
||||
|
||||
// Add the Twig extensions
|
||||
$environment->setExtensions($container->getTagged('twig.extension'));
|
||||
|
||||
// Add a global tracking the debug states
|
||||
$environment->addGlobal('appDebug', $config->get('debug', false));
|
||||
$environment->addGlobal('fwDebug', $debug);
|
||||
|
||||
return $environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.extension.debug` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return DebugExtension
|
||||
*/
|
||||
public function getTwigExtensionDebugService(Container $container): DebugExtension
|
||||
{
|
||||
return new DebugExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.extension.framework` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return FrameworkExtension
|
||||
*/
|
||||
public function getTwigExtensionFrameworkService(Container $container): FrameworkExtension
|
||||
{
|
||||
return new FrameworkExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.extension.profiler` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ProfilerExtension
|
||||
*/
|
||||
public function getTwigExtensionProfilerService(Container $container): ProfilerExtension
|
||||
{
|
||||
return new ProfilerExtension($container->get('twig.profiler.profile'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.loader` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return \Twig_LoaderInterface
|
||||
*/
|
||||
public function getTwigLoaderService(Container $container): \Twig_LoaderInterface
|
||||
{
|
||||
return new FilesystemLoader([LPATH_TEMPLATES]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.profiler.profile` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Profile
|
||||
*/
|
||||
public function getTwigProfilerProfileService(Container $container): Profile
|
||||
{
|
||||
return new Profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.runtime.framework` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return FrameworkTwigRuntime
|
||||
*/
|
||||
public function getTwigRuntimeFrameworkService(Container $container): FrameworkTwigRuntime
|
||||
{
|
||||
return new FrameworkTwigRuntime(
|
||||
$container->get(AbstractApplication::class),
|
||||
$container->get(PreloadManager::class),
|
||||
LPATH_ROOT . '/media/sri-manifest.json'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `twig.runtime.loader` service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return ContainerRuntimeLoader
|
||||
*/
|
||||
public function getTwigRuntimeLoaderService(Container $container): ContainerRuntimeLoader
|
||||
{
|
||||
return new ContainerRuntimeLoader($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag services which are Twig extensions
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function tagTwigExtensions(Container $container): void
|
||||
{
|
||||
/** @var \Joomla\Registry\Registry $config */
|
||||
$config = $container->get('config');
|
||||
|
||||
$debug = $config->get('template.debug', false);
|
||||
|
||||
$twigExtensions = ['twig.extension.framework'];
|
||||
|
||||
if ($debug)
|
||||
{
|
||||
$twigExtensions[] = 'twig.extension.debug';
|
||||
}
|
||||
|
||||
$container->tag('twig.extension', $twigExtensions);
|
||||
}
|
||||
}
|
81
libraries/src/Service/UserProvider.php
Normal file
81
libraries/src/Service/UserProvider.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Kumwe CMS
|
||||
*
|
||||
* @created 9th April 2022
|
||||
* @author Llewellyn van der Merwe <https://git.vdm.dev/Llewellyn>
|
||||
* @git Kumwe CMS <https://git.vdm.dev/Kumwe/cms>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Service;
|
||||
|
||||
use Joomla\Authentication\AuthenticationStrategyInterface;
|
||||
use Joomla\Authentication\Strategies\DatabaseStrategy;
|
||||
use Joomla\Input\Input;
|
||||
use Kumwe\CMS\Session\MetadataManager;
|
||||
use Kumwe\CMS\User\UserFactory;
|
||||
use Kumwe\CMS\User\UserFactoryInterface;
|
||||
use Joomla\Database\DatabaseInterface;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* Service provider for the user dependency
|
||||
*
|
||||
* @since 1.0.0
|
||||
* source: https://github.com/joomla/joomla-cms/blob/4.2-dev/libraries/src/Service/Provider/User.php
|
||||
*/
|
||||
class UserProvider implements ServiceProviderInterface
|
||||
{
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->alias('user.factory', UserFactoryInterface::class)
|
||||
->alias(UserFactory::class, UserFactoryInterface::class)
|
||||
->share(UserFactoryInterface::class, [$this, 'getUserFactoryService'], true);
|
||||
|
||||
$container->alias(DatabaseStrategy::class, AuthenticationStrategyInterface::class)
|
||||
->share(AuthenticationStrategyInterface::class, [$this, 'getAuthenticationStrategyService'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UserFactoryInterface class service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return UserFactoryInterface
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getUserFactoryService(Container $container): UserFactoryInterface
|
||||
{
|
||||
return new UserFactory(
|
||||
$container->get(DatabaseInterface::class),
|
||||
$container->get(AuthenticationStrategyInterface::class),
|
||||
$container->get(MetadataManager::class)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AuthenticationStrategyInterface class service
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return AuthenticationStrategyInterface
|
||||
*/
|
||||
public function getAuthenticationStrategyService(Container $container): AuthenticationStrategyInterface
|
||||
{
|
||||
return new DatabaseStrategy(
|
||||
$container->get(Input::class),
|
||||
$container->get(DatabaseInterface::class)
|
||||
);
|
||||
}
|
||||
}
|
326
libraries/src/Session/MetadataManager.php
Normal file
326
libraries/src/Session/MetadataManager.php
Normal file
@ -0,0 +1,326 @@
|
||||
<?php
|
||||
/**
|
||||
* Joomla! Content Management System
|
||||
*
|
||||
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Kumwe\CMS\Session;
|
||||
|
||||
use Kumwe\CMS\User\User;
|
||||
use Joomla\Database\DatabaseInterface;
|
||||
use Joomla\Database\Exception\ExecutionFailureException;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Session\SessionInterface;
|
||||
|
||||
/**
|
||||
* Manager for optional session metadata.
|
||||
*
|
||||
* @since 3.8.6
|
||||
* @internal
|
||||
*/
|
||||
final class MetadataManager
|
||||
{
|
||||
/**
|
||||
* Internal variable indicating a session record exists.
|
||||
*
|
||||
* @var integer
|
||||
* @since 4.0.0
|
||||
* @note Once PHP 7.1 is the minimum supported version this should become a private constant
|
||||
*/
|
||||
private static $sessionRecordExists = 1;
|
||||
|
||||
/**
|
||||
* Internal variable indicating a session record does not exist.
|
||||
*
|
||||
* @var integer
|
||||
* @since 4.0.0
|
||||
* @note Once PHP 7.1 is the minimum supported version this should become a private constant
|
||||
*/
|
||||
private static $sessionRecordDoesNotExist = 0;
|
||||
|
||||
/**
|
||||
* Internal variable indicating an unknown session record statue.
|
||||
*
|
||||
* @var integer
|
||||
* @since 4.0.0
|
||||
* @note Once PHP 7.1 is the minimum supported version this should become a private constant
|
||||
*/
|
||||
private static $sessionRecordUnknown = -1;
|
||||
|
||||
/**
|
||||
* Database driver.
|
||||
*
|
||||
* @var DatabaseInterface
|
||||
* @since 3.8.6
|
||||
*/
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* MetadataManager constructor.
|
||||
*
|
||||
* @param DatabaseInterface $db Database driver.
|
||||
*
|
||||
* @since 3.8.6
|
||||
*/
|
||||
public function __construct(DatabaseInterface $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the metadata record if it does not exist.
|
||||
*
|
||||
* @param SessionInterface $session The session to create the metadata record for.
|
||||
* @param User $user The user to associate with the record.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.8.6
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function createRecordIfNonExisting(SessionInterface $session, User $user)
|
||||
{
|
||||
$exists = $this->checkSessionRecordExists($session->getId());
|
||||
|
||||
// Only touch the database if the record does not already exist
|
||||
if ($exists !== self::$sessionRecordExists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->createSessionRecord($session, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the metadata record if it does not exist.
|
||||
*
|
||||
* @param SessionInterface $session The session to create or update the metadata record for.
|
||||
* @param User $user The user to associate with the record.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function createOrUpdateRecord(SessionInterface $session, User $user)
|
||||
{
|
||||
$exists = $this->checkSessionRecordExists($session->getId());
|
||||
|
||||
// Do not try to touch the database if we can't determine the record state
|
||||
if ($exists === self::$sessionRecordUnknown)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ($exists === self::$sessionRecordDoesNotExist)
|
||||
{
|
||||
$this->createSessionRecord($session, $user);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->updateSessionRecord($session, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete records with a timestamp prior to the given time.
|
||||
*
|
||||
* @param integer $time The time records should be deleted if expired before.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.8.6
|
||||
*/
|
||||
public function deletePriorTo($time)
|
||||
{
|
||||
$query = $this->db->getQuery(true)
|
||||
->delete($this->db->quoteName('#__session'))
|
||||
->where($this->db->quoteName('time') . ' < :time')
|
||||
->bind(':time', $time, ParameterType::INTEGER);
|
||||
|
||||
$this->db->setQuery($query);
|
||||
|
||||
try
|
||||
{
|
||||
$this->db->execute();
|
||||
}
|
||||
catch (ExecutionFailureException $exception)
|
||||
{
|
||||
// Since garbage collection does not result in a fatal error when run in the session API, we don't allow it here either.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get session record exists
|
||||
*
|
||||
* @param string $sessionId The session ID to check
|
||||
*
|
||||
* @return mixed on success value for record presence
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getSessionRecord(string $sessionId)
|
||||
{
|
||||
$query = $this->db->getQuery(true)
|
||||
->select('*')
|
||||
->from($this->db->quoteName('#__session'))
|
||||
->where($this->db->quoteName('session_id') . ' = :session_id')
|
||||
->bind(':session_id', $sessionId)
|
||||
->setLimit(1);
|
||||
|
||||
$this->db->setQuery($query);
|
||||
|
||||
return $this->db->loadObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the session record exists
|
||||
*
|
||||
* @param string $sessionId The session ID to check
|
||||
*
|
||||
* @return integer Status value for record presence
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
private function checkSessionRecordExists(string $sessionId): int
|
||||
{
|
||||
$query = $this->db->getQuery(true)
|
||||
->select($this->db->quoteName('session_id'))
|
||||
->from($this->db->quoteName('#__session'))
|
||||
->where($this->db->quoteName('session_id') . ' = :session_id')
|
||||
->bind(':session_id', $sessionId)
|
||||
->setLimit(1);
|
||||
|
||||
$this->db->setQuery($query);
|
||||
|
||||
try
|
||||
{
|
||||
$exists = $this->db->loadResult();
|
||||
}
|
||||
catch (ExecutionFailureException $e)
|
||||
{
|
||||
return self::$sessionRecordUnknown;
|
||||
}
|
||||
|
||||
if ($exists)
|
||||
{
|
||||
return self::$sessionRecordExists;
|
||||
}
|
||||
|
||||
return self::$sessionRecordDoesNotExist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the session record
|
||||
*
|
||||
* @param SessionInterface $session The session to create the metadata record for.
|
||||
* @param User $user The user to associate with the record.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
private function createSessionRecord(SessionInterface $session, User $user)
|
||||
{
|
||||
$query = $this->db->getQuery(true);
|
||||
|
||||
$time = $session->isNew() ? time() : $session->get('session.timer.start');
|
||||
|
||||
$columns = [
|
||||
$this->db->quoteName('session_id'),
|
||||
$this->db->quoteName('guest'),
|
||||
$this->db->quoteName('time'),
|
||||
$this->db->quoteName('userid'),
|
||||
$this->db->quoteName('username'),
|
||||
];
|
||||
|
||||
// Add query placeholders
|
||||
$values = [
|
||||
':session_id',
|
||||
':guest',
|
||||
':time',
|
||||
':user_id',
|
||||
':username',
|
||||
];
|
||||
|
||||
// Bind query values
|
||||
$sessionId = $session->getId();
|
||||
$userIsGuest = $user->get('guest', 0);
|
||||
$userId = $user->get('id', 0);
|
||||
$username = $user->get('username', '');
|
||||
|
||||
$query->bind(':session_id', $sessionId)
|
||||
->bind(':guest', $userIsGuest, ParameterType::INTEGER)
|
||||
->bind(':time', $time)
|
||||
->bind(':user_id', $userId, ParameterType::INTEGER)
|
||||
->bind(':username', $username);
|
||||
|
||||
$query->insert($this->db->quoteName('#__session'))
|
||||
->columns($columns)
|
||||
->values(implode(', ', $values));
|
||||
|
||||
$this->db->setQuery($query);
|
||||
|
||||
try
|
||||
{
|
||||
$this->db->execute();
|
||||
}
|
||||
catch (ExecutionFailureException $e)
|
||||
{
|
||||
// This failure isn't critical, we can go on without the metadata
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the session record
|
||||
*
|
||||
* @param SessionInterface $session The session to update the metadata record for.
|
||||
* @param User $user The user to associate with the record.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
private function updateSessionRecord(SessionInterface $session, User $user)
|
||||
{
|
||||
$query = $this->db->getQuery(true);
|
||||
|
||||
$time = time();
|
||||
|
||||
$setValues = [
|
||||
$this->db->quoteName('guest') . ' = :guest',
|
||||
$this->db->quoteName('time') . ' = :time',
|
||||
$this->db->quoteName('userid') . ' = :user_id',
|
||||
$this->db->quoteName('username') . ' = :username',
|
||||
];
|
||||
|
||||
// Bind query values
|
||||
$sessionId = $session->getId();
|
||||
$userIsGuest = $user->get('guest', 0);
|
||||
$userId = $user->get('id', 0);
|
||||
$username = $user->get('username', '');
|
||||
|
||||
$query->bind(':session_id', $sessionId)
|
||||
->bind(':guest', $userIsGuest, ParameterType::INTEGER)
|
||||
->bind(':time', $time)
|
||||
->bind(':user_id', $userId, ParameterType::INTEGER)
|
||||
->bind(':username', $username);
|
||||
|
||||
$query->update($this->db->quoteName('#__session'))
|
||||
->set($setValues)
|
||||
->where($this->db->quoteName('session_id') . ' = :session_id');
|
||||
|
||||
$this->db->setQuery($query);
|
||||
|
||||
try
|
||||
{
|
||||
$this->db->execute();
|
||||
}
|
||||
catch (ExecutionFailureException $e)
|
||||
{
|
||||
// This failure isn't critical, we can go on without the metadata
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user