32 Commits

Autor SHA1 Nachricht Datum
tom d5263e7405 FIX Field name and description in language file 2023-10-23 22:35:44 +02:00
tom e4a1d2c078 Adding views of stacks, manufacturers lists 2023-10-23 21:55:15 +02:00
tom 577a9f680a FIX publish / unpublish with alias state 2023-10-16 18:00:27 +02:00
tom 303f1c8a00 ADD list of items 2023-10-15 23:23:02 +02:00
tom 36cb70eea0 ADD query of whole database 2023-10-15 16:17:17 +02:00
tom e39dcaf35c ADD stock location field 2023-10-15 12:27:09 +02:00
tom 6845e087f2 UPD edit form 2023-10-15 11:40:55 +02:00
tom d122312ddd ADD fields, field manipulators 2023-10-14 21:15:09 +02:00
tom 436734cd4c ADD B4 Actions: Save and View 2023-10-07 23:33:29 +02:00
tom 9db4ad808b CHG description and label 2023-10-06 17:42:37 +02:00
tom df22394e33 ADD details in documentation for DepotComponent 2023-10-06 05:22:40 +02:00
tom 2b5e287a78 DEL unnecessary code 2023-10-06 04:47:51 +02:00
tom 7f79667409 CHG component_name and its label, description 2023-10-06 04:46:37 +02:00
tom a3787d1965 typo in .editorconfig 2023-10-06 04:38:41 +02:00
tom 6928ff5a74 Fix syntax error, unexpected token "(" 2023-10-05 14:56:39 +02:00
tom e30b2c6550 Fix header of file 2023-10-05 14:51:28 +02:00
tom 4786bf13d9 reduce forms/part.xml 2023-10-05 14:48:35 +02:00
tom d9220cd888 FIX typo form(s)! 2023-10-05 14:36:41 +02:00
tom 70e987b338 part.xml was in wrong folder, must be "admin/forms" 2023-10-05 14:34:11 +02:00
tom 47796a6ada try to get it work 2023-10-05 11:45:44 +02:00
tom f85556f466 try to get it compile 2023-10-05 11:45:29 +02:00
tom 5f1db1b0f5 Echo instead of the short php form 2023-10-05 03:26:48 +02:00
tom eebafe0241 ADD PartTable, several typos 2023-10-05 03:06:49 +02:00
tom 336eb346a7 remove old style array() 2023-10-05 02:43:12 +02:00
tom f0b8e1ed02 ADD MVC for part 2023-10-05 02:28:17 +02:00
tom 35c19b24e3 FIX typo in Menu Stocks 2023-10-04 21:00:04 +02:00
tom 618a995a94 CHG SQL style for creating the table 2023-10-04 20:55:41 +02:00
tom d9dcfeea3a ADD the update 0.0.2.sql 2023-10-04 19:12:52 +02:00
tom 4e75af67ed ADD database tables b_2 2023-10-04 18:06:13 +02:00
tom f9004e46cb Add .editorconfig file to get right representation in gitea editor and view 2023-10-03 12:55:24 +02:00
tom 22e7f13228 MVCComponent already extended by Extension\DepotComponent 2023-10-03 11:09:44 +02:00
tom 6bd4d53333 B1 first commit, example 2023-10-03 03:56:38 +02:00
68 geänderte Dateien mit 3334 neuen und 2446 gelöschten Zeilen
+13
Datei anzeigen
@@ -0,0 +1,13 @@
# Top-most EditorConfig file
root = true
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = UTF-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
+44 -6
Datei anzeigen
@@ -140,12 +140,50 @@ this project should follow.
## Syntax and indentation
1. Use K&R-style. Of course, we can't and don't want to force anybody to use a
style he or she is not used to, but, at the very least, when you write code
that goes into the core of PHP or one of its standard modules, please
maintain the K&R style. This applies to just about everything, starting with
indentation and comment styles and up to function declaration syntax. Also
1. Use K&R-style and use 1TBS ()"One True Bace Style").
Of course, we can't and don't
want to force anybody to use a style he or she is not used to, but, at the very
least, when you write code that goes into the core of PHP or one of its standard
modules, please maintain the K&R style.
This applies to just about everything, starting with indentation and comment
styles and up to function declaration syntax. Also
see [Indentstyle](http://www.catb.org/~esr/jargon/html/I/indent-style.html).
When following K&R, each function has its opening brace at the next line on the
same indentation level as its header, the statements within the braces are
indented, and the closing brace at the end is on the same indentation level as
the header of the function at a line of its own.
```php
protected function batch_client($value, $pks, $contexts)
{
// Set the variables
$user = $this->getCurrentUser();
$table = $this->getTable();
foreach ($pks as $pk) {
if (!$user->authorise('core.edit', $contexts[$pk])) {
$this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT'));
return false;
}
$table->reset();
$table->load($pk);
$table->cid = (int) $value;
if (!$table->store()) {
$this->setError($table->getError());
return false;
}
}
// Clean the cache
$this->cleanCache();
return true;
}
```
1. Be generous with whitespace and braces. Keep one empty line between the
variable declaration section and the statements in a block, as well as
@@ -165,7 +203,7 @@ this project should follow.
```
1. When indenting, use the tab character. A tab is expected to represent four
spaces. It is important to maintain consistency in indentation so that
spaces (1 tab == 4 spaces). It is important to maintain consistency in indentation so that
definitions, comments, and control structures line up correctly.
## Trailing whitespace, EOF
+361
Datei anzeigen
@@ -0,0 +1,361 @@
# GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 Lesser 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.
## 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 an idea of what it does.
Copyright (C) yyyy 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 Lesser General Public
License](https://www.gnu.org/licenses/lgpl.html) instead of this
License.
-339
Datei anzeigen
@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General
Public License instead of this License.
+714
Datei anzeigen
@@ -0,0 +1,714 @@
# Depot
## Introduction
This project is also based on the desperation to sort and find my electronic
components. Some integrated circuits (ICs) accumulated in various boxes and
the question of whether I own that or the other IC, had to be painstakingly
researched. Above all, there were at one time several places where components
were stored or partly kept at a plant.
The idea was born, but it took long time to implement it.
Klosterneuburg, October 2023 Thomas Kuschel KW4NZ.
## Workflow (since 0.0.1)
In git we start to make a new branch named b1_basic_backend, where we start
developing our project. The first run with simply renaming entries from a
copy of the component **com_banners** did not work as expected.
So let us start at the very beginning:
## Adding basic files for component (b1_basic_backend)
With the git branch **b1_basic_backend**
Add the following basic six files:
1. admin
- src/Extension/DepotComponent.php: The main extension file for the component.
- services/provider.php: It tells Joomla how to initialize or boot the component.
- src/Controller/DisplayController.php: The default Controller for the component.
- src/View/Parts/HtmlView.php: The Html View for the "Parts" page.
- tmpl/parts/default.php: The layout file for the "Parts" page.
2. depot.xml: XML manifest file that tells Joomla! how to install the component.
#### Description of each file:
##### 1. DepotComponent.php
This file contains class for the extension. The class extends MVCComponent.
Compare this version with the original at [Tech Fry Tutorium](https://www.techfry.com/joomla/adding-basic-files-for-component).
```php
namespace KW4NZ\Component\Depot\Administrator\Extension;
use Joomla\CMS\Extension\MVCComponent;
class DepotComponent extends MVCComponent
{
}
```
##### 2. provider.php
This is a special file that tells Joomla how to initialize the component - which
services it requires and how they should be provided.
The service provider file registers dependencies the component will use.
Here, we have included two dependencies:
- **DispatcherFactory** is needed to create the Dispatcher class instance,
and then Joomla will call dispatch() on this Dispatcher object, as the
next step in running the component.
- **MVCFactory** is needed to create the Controller, View, Model and Table class
instances on behalf of the component.
##### 3. DisplayController.php
This is a **default controller** for the component. It simply sets its default
view and leaves the rest to its parent.
When you view the component through URL, Joomla uses the **controller** to execute
the **task**. The task is the name of method in the controller file.
If you do not pass the controller or task in the URL, it defaults to Display
Controller and display Task.
The default view is the name of the component. So, here we need to override the
default view to `parts`.
##### 4. HtmlView.php
This file contains class HtmlView that extends BaseHtmlView. The BaseHtmlView is
the base class for a Joomla View.
The **view gets the data from the model to be output by the layout file.**
For example:
```php
$this->msg = $this->get('Msg');
```
This method converts the get('Msg') call into a getMsg() call on the model, which
is the method which you have to provide in the model.
The view file displays data using the template layout file - $tpl, which defaults
to default.php.
##### 5. default.php
This file holds the template for the page. When no specific layout is
requested for a view, Joomla will load the template in the **default.php** file.
```php
<h2>Welcome to Depot Component!</h2>
```
##### 6. depot.xml
This file tells Joomla how to install the component and what file are included.
In the administration part, we include a link to the menu and include files
and folders (services, src, tmpl and so on) which are in the parent folder
admin of the component. While installing the component, these will get copied
to the Joomla administrator/components/com_depot.
#### Installation the component
Create a **.zip** file of the com_depot directory. Then inside the Joomla
Administration upload this .zip package.
Now you should see a new link "Depot" in the "Compnents" section of the menu.
If you click it, you should see the default "Depot" page.
#### Language files
We create two language files for the system and the component **Depot** at
the directory /admin/language/en-GB/ naming it
- com_depot.ini
- com_depot.sys.ini
---
## Creating and managing Joomla database (b2_database)
With the new git branch **b2_database** we continue our workflow.
Joomla usually manage its content with a database. In our component, we use
a MariaDB database. At the time of development of this component we have PHP8.2,
and we use Mariadb database with version from 11.1,
client 15.2 for Linux (x86_64) using readline 5.1
We support MySQL and MariaDB; not tested support for PostgreSQL.
In the manifest file \<component_name\>.xml, here the file **depot.xml**,
there are installation instructions to "install", "uninstall", and
"update" the Joomla extension/component.
The SQL plain text files are stored in and as:
- admin/sql/
- install.mysql.utf8.sql
- uninstall.mysql.utf8.sql
- admin/sql/updates/mysql/
- 0.0.1.sql
- 0.0.4.sql
- 0.0.5.sql
#### Database table installation
1. When the component is installed for the first time, the file
**install.mysql.utf8.sql** is executed.
1. If the component is already installed, the update
scenario comes into play, the folder **admin/sql/updates/mysql/**: Only the files with higher version
numbers than the installed version of the component will be
executed in ascending order.<br>
Hint: The version of the installed component is stored in the
Joomla's table "#__schemas".
The "#__"-prefix is substituted automatically with the database prefix, (e.g. "jm_") which is defined in the configuration file (configuration.php) of the installed Joomla version as parameter $dbprefix.
**install.mysql.utf8.sql**
```sql
DROP TABLE IF EXISTS `#__depot`;
CREATE TABLE `#__depot`(
`id` SERIAL,
`component_name` VARCHAR(1024) CHARACTER SET ascii COLLATE ascii_general_ci NULL DEFAULT NULL
COMMENT 'unique component name (ASCII characters only)',
`alias` VARCHAR(1024) NOT NULL DEFAULT '',
`description` VARCHAR(4000) NOT NULL DEFAULT '',
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`quantity_exp` INT(11) NOT NULL DEFAULT 0
COMMENT 'Exponent of the quantity (10^x of the number, usually 0 i.e. 10⁰)',
`asset_id` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.',
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`checked_out` INT(11) NOT NULL DEFAULT 0,
`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`path` VARCHAR(400) NOT NULL DEFAULT '',
`state` TINYINT(4) NOT NULL DEFAULT 0
COMMENT 'Published=1,Unpublished=0,Archived=2,Trashed=-2',
`access` TINYINT(4) NOT NULL DEFAULT 0,
`params` VARCHAR(1024) NOT NULL DEFAULT '',
`image` VARCHAR(1024) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0,
`version` int unsigned NOT NULL DEFAULT 1,
-- references to other tables:
`category_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_alt` VARCHAR(1024) NOT NULL DEFAULT '',
`manufacturer_id` INT(11) NOT NULL DEFAULT 0,
`stock_id` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_state` (`state`),
KEY `idx_stock_id` (`stock_id`),
KEY `idx_manufacturer` (`manufacturer_id`),
UNIQUE KEY `aliasindex` (`alias`,`manufacturer_id`,`stock_id`)
) ENGINE=InnoDB
AUTO_INCREMENT=0
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `#__depot` (`component_name`,`alias`,`description`,`quantity`,`created`,
`ordering`,`state`,`manufacturer_id`) VALUES
('1N5404','1n5404','diode, rectifier 3A',9,'2023-09-25 15:00:00',1,1,1),
('1N4148','1n4148','diode, general purpose',1234,'2023-09-25 15:15:15',2,1,2);
```
The table is created in the database when the component is installed.
Also two lines of sample data are inserted into the table "#__depot".
#### Database table uninstallation
When the component is uninstalled the
**uninstall.mysql.utf8 sql** is executed.
We drop the used tables from the database.
**install.mysql.utf8.sql**
```sql
DROP TABLE IF EXISTS `#__depot`;
```
#### Database table update
When the component is updated the
**admin/sql/updates/mysql** folder with its files is executed.
Even if you do not need a database update, you can add an empty file in admin/sql/updates/mysql/0.0.2.sql to initialize the schema version.
In future versions, if you plan to use database tables, the update can be performed automatically.
We create an empty file, just with a comment "-- version 0.0.2"
**admin/sql/updates/mysql/0.0.2.sql**
```sql
-- version 0.0.2
```
#### Manifest file for extensions
The sql files are only executed if they exist in the \<component_name\>.xml manifest file. We add this after the namespace tag, just before the files information tag:
```php
<install> <!-- Runs on install -->
<sql>
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
</sql>
</install>
<uninstall> <!-- Runs on uninstall -->
<sql>
<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update>
<schemas>
<schemapath type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
```
The **\<version\> tag** of the manifest must be updated to 0.0.2 and
also add the sql folder in the administration files section.
#### Table class
**src/table/DepotTable.php**
For each database table, you have to define a table class. The model
asks the table to get information or perform database operations.
This table class has to be defined in admin/src/Table/DepotTable.php file.
```php
<?php
namespace KW4NZ\Component\Depot\Administrator\Table;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
\defined('_JEXEC') or die;
class DepotTable extends Table
{
function __contruct(DatabaseDriver $db)
{
parent::__contruct('#__depot', 'id', $db);
}
}
```
Joomla uses the **Table Object** to get item or record, insert records,
update or delete records for the database operations.
Methods in the table objects are:
1. **load()** to load the existing record from the database, passing
the primary key of the record.
1. **bind()** to set the new values for the fields.
1. **check()** to perform any validation.
1. **store()** to save the new values to the database.
1. **delete()** to delete the record from the database.
---
## Get a Form in Joomla component (b3_form)
The **Form** class of Joomla is used to create complex forms with flexible
layouts and dynamic properties. First, the form fields are defined in the
XML file. Then the view file gets the form from the model and layout file
displays the form.
#### XML Form file
**admin/forms/part.xml**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<form>
<field
name="title"
type="text"
label="JGLOBAL_TITLE"
required="true"
/>
</form>
```
Similarly you can add other fields to the XML file.
#### View file
**admin/src/View/Part/HtmlView.php**
This file is similar to the view file added earlier for the "Parts" view.
The view file gets the form from the model in the display() method.
```php
<?php
namespace KW4NZ\Component\Depot\Administrator\View\Part;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
\defined('_JEDEC') or die;
class HtmlView extends BaseHtmlView
{
protected $form;
protected $item;
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
parent::display($tpl);
}
}
```
The code will look for the method **getForm()**
and **getItem()** in the model file.
We need to get the item to get the ID
of the record in case of editing the existing record.
#### Model file
**admin/src/Model/PartModel.php**
We need to extend the model class with the **AdminModel**.
The AdminModel class extends FormModel class. The **getForm()**
method gets the Form object for the edit form.
```php
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\MVC\Model\AdminModel;
\defined('_JEXEC') or die;
class PartModel extends AdminModel
{
public function getForm($data = array(), $loadData = true)
{
$form = $this->loadForm('com_depot.part',
'part', array('control' => 'jform',
'load_data' => $loadData));
if (empty($form)) {
return false;
}
return $form;
}
}
```
The **loadForm()** and **preprocessForm()** methods are defined in
the FromModel class and the **bind()** method is defined in the
Form class. The first argument (name) of loadForm() is set to
"com_depot.part". The second argument (form xml source) is "part",
and the third argument is the associative array for options.
The form is defined in the source file: **forms/part.xml**
After you have set the $form variable with the Form object,
you check to see if you are loading data to the form.
If you want to pre-load data for the form, you include an element
called "load_data" that is set to a boolean true.
Then, the method calls the loadFormData() method to get the data
for the form. This method gets any previously loaded data from
the session or database.
###### Modifying Form dynamically
Inside the getForm() method, before returning the $form, you can modify the form with many methods of the Form class. You can easily fine-tune your forms dynamically before they are rendered.
#### Layout file - rendering Form
**tmpl/part/edit.php**
After you get the form in the view file ($this->form), the form
is rendered in the layout file (edit.php).
```php
<?php
use Joomla\CMS\HTML\HTMLHelper;
$wa = $this->document->getWebAssetManager();
$wa->useScript('keepalive');
$wa->useScript('form.validate');
?>
<form action="<?= Route::_('index.php?option=com_depot&layout=edit&id=' .
(int) $this->item->id); ?>"
method="post" name="adminForm" id="item-form" class="form-validate">
<?= $this->form->renderField('title'); ?>
<input type="hidden" name="task" value="part.edit" />
<?= HTMLHelper::_('form.token'); ?>
</form>
```
The form validate script is required to submit the for. The renderField() method
of the Form class displays the field - both label and input.
We can access the form using following URL:
```php
administrator/index.php?option=com_depot&view=part&layout=edit
```
It displays edit.php layout file of the Part View. When the form is submitted, the
data is sent to the controller depending upon the action buttons in the toolbar.
Please remember to add the additional folder `form` to the Manifest file "depot.xml", i.e.
just a line before `<folder>services</folder>` :
```xml
<folder>form</folder>
```
---
## Adding administrator's actions (Back-end) - Save and Cancel (b4_actions)
In the form View, you can add action buttons like "Save" and "Cancel" to submit the form
or cancel the editing respectively. These buttons are added to the toolbar.
These buttons require compound tasks (controller and method). For example,
- Save and Edit: part.apply
- Save and Close: part.save
- Cancel: part.cancel
#### View file
**admin/src/View/Part/HtmlView.php**
In the View file, we create a new method to add a toolbar: `addToolbar()`. The
toolbar hides the sidebar menu on forms, sets the title and adds action buttons.
```php
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
protected function addToolbar()
{
Factory::getApplication()->getInput()->set('hidemainmenu', true);
ToolbarHelper::title('Part: Add');
ToolbarHelper::apply('part.apply');
ToolbarHelper::save('part.save');
ToolbarHelper::cancel('part.cancel', 'JTOOLBAR_CLOSE');
}
```
The display() calls this method to include the toolbar.
```php
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->addToolbar();
parent::display($tpl);
}
```
#### Controller file
**admin/src/Controller/PartController.php***
Now, when these action buttons are clicked, Joomla will look for apply(), save() or cancel()
methods in the Part controller. So, create a controller clss that will extend FormController.
These methods are already defined in the parent class.
```php
use Joomla\CMS\MVC\Controller\FormController;
class PartController extends FormController
{
}
```
#### Model file
**admin/src/model/PartModel.php**
If you click on Save button, it will save the data and redirect to the editing screen. However, the data will not be present in the form. Though, we have set `$loadData` to true, we also need to create a method `loadFormData()` to get the data for the form.
```php
protected function loadFormData()
{
$app = Factory::getApplication();
$data = $app->getUserState('com_depot.edit.part.data', []);
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
```
First, this method tries to get the data from the session. If it fails to get data from the
session, then it gets data from the database. The `getItem()` method is defined in the
parent class.
Suppose the user has filled out the form to add a new item but has some invalid data in the
form. In this case, the save will not be successful, so the data is not saved in the
database. It would be very frustrating if the user hat to reenter all the fields to fix a
single error. To handle this scenario, you save the entered data in the user's session.
Only after the save is successful, you clear this out of the session.
So, you either have data from the database, which you can get with `getItem()`, or you have
data from the session, which you can get with `getUserSate()`.
---
## Automatic handling of fields (b5_field_manipulation)
Values of some fields in the form can be automatically handled. There is no need to fill in
the values while creating or editing a record.
For example, `alias` can be generated from the `title` (or here, from the component's name),
dates can be set to the current date or to `null`, user id can be obtained from current
logged in user. Further may you also need to check validity of some fields like "should not
be empty", `alias` should be unique, etc.
The data submitted by the form needs to be modified before saving. This can be done at
various places:
- in the **Model class** by oeverriding the `save()` method or `preparetable()` method.
- in the **Table class** by overriding the `bind()`, `check()`, or `store()` methods.
#### 1. Model file
**admin/src/Model/PartModel.php
```php
public function save($data)
{
/* Add code to modify data before saving */
return parent:save($data);
}
```
It is better to perform automatic handling of fields in the Table class as the data can be
saved not only from administration, but also from frontend, API or by any other means.
##### Example generating Alias
Alias is generated from the `component_name` (or any other field) using **OutputFilter** class
method.
```php
if (empty($data['alias']))
{
if (Factory::getConfig()->get('unicodeslugs') == 1) {
$data['alias'] = OutputFilter::stringURLUnicodeSlug($data['component_name']);
} else {
$data['alias'] = OutputFilter::stringURLSafe($data['component_name']);
}
}
```
##### Ordering
The ordering value is calculated by finding the maximum value in the column and then
incrementing it.
```php
/* if it is 0 -> get the max + 1 value */
if (!$data['ordering']) {
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('MAX(ordering)')
->from('#__depot');
$db->setQuery($query);
$max = $db->loadResult();
$data['ordering'] = $max + 1;
}
```
#### 2. bind()
The `bind()` splits the article text or description into intro text and full text based on read
more tag in the content. This method also converts fields data from arrays to JSON for
saving into the database.
```php
public function bind($array, $ignore = '')
{
if (isset($array['attribs']) && \is_array($array['attribs'])) {
$registry = new Registry($array['attribs']);
$array['attribs'] = (string) $registry;
}
return parent::bind($array, $ignore);
}
```
#### 3. check()
The check() checks whether title of the article is not empty. This method also sets the alias,
hits, publishing dates.
```php
public function check()
{
try {
parent::check();
}
catch (\Exception $e) {
$this->setError($e->getMessage());
return false;
}
if (trim($this->title) == '') {
$this->setError('Title (title) is not set.');
return false;
}
if (trim($this->alias) == '') {
$this->alias = $this->title;
}
$this->alias = ApplicationHelper::stringURLSave($this->alias, $this->language);
// Ensure any new items have compulsory fields set
if (!$this->id) {
// Hits must be zero on a new item
$this-hits = 0;
}
// Set publish_up to null if not set
if (!$this->publish_up) {
$this->publish_up = null;
}
// Set publish_down to null if not set
if (!$this->publish_down) {
$this->publish_down = null;
}
// Check the publish down date is not earlier than publish up.
if (!is_null($this->publish_up) &&
!is_null($this->publish_down) &&
$this->publish_down < $this->publish_up) {
// swap the dates
$temp = $this->publish_up;
$this->publish_up = $this->publish_down;
$this->publish_down = $temp;
}
return true;
}
```
#### 4. store()
The `store()` sets created and modified dates, created by and modified by users, and also
checks for unique alias.
```php
public function store($updateNulls = true)
{
$app = Factory::getApplication();
$date = Factory::getDate()->toSql();
$user = Factory::getUser();
if (!this->created) {
$this->created = $date;
}
if (!this->created_by) {
$this->created_by = $user->get('id');
}
if ($this->id) {
// Existing item
$this->modified_by = $user->get('id');
$this->modified = $date;
} else {
// Set modified to created date if not set
if (!$this->modified)) {
$this->modified = $this->created;
}
// Set modified_by to created_by user if not set
if (empty($this->modified_by)) {
$this->modified_by = $this->created_by;
}
}
// Verify that the alias is unique
$table = $app->bootComponent('com_depot')->getMVCFactory()
->createTable('Part','Administrator');
if ($table->load(['alias' => $this->alias]) &&
($table->id != $this->id || $this->id == 0)) {
$this->setError('Alias is not unique.');
if ($table->state == -2) {
$this->setError('Alias is not unique. The item is in trash.');
}
return false;
}
return parent::store($updateNulls);
}
```
---
Datei anzeigen
+93
Datei anzeigen
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<form>
<fieldset
name="details"
label="COM_DEPOT_DETAILS"
addruleprefix="KW4NZ\Component\Depot\Administrator\Rule"
addfieldprefix="KW4NZ\Component\Depot\Administrator\Field"
>
<field
name="name_short"
type="text"
label="COM_DEPOT_FIELD_MANUFACTURER_ACRONYM_LABEL"
description="COM_DEPOT_FIELD_MANUFACTURER_ACRONYM_DESC"
required="true"
autofocus="1"
/>
<field
name="name_long"
type="text"
label="COM_DEPOT_FIELD_MANUFACTURER_LONG_NAME_LABEL"
description="COM_DEPOT_FIELD_MANUFACTURER_LONG_NAME_DESC"
required="true"
/>
<field
name="alias"
type="text"
label="JFIELD_ALIAS_LABEL"
description="JFIELD_ALIAS_DESC"
hint="COM_DEPOT_FIELD_ALIAS_MANUFACTURER_PLACEHOLDER"
size="40"
/>
<field
name="state"
type="list"
label="JSTATUS"
class="form-select-color-state"
default="1"
validate="options"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
<option value="2">JARCHIVED</option>
<option value="-2">JTRASHED</option>
</field>
</fieldset>
<fieldset
name="statistics"
label="COM_DEPOT_FIELD_STATISTICS"
>
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
class="readonly"
default="0"
readonly="true"
/>
<field
name="created"
type="calendar"
label="COM_DEPOT_FIELD_CREATED_LABEL"
class="readonly"
translateformat="true"
showtime="true"
readonly="true"
filter="user_utc"
/>
<field
name="created_by"
type="user"
label="COM_DEPOT_FIELD_CREATED_BY_LABEL"
class="readonly"
readonly="true"
/>
<field
name="modified"
type="calendar"
label="COM_DEPOT_FIELD_MODIFIED_LABEL"
class="readonly"
translateformat="true"
showtime="true"
readonly="true"
filter="user_utc"
/>
<field
name="modified_by"
type="user"
label="COM_DEPOT_FIELD_MODIFIED_BY_LABEL"
class="readonly"
readonly="true"
/>
</fieldset>
</form>
+122
Datei anzeigen
@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<form>
<fieldset
name="details"
label="COM_DEPOT_DETAILS"
addruleprefix="KW4NZ\Component\Depot\Administrator\Rule"
addfieldprefix="KW4NZ\Component\Depot\Administrator\Field"
>
<field
name="component_name"
type="text"
label="COM_DEPOT_FIELD_COMPONENT_NAME_LABEL"
description="COM_DEPOT_FIELD_COMPONENT_NAME_DESC"
required="true"
autofocus="1"
/>
<field
name="quantity"
type="number"
label="COM_DEPOT_FIELD_QUANTITY_LABEL"
description="COM_DEPOT_FIELD_QUANTITY_DESC"
default="0"
/>
<field
name="quantity_exp"
type="number"
label="COM_DEPOT_FIELD_QUANTITY_EXP_LABEL"
description="COM_DEPOT_FIELD_QUANTITY_EXP_DESC"
default="0"
/>
<field
name="alias"
type="text"
label="JFIELD_ALIAS_LABEL"
description="JFIELD_ALIAS_DESC"
hint="COM_DEPOT_FIELD_ALIAS_PART_PLACEHOLDER"
size="40"
/>
<field
name="manufacturer_id"
type="sql"
label="COM_DEPOT_FIELD_SELECT_MANUFACTURER"
query="SELECT id, CONCAT( name_short, ' (', name_long, ')') AS title FROM #__depot_manufacturer ORDER BY title"
key_field="id"
value_field="title"
required="true"
>
<option value="">COM_DEPOT_SELECT_YOUR_OPTION</option>
</field>
<field
name="stock_id"
type="sql"
label="COM_DEPOT_FIELD_SELECT_STOCK"
query="SELECT id, name FROM #__depot_stock ORDER BY name"
key_field="id"
value_field="name"
required="true"
>
<option value="">COM_DEPOT_SELECT_YOUR_OPTION</option>
</field>
<field
name="state"
type="list"
label="JSTATUS"
class="form-select-color-state"
default="1"
validate="options"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
<option value="2">JARCHIVED</option>
<option value="-2">JTRASHED</option>
</field>
</fieldset>
<fieldset
name="statistics"
label="COM_DEPOT_FIELD_STATISTICS"
>
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
class="readonly"
default="0"
readonly="true"
/>
<field
name="created"
type="calendar"
label="COM_DEPOT_FIELD_CREATED_LABEL"
class="readonly"
translateformat="true"
showtime="true"
readonly="true"
filter="user_utc"
/>
<field
name="created_by"
type="user"
label="COM_DEPOT_FIELD_CREATED_BY_LABEL"
class="readonly"
readonly="true"
/>
<field
name="modified"
type="calendar"
label="COM_DEPOT_FIELD_MODIFIED_LABEL"
class="readonly"
translateformat="true"
showtime="true"
readonly="true"
filter="user_utc"
/>
<field
name="modified_by"
type="user"
label="COM_DEPOT_FIELD_MODIFIED_BY_LABEL"
class="readonly"
readonly="true"
/>
</fieldset>
</form>
+93
Datei anzeigen
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<form>
<fieldset
name="details"
label="COM_DEPOT_DETAILS"
addruleprefix="KW4NZ\Component\Depot\Administrator\Rule"
addfieldprefix="KW4NZ\Component\Depot\Administrator\Field"
>
<field
name="name"
type="text"
label="COM_DEPOT_FIELD_STOCK_NAME_LABEL"
description="COM_DEPOT_FIELD_STOCK_NAME_DESC"
required="true"
autofocus="1"
/>
<field
name="description"
type="text"
label="COM_DEPOT_FIELD_STOCK_DESCRIPTION_LABEL"
description="COM_DEPOT_FIELD_STOCK_DESCRIPTION_DESC"
required="true"
/>
<field
name="alias"
type="text"
label="JFIELD_ALIAS_LABEL"
description="JFIELD_ALIAS_DESC"
hint="COM_DEPOT_FIELD_ALIAS_STOCK_PLACEHOLDER"
size="40"
/>
<field
name="state"
type="list"
label="JSTATUS"
class="form-select-color-state"
default="1"
validate="options"
>
<option value="1">JPUBLISHED</option>
<option value="0">JUNPUBLISHED</option>
<option value="2">JARCHIVED</option>
<option value="-2">JTRASHED</option>
</field>
</fieldset>
<fieldset
name="statistics"
label="COM_DEPOT_FIELD_STATISTICS"
>
<field
name="id"
type="text"
label="JGLOBAL_FIELD_ID_LABEL"
class="readonly"
default="0"
readonly="true"
/>
<field
name="created"
type="calendar"
label="COM_DEPOT_FIELD_CREATED_LABEL"
class="readonly"
translateformat="true"
showtime="true"
readonly="true"
filter="user_utc"
/>
<field
name="created_by"
type="user"
label="COM_DEPOT_FIELD_CREATED_BY_LABEL"
class="readonly"
readonly="true"
/>
<field
name="modified"
type="calendar"
label="COM_DEPOT_FIELD_MODIFIED_LABEL"
class="readonly"
translateformat="true"
showtime="true"
readonly="true"
filter="user_utc"
/>
<field
name="modified_by"
type="user"
label="COM_DEPOT_FIELD_MODIFIED_BY_LABEL"
class="readonly"
readonly="true"
/>
</fieldset>
</form>
+58
Datei anzeigen
@@ -1 +1,59 @@
; @package Depot.Language
; @subpackage com_depot
; @author Thomas Kuschel <thomas@kuschel.at>
; @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
; @license GNU General Public License version 2 or later; see LICENSE.md
; @since 0.0.1
;
COM_DEPOT_FIELD_ALIAS_PART_PLACEHOLDER="Auto-generate from component name"
COM_DEPOT_FIELD_ALIAS_STOCK_PLACEHOLDER="Auto-generate from stock name"
COM_DEPOT_FIELD_ALIAS_MANUFACTURER_PLACEHOLDER="Auto-generate from manufacturer acronym"
COM_DEPOT_FIELD_COMPONENT_NAME_DESC="The name of the component is unique. Please do not enter special characters or umlauts."
COM_DEPOT_FIELD_COMPONENT_NAME_LABEL="Component Name"
COM_DEPOT_FIELD_CREATED_LABEL="Created"
COM_DEPOT_FIELD_CREATED_BY_LABEL="Created by"
COM_DEPOT_FIELD_MANUFACTURER_ACRONYM_DESC="Enter here the acronym of the manufacturer or short name"
COM_DEPOT_FIELD_MANUFACTURER_ACRONYM_LABEL="Manufacturer Acronym"
COM_DEPOT_FIELD_MANUFACTURER_LONG_NAME_DESC="Enter here the long name of the manufacturer"
COM_DEPOT_FIELD_MANUFACTURER_LONG_NAME_LABEL="Manufacturer (long name)"
COM_DEPOT_FIELD_MODIFIED_LABEL="Modified"
COM_DEPOT_FIELD_MODIFIED_BY_LABEL="Modified by"
COM_DEPOT_FIELD_QUANTITY_LABEL="Quantity"
COM_DEPOT_FIELD_QUANTITY_DESC="Enter here the current number of components"
COM_DEPOT_FIELD_QUANTITY_EXP_LABEL="Quantity Exponent"
COM_DEPOT_FIELD_QUANTITY_EXP_DESC="Exponent (10^x of the number, usually 0, i.e. 10⁰)"
COM_DEPOT_FIELD_SELECT_MANUFACTURER="Manufacturer"
COM_DEPOT_FIELD_SELECT_STOCK="Stock Location"
COM_DEPOT_FIELD_STOCK_NAME_DESC="Enter here the short stock location"
COM_DEPOT_FIELD_STOCK_NAME_LABEL="Stock Location"
COM_DEPOT_FIELD_STOCK_DESCRIPTION_DESC="Enter here the exact location/description"
COM_DEPOT_FIELD_STOCK_DESCRIPTION_LABEL="Description"
COM_DEPOT_LEGEND_MANUFACTURER_DETAILS="Manufacturer Details"
COM_DEPOT_LEGEND_PART_DETAILS="Component Details"
COM_DEPOT_LEGEND_STOCK_DETAILS="Stock Location Details"
COM_DEPOT_LEGEND_STATISTICS="Statistics"
COM_DEPOT_MANAGER_MANUFACTURERS="Manager Manufacturers"
COM_DEPOT_MANAGER_PARTS="Manager Components"
COM_DEPOT_MANAGER_STOCKS="Manager Stock Locations"
COM_DEPOT_N_ITEMS_DELETED_1="One component deleted"
COM_DEPOT_N_ITEMS_DELETED_MORE="%d components deleted"
COM_DEPOT_N_ITEMS_PUBLISHED_1="One component published"
COM_DEPOT_N_ITEMS_PUBLISHED_MORE="%d components published"
COM_DEPOT_N_ITEMS_UNPUBLISHED_1="One component unpublished"
COM_DEPOT_N_ITEMS_UNPUBLISHED_MORE="%d components unpublished"
COM_DEPOT_SELECT_YOUR_OPTION="Select your option"
COM_DEPOT_TAB_NEW_PART="New Component"
COM_DEPOT_TAB_NEW_MANUFACTURER="New Manufacturer"
COM_DEPOT_TAB_EDIT_PART="Component Details"
COM_DEPOT_TAB_EDIT_MANUFACTURER="Manufacturer Details"
COM_DEPOT_TAB_EDIT_STOCK="Stock Details"
COM_DEPOT_TAB_STATISTICS="Statistics"
COM_DEPOT_TABLE_HEAD_ID="ID"
COM_DEPOT_TABLE_HEAD_NAME="Component Name"
COM_DEPOT_TABLE_HEAD_MANUFACTURER="Manufacturer"
COM_DEPOT_TABLE_HEAD_MANUFACTURER_ACRONYM="Acronym"
COM_DEPOT_TABLE_HEAD_STOCK="Stock Location"
COM_DEPOT_TABLE_HEAD_QUANTITY="Quantity"
COM_DEPOT_TABLE_HEAD_QUANTITY_EXP="Exponent"
COM_DEPOT_TABLE_HEAD_DESCRIPTION="Description"
COM_DEPOT_XML_DESCRIPTION="Depot, the component warehouse"
+7
Datei anzeigen
@@ -1,3 +1,10 @@
; @package Depot.Language
; @subpackage com_depot
; @author Thomas Kuschel <thomas@kuschel.at>
; @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
; @license GNU General Public License version 2 or later; see LICENSE.md
; @since 0.0.1
;
COM_DEPOT_MENU="Depot"
COM_DEPOT_MENU_MANUFACTURERS="Manufacturers"
COM_DEPOT_MENU_STOCKS="Stock locations"
Datei anzeigen
Datei anzeigen
+38
Datei anzeigen
@@ -0,0 +1,38 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.1
*/
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
use Joomla\CMS\Extension\ComponentInterface;
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use KW4NZ\Component\Depot\Administrator\Extension\DepotComponent;
return new class implements ServiceProviderInterface
{
public function register(Container $container)
{
$container->registerServiceProvider(new ComponentDispatcherFactory('\\KW4NZ\\Component\\Depot'));
$container->registerServiceProvider(new MVCFactory('\\KW4NZ\\Component\\Depot'));
$container->set(
ComponentInterface::class,
function (Container $container)
{
$component = new DepotComponent($container->get(ComponentDispatcherFactoryInterface::class));
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
return $component;
}
);
}
};
+90 -13
Datei anzeigen
@@ -1,12 +1,20 @@
-- @package Depot.SQL MariaDB
-- @subpackage com_depot
-- @author Thomas Kuschel <thomas@kuschel.at>
-- @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
-- @license GNU General Public License version 2 or later; see LICENSE.md
-- @since 0.0.2
DROP TABLE IF EXISTS `#__depot`;
CREATE TABLE `#__depot`(
CREATE TABLE `#__depot` (
`id` SERIAL,
`component_name` VARCHAR(1024) CHARACTER SET ascii COLLATE ascii_general_ci NULL DEFAULT NULL
COMMENT 'unique component name (ASCII characters only)',
`alias` VARCHAR(1024) NOT NULL DEFAULT '',
`description` VARCHAR(4000) NOT NULL DEFAULT '',
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`quantity_exp` INT(11) NOT NULL DEFAULT 0 COMMENT 'Exponent of the quantity (10^x of the number, usually 0 i.e. 10⁰)',
`quantity_exp` INT(11) NOT NULL DEFAULT 0
COMMENT 'Exponent of the quantity (10^x of the number, usually 0 i.e. 10⁰)',
`asset_id` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.',
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
@@ -14,20 +22,20 @@ CREATE TABLE `#__depot`(
`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
-- `parent_id` INT(11) NOT NULL DEFAULT 1,
-- `level` INT(11) NOT NULL DEFAULT 0,
`path` VARCHAR(400) NOT NULL DEFAULT '',
`state` TINYINT(4) NOT NULL DEFAULT 0 COMMENT 'Published=1,Unpublished=0,Archived=2,Trashed=-2',
`state` TINYINT(4) NOT NULL DEFAULT 0
COMMENT 'Published=1,Unpublished=0,Archived=2,Trashed=-2',
`access` TINYINT(4) NOT NULL DEFAULT 0,
`category_id` INT(11) NOT NULL DEFAULT 0,
`params` VARCHAR(1024) NOT NULL DEFAULT '',
`image` VARCHAR(1024) NOT NULL DEFAULT '',
`manufacturer_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_alt` VARCHAR(1024) NOT NULL DEFAULT '',
`stock_id` INT(11) NOT NULL DEFAULT 0,
`ordering` INT(11) NOT NULL DEFAULT 0,
`version` int unsigned NOT NULL DEFAULT 1,
-- references to other tables:
`category_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_alt` VARCHAR(1024) NOT NULL DEFAULT '',
`manufacturer_id` INT(11) NOT NULL DEFAULT 0,
`stock_id` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_state` (`state`),
KEY `idx_stock_id` (`stock_id`),
@@ -38,6 +46,75 @@ CREATE TABLE `#__depot`(
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `#__depot` (`component_name`,`alias`,`description`,`quantity`,`created`,
`ordering`,`state`,`manufacturer_id`) VALUES
('1N5404','1n5404','diode, rectifier 3A',9,'2023-09-25 15:00:00',1,1,1),
('1N4148','1n4148','diode, general purpose',1234,'2023-09-25 15:15:15',2,1,2);
`ordering`,`state`,`manufacturer_id`,`stock_id`) VALUES
('1N5404','1n5404','diode, rectifier 3A',9,'2023-09-25 15:00:00',1,1,1,1),
('1N4148','1n4148','diode, general purpose',1234,'2023-09-25 15:15:15',2,1,2,1);
DROP TABLE IF EXISTS `#__depot_manufacturer`;
CREATE TABLE `#__depot_manufacturer` (
`id` SERIAL,
`name_short` CHAR(25) CHARACTER SET ascii COLLATE ascii_general_ci NULL DEFAULT NULL
COMMENT 'unique manufacturer name or abbriviation',
`alias` VARCHAR(127) NOT NULL DEFAULT '',
`name_long` VARCHAR(1024) NOT NULL DEFAULT '',
`url` VARCHAR(1024) NOT NULL DEFAULT '',
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`checked_out` INT(11) NOT NULL DEFAULT 0,
`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`description` VARCHAR(4000) NOT NULL DEFAULT '',
`state` TINYINT(4) NOT NULL DEFAULT 0,
`image` VARCHAR(1024) NOT NULL DEFAULT '',
`access` TINYINT(4) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `name_short` (`name_short`)
) ENGINE=InnoDB
AUTO_INCREMENT=0
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `#__depot_manufacturer` (`name_short`, `name_long`, `url`,
`description`, `image`, `state`) VALUES
('TSC','Taiwan Semiconductor','https://www.taiwansemi.com',
'Diodes, ECAD Models, ICs, MOSFETs, Protection Devices, AEC-Q qualified','',1),
('ST','STMicroelectronics','https://www.st.com',
'Microprocessors, Audio ICs, OPamps, Diodes, Memories, MEMS, NFCs, Transistors, Wireless, Automotive electronics, etc.','',1);
DROP TABLE IF EXISTS `#__depot_stock`;
CREATE TABLE `#__depot_stock` (
`id` SERIAL,
`name` VARCHAR(1024) NOT NULL DEFAULT '',
`alias` VARCHAR(1024) NOT NULL DEFAULT '',
`owner` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`checked_out` INT(11) NOT NULL DEFAULT 0,
`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`description` VARCHAR(4000) NOT NULL DEFAULT '',
`params` VARCHAR(1024) NOT NULL DEFAULT '',
`location` VARCHAR(1024) NOT NULL DEFAULT '',
`latitude` DECIMAL(9,7) NOT NULL DEFAULT 48.31738798930856,
`longitude` DECIMAL(10,7) NOT NULL DEFAULT 16.313504251028924,
`state` TINYINT(4) NOT NULL DEFAULT 0,
`access` TINYINT(4) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `nameindex` (`name`,`owner`)
)
ENGINE=InnoDB
AUTO_INCREMENT=0
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `#__depot_stock`(`name`, `location`, `description`, `state`, `access`) VALUES
('Semiconductors workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 5x12 (60) compartments à 54 x 35 x 140 mm',1,0),
('Resistors workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 2x5x12 + 1x5x7+3 (158) compartments à 54 x 35 x 140 mm',1,0),
('Capacitors/Inductors workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 5x12 (60) compartments à 54 x 35 x 140 mm',1,0),
('Plugs/Sockets/other workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 5x12 (60) compartments à 54 x 35 x 140 mm',1,0),
('SMD cabinet', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'SMD cabinet, conductive, 6-times cabinet with inlays, 6 x 7*6 (252) round boxes, each ø 27 x 13 mm',1,0);
+7
Datei anzeigen
@@ -1 +1,8 @@
-- @package Depot.Language
-- @subpackage com_depot
-- @author Thomas Kuschel <thomas@kuschel.at>
-- @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
-- @license GNU General Public License version 2 or later; see LICENSE.md
-- @since 0.0.2
DROP TABLE IF EXISTS `#__depot`;
+8 -1
Datei anzeigen
@@ -1 +1,8 @@
-- database update
-- @package Depot.SQL MariaDB -- UPDATE to 0.0.1
-- @subpackage com_depot
-- @author Thomas Kuschel <thomas@kuschel.at>
-- @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
-- @license GNU General Public License version 2 or later; see LICENSE.md
-- @since 0.0.2
-- dummy
+50
Datei anzeigen
@@ -0,0 +1,50 @@
-- @package Depot.SQL MariaDB -- UPDATE to 0.0.2
-- @subpackage com_depot
-- @author Thomas Kuschel <thomas@kuschel.at>
-- @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
-- @license GNU General Public License version 2 or later; see LICENSE.md
-- @since 0.0.2
CREATE TABLE IF NOT EXISTS `#__depot` (
`id` SERIAL,
`component_name` VARCHAR(1024) CHARACTER SET ascii COLLATE ascii_general_ci NULL DEFAULT NULL
COMMENT 'unique component name (ASCII characters only)',
`alias` VARCHAR(1024) NOT NULL DEFAULT '',
`description` VARCHAR(4000) NOT NULL DEFAULT '',
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`quantity_exp` INT(11) NOT NULL DEFAULT 0
COMMENT 'Exponent of the quantity (10^x of the number, usually 0 i.e. 10⁰)',
`asset_id` INT(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.',
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`checked_out` INT(11) NOT NULL DEFAULT 0,
`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`path` VARCHAR(400) NOT NULL DEFAULT '',
`state` TINYINT(4) NOT NULL DEFAULT 0
COMMENT 'Published=1,Unpublished=0,Archived=2,Trashed=-2',
`access` TINYINT(4) NOT NULL DEFAULT 0,
`params` VARCHAR(1024) NOT NULL DEFAULT '',
`image` VARCHAR(1024) NOT NULL DEFAULT '',
`ordering` INT(11) NOT NULL DEFAULT 0,
`version` int unsigned NOT NULL DEFAULT 1,
-- references to other tables:
`category_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_id` INT(11) NOT NULL DEFAULT 0,
`datasheet_alt` VARCHAR(1024) NOT NULL DEFAULT '',
`manufacturer_id` INT(11) NOT NULL DEFAULT 0,
`stock_id` INT(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_state` (`state`),
KEY `idx_stock_id` (`stock_id`),
KEY `idx_manufacturer` (`manufacturer_id`),
UNIQUE KEY `aliasindex` (`alias`,`manufacturer_id`,`stock_id`)
) ENGINE=InnoDB
AUTO_INCREMENT=0
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `#__depot` (`component_name`,`alias`,`description`,`quantity`,`created`,
`ordering`,`state`,`manufacturer_id`) VALUES
('1N5404','1n5404','diode, rectifier 3A',9,'2023-09-25 15:00:00',1,1,1),
('1N4148','1n4148','diode, general purpose',1234,'2023-09-25 15:15:15',2,1,2);
+35
Datei anzeigen
@@ -0,0 +1,35 @@
-- @package Depot.SQL MariaDB -- UPDATE to 0.0.5
-- @subpackage com_depot
-- @author Thomas Kuschel <thomas@kuschel.at>
-- @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
-- @license GNU General Public License version 2 or later; see LICENSE.md
-- @since 0.0.5
CREATE TABLE IF NOT EXISTS `#__depot_manufacturer` (
`id` SERIAL,
`name_short` CHAR(25) CHARACTER SET ascii COLLATE ascii_general_ci NULL DEFAULT NULL
COMMENT 'unique manufacturer name or abbriviation',
`name_long` VARCHAR(1024) NOT NULL DEFAULT '',
`url` VARCHAR(1024) NOT NULL DEFAULT '',
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`checked_out` INT(11) NOT NULL DEFAULT 0,
`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`description` VARCHAR(4000) NOT NULL DEFAULT '',
`state` TINYINT(4) NOT NULL DEFAULT 0,
`image` VARCHAR(1024) NOT NULL DEFAULT '',
`access` TINYINT(4) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `name_short` (`name_short`)
) ENGINE=InnoDB
AUTO_INCREMENT=0
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `#__depot_manufacturer` (`name_short`, `name_long`, `url`,
`description`, `image`, `state`) VALUES
('TSC','Taiwan Semiconductor','https://www.taiwansemi.com',
'Diodes, ECAD Models, ICs, MOSFETs, Protection Devices, AEC-Q qualified','',1),
('ST','STMicroelectronics','https://www.st.com',
'Microprocessors, Audio ICs, OPamps, Diodes, Memories, MEMS, NFCs, Transistors, Wireless, Automotive electronics, etc.','',1);
+42
Datei anzeigen
@@ -0,0 +1,42 @@
-- @package Depot.SQL MariaDB -- UPDATE to 0.9.0
-- @subpackage com_depot
-- @author Thomas Kuschel <thomas@kuschel.at>
-- @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
-- @license GNU General Public License version 2 or later; see LICENSE.md
-- @since 0.9.0
CREATE TABLE IF NOT EXISTS `#__depot_stock` (
`id` SERIAL,
`name` VARCHAR(1024) NOT NULL DEFAULT '',
`alias` VARCHAR(1024) NOT NULL DEFAULT '',
`owner` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`checked_out` INT(11) NOT NULL DEFAULT 0,
`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified_by` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`description` VARCHAR(4000) NOT NULL DEFAULT '',
`params` VARCHAR(1024) NOT NULL DEFAULT '',
`location` VARCHAR(1024) NOT NULL DEFAULT '',
`latitude` DECIMAL(9,7) NOT NULL DEFAULT 48.31738798930856,
`longitude` DECIMAL(10,7) NOT NULL DEFAULT 16.313504251028924,
`state` TINYINT(4) NOT NULL DEFAULT 0,
`access` TINYINT(4) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `nameindex` (`name`,`owner`)
) ENGINE=InnoDB
AUTO_INCREMENT=0
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `#__depot_stock` (`name`, `location`, `description`, `state`, `access`) VALUES
('Semiconductors workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 5x12 (60) compartments à 54 x 35 x 140 mm',1,0),
('Resistors workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 2x5x12 + 1x5x7+3 (158) compartments à 54 x 35 x 140 mm',1,0),
('Capacitors/Inductors workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 5x12 (60) compartments à 54 x 35 x 140 mm',1,0),
('Plugs/Sockets/other workshop cabinet depot', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'MARS Svratka Workshop Depot 5x12 (60) compartments à 54 x 35 x 140 mm',1,0),
('SMD cabinet', 'Tom''s office, Martinstr. 58a, 3400 Klosterneuburg',
'SMD cabinet, conductive, 6-times cabinet with inlays, 6 x 7*6 (252) round boxes, each ø 27 x 13 mm',1,0);
@@ -1,140 +0,0 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_banners
*
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace KW4NZ\Component\Depot\Administrator\Controller;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Response\JsonResponse;
use Joomla\Input\Input;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Depot item list controller class.
*
* @since 1.6
*/
class DepotItemsController extends AdminController
{
/**
* The prefix to use with controller messages.
*
* @var string
* @since 1.6
*/
protected $text_prefix = 'COM_BANNERS_BANNERS'; //?????
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
* @param ?MVCFactoryInterface $factory The factory.
* @param ?CMSApplication $app The Application for the dispatcher
* @param ?Input $input Input
*
* @since 3.0
*/
public function __construct($config = [], MVCFactoryInterface $factory = null, $app = null, $input = null)
{
parent::__construct($config, $factory, $app, $input);
$this->registerTask('sticky_unpublish', 'sticky_publish');
}
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model.
*
* @since 1.6
*/
public function getModel($name = 'Depot', $prefix = 'Administrator', $config = ['ignore_request' => true])
{
return parent::getModel($name, $prefix, $config);
}
/**
* Stick items
*
* @return void
*
* @since 1.6
*/
public function sticky_publish()
{
// Check for request forgeries.
$this->checkToken();
$ids = (array) $this->input->get('cid', [], 'int');
$values = ['sticky_publish' => 1, 'sticky_unpublish' => 0];
$task = $this->getTask();
$value = ArrayHelper::getValue($values, $task, 0, 'int');
// Remove zero values resulting from input filter
$ids = array_filter($ids);
if (empty($ids)) {
$this->app->enqueueMessage(Text::_('COM_BANNERS_NO_BANNERS_SELECTED'), 'warning');
} else {
// Get the model.
/** @var \Joomla\Component\Banners\Administrator\Model\BannerModel $model */
$model = $this->getModel();
// Change the state of the records.
if (!$model->stick($ids, $value)) {
$this->app->enqueueMessage($model->getError(), 'warning');
} else {
if ($value == 1) {
$ntext = 'COM_BANNERS_N_BANNERS_STUCK';
} else {
$ntext = 'COM_BANNERS_N_BANNERS_UNSTUCK';
}
$this->setMessage(Text::plural($ntext, \count($ids)));
}
}
$this->setRedirect('index.php?option=com_banners&view=banners');
}
/**
* Method to get the number of published banners for quickicons
*
* @return void
*
* @since 4.3.0
*/
public function getQuickiconContent()
{
$model = $this->getModel('banners');
$model->setState('filter.published', 1);
$amount = (int) $model->getTotal();
$result = [];
$result['amount'] = $amount;
$result['sronly'] = Text::plural('COM_BANNERS_N_QUICKICON_SRONLY', $amount);
$result['name'] = Text::plural('COM_BANNERS_N_QUICKICON', $amount);
echo new JsonResponse($result);
}
}
@@ -1,48 +0,0 @@
<?php
namespace KW4NZ\Component\Depot\Administrator\Controller;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Response\JsonResponse;
use Joomla\Input\Input;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Depots list controller class.
*
* @since 1.6
*/
class DepotsController extends AdminController
{
/**
* The prefix to use with controller messages
*
* @var string
* @since 1.6
*/
protected $text_prefix = 'COM_DEPOT_DEPOTS';
/**
* Method to get a model object, loading it if required
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model.
*
* @since 1.6
*/
public function getModel($name = 'Depot', $prefix = 'Administrator', $config = ['ignore_request' => true])
{
return parent::getModel($name, $prefix, $config);
}
}
+12 -63
Datei anzeigen
@@ -1,71 +1,20 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.1
*/
namespace KW4NZ\Component\Depot\Administrator\Controller;
use Joomla\CMS\Language\Text;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
// use Joomla\Component\Depot\Administrator\Helper\BannersHelper;
\defined('_JEXEC') or die;
/**
* Depot display controller.
*
* @since 1.6
*/
class DisplayController extends BaseController
{
/**
* The default view.
*
* @var string
* @since 1.6
*/
protected $default_view = 'depots';
/**
* Method to display a view.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe URL parameters and their variable types
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values
*
* @return BaseController|boolean This object to support chaining
*
* @since 1.5
*/
public function display($cachable = false, $urlparams = [])
{
// BannersHelper::updateReset();
$view = $this->input->get('view', $this->default_view);
$layout = $this->input->get('layout', 'default');
$id = $this->input->getInt('id');
// Check for edit form.
if ($view === 'depot' && $layout === 'edit' && !$this->checkEditId('com_depot.edit.depot', $id)) {
// Somehow the person just went to the form - we don't allow that.
if (!\count($this->app->getMessageQueue())) {
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
}
$this->setRedirect(Route::_('index.php?option=com_depot&view=depots', false));
return false;
}
/*
if ($view === 'client' && $layout === 'edit' && !$this->checkEditId('com_banners.edit.client', $id)) {
// Somehow the person just went to the form - we don't allow that.
if (!\count($this->app->getMessageQueue())) {
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
}
$this->setRedirect(Route::_('index.php?option=com_banners&view=clients', false));
return false;
}
*/
return parent::display();
}
protected $default_view = 'parts';
}
@@ -0,0 +1,19 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.1
*/
namespace KW4NZ\Component\Depot\Administrator\Controller;
use Joomla\CMS\MVC\Controller\FormController;
defined('_JEXEC') or die;
class ManufacturerController extends FormController
{
}
+19
Datei anzeigen
@@ -0,0 +1,19 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.4
*/
namespace KW4NZ\Component\Depot\Administrator\Controller;
use Joomla\CMS\MVC\Controller\FormController;
defined('_JEXEC') or die;
class PartController extends FormController
{
}
@@ -0,0 +1,23 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.6
*/
namespace KW4NZ\Component\Depot\Administrator\Controller;
use Joomla\CMS\MVC\Controller\AdminController;
defined('_JEXEC') or die;
class PartsController extends AdminController
{
public function getModel($name = 'Part', $prefix = 'Administrator', $config = ['ignore_request' => true])
{
return parent::getModel($name, $prefix, $config);
}
}
@@ -0,0 +1,19 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.2
*/
namespace KW4NZ\Component\Depot\Administrator\Controller;
use Joomla\CMS\MVC\Controller\FormController;
defined('_JEXEC') or die;
class StockController extends FormController
{
}
+9 -61
Datei anzeigen
@@ -1,69 +1,17 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.1
*/
namespace KW4NZ\Component\Depot\Administrator\Extension;
use Joomla\CMS\Categories\CategoryServiceInterface;
use Joomla\CMS\Categories\CategoryServiceTrait;
use Joomla\CMS\Component\Router\RouterServiceInterface;
use Joomla\CMS\Component\Router\RouterServiceTrait;
use Joomla\CMS\Extension\BootableExtensionInterface;
use Joomla\CMS\Extension\MVCComponent;
use Joomla\CMS\HTML\HTMLRegistryAwareTrait;
use Joomla\CMS\Tag\TagServiceInterface;
use Joomla\CMS\Tag\TagServiceTrait;
use Joomla\Database\DatabaseInterface;
use KW4NZ\Component\Depot\Administrator\Service\HTML\Depot;
use Psr\Container\ContainerInterface;
\defined('_JEXEC') or die;
class DepotComponent extends MVCComponent implements
BootableExtensionInterface,
CategoryServiceInterface,
RouterServiceInterface,
TagServiceInterface
class DepotComponent extends MVCComponent
{
use HTMLRegistryAwareTrait;
use RouterServiceTrait;
use CategoryServiceTrait, TagServiceTrait {
CategoryServiceTrait::getTableNameForSection insteadof TagServiceTrait;
CategoryServiceTrait::getStateColumnForSection insteadof TagServiceTrait;
}
/**
* Booting the extension. This is the function to set up the environment of the extension like
* registering new class loaders, etc.
*
* If required, some initial set up can be done from services of the container, eg.
* registering HTML services.
*
* @param ContainerInterface $container The container
*
* @return void
*
* @since 4.4.0
*/
public function boot(ContainerInterface $container)
{
$depot = new Depot();
$depot->setDatabase($container->get(DatebaseInterface::class));
$this->getRegistry()->register('depot', $depot);
}
/**
* Returns the table name for the count items function for the given section.
*
* @param ?string $section The section
*
* @return string|null
*
* @since 4.0.0
*/
protected function getTableNameForSection(string $section = null)
{
return 'depot';
}
}
-211
Datei anzeigen
@@ -1,211 +0,0 @@
<?php
namespace KW4NZ\Component\Depot\Administrator\Model;
//use Joomla\CMS\MVC\Model\ListModel;
//use Joomla\CMS\Factory;
//use Joomla\Database\DatabaseInterface;
//use Joomla\CMS\Language\Associations;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Response\JsonResponse;
use Joomla\Input\Input;
use Joomla\Utilities\ArrayHelper;
\defined('_JEXEC') or die;
/**
* Depot list controller class.
*
* @since 1.6
*/
class DepotItemsModel extends ListModel {
/**
* The prefix to use with controller messages.
*
* @var string
* @since 1.6
*/
protected $text_prefix = 'COM_BANNERS_BANNERS';
public function __construct($config = array())
{
if (empty($config['filter_fields'])) {
$config['filter_fields'] = [
'id',
'name',
'quantity',
'state',
'author',
'created',
'modifier',
'language',
'lft',
'category_id',
'access',
'association',
'published',
];
}
parent::__construct($config);
}
protected function populateState($ordering = null, $direction = null) {
$app = Factory::getApplication();
// Adjust the context to support modal layouts.
if ($layout = $app->input->get('layout')) {
$this->context .= '.' . $layout;
}
// Adjust the context to support forced languages.
$forcedLanguage = $app->input->get('forcedLanguage', '', 'CMD');
if ($forcedLanguage) {
$this->context .= '.' . $forcedLanguage;
}
parent::populateState($ordering, $direction);
// If there's a forced language then define that filter for the query where clause
if (!empty($forcedLanguage)) {
$this->setState('filter.language', $forcedLanguage);
}
}
/**
* Build an SQL query to load the list data.
*
* @return \Joomla\Database\DatabaseQuery
*
* @since 1.6
*/
protected function getListQuery()
{
// Initialize variables.
$db = $this->getDatabase();
$query = $db->getQuery(true);
$user = Factory::getApplication()->getIdentity();
// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
[
$db->quoteName('a.id'),
$db->quoteName('a.name'),
$db->quoteName('a.alias'),
$db->quoteName('a.quantity'),
$db->quoteName('a.quantity_exp'),
$db->quoteName('a.checked_out'),
$db->quoteName('a.checked_out_time'),
$db->quoteName('')
// @TODO, see J5 com_banners
]
)
*/
$query->select('a.id as id, a.name as name, a.quantity as quantity,
a.quantity_exp as quantity_exp, a.manufacturer_id as manufacturer_id,
a.datasheet_id as datasheet_id, a.datasheet_alt as datasheet_alt,
a.stock_id as stock_id,
a.greeting as greeting,
a.state as state, a.created as created, a.access as access,
a.modified as modified,
a.checked_out as checked_out, a.checked_out_time as checked_out_time, a.catid as catid,
a.lft as lft, a.rgt as rgt, a.parent_id as parent_id, a.level as level, a.path as path,
a.image as imageInfo, a.latitude as latitude, a.longitude as longitude, a.alias as alias, a.language as language')
->from($db->quoteName('#__jron', 'a'));
// Join over the categories.
$query->select($db->quoteName('c.title', 'category_title'))
->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON c.id = a.catid');
// Join with users table to get the username of the author
$query->select($db->quoteName('u.username', 'author'))
->join('LEFT', $db->quoteName('#__users', 'u') . ' ON u.id = a.created_by');
// Join with users table to get the username of the person who checked the record out
$query->select($db->quoteName('u2.username', 'editor'))
->join('LEFT', $db->quoteName('#__users', 'u2') . ' ON u2.id = a.checked_out');
// Join with users table to get the username of the last modifier of the stock
$query->select($db->quoteName('u4.username', 'modifier'))
->join('LEFT', $db->quoteName('#__users', 'u4') . ' ON u4.id = a.modified_by');
// Join with languages table to get the language title and image to display
// Put these into fields called language_title and language_image so that
// we can use the little com_content layout to display the map symbol
$query->select($db->quoteName('l.title', 'language_title') . "," .$db->quoteName('l.image', 'language_image'))
->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON l.lang_code = a.language');
// Join over the associations - we just want to know if there are any, at this stage
if (Associations::isEnabled())
{
$query->select('COUNT(asso2.id)>1 as association')
->join('LEFT', '#__associations AS asso ON asso.id = a.id AND asso.context=' . $db->quote('com_jron.item'))
->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key')
->group('a.id');
}
// Join over the access levels, to get the name of the access level
$query->select('v.title AS access_level')
->join('LEFT', '#__viewlevels AS v ON v.id = a.access');
// Filter: like / search
$search = $this->getState('filter.search');
if (!empty($search)) {
$like = $db->quote('%' . $search . '%');
$query->where('a.name LIKE ' . $like);
}
// Filter by (published) state
$state = $this->getState('filter.state');
if (is_numeric($state)) {
$query->where('a.state = ' . (int) $state);
}
elseif ($state === '') {
$query->where('(a.state IN (0, 1))');
}
// Filter by language, if the user has set that in the filter field
$language = $this->getState('filter.language');
if ($language) {
$query->where('a.language = ' . $db->quote($language));
}
// Filter by categories
$catid = $this->getState('filter.category_id');
if ($catid) {
$query->where("a.catid = " . $db->quote($db->escape($catid)));
}
// Display only records to which the user has access
if (!$user->authorise('core.admin')) { // ie if not SuperUser
$userAccessLevels = implode(',', $user->getAuthorisedViewLevels());
$query->where('a.access IN (' . $userAccessLevels . ')');
$query->where('c.access IN (' . $userAccessLevels . ')');
}
// exclude root part record
$query->where('a.id > 1');
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'lft');
$orderDirn = $this->state->get('list.direction', 'asc');
$query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn));
return $query;
}
}
-473
Datei anzeigen
@@ -1,473 +0,0 @@
<?php
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Model\AdminModel;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Table\TableInterface;
use Joomla\CMS\Versioning\VersionableModelTrait;
use Joomla\Component\Categories\Administrator\Helper\CategoriesHelper;
use Joomla\Database\ParameterType;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Banner model.
*
* @since 1.6
*/
class DepotModel extends AdminModel
{
use VersionableModelTrait;
/**
* The prefix to use with controller messages.
*
* @var string
* @since 1.6
*/
protected $text_prefix = 'COM_DEPOT_DEPOT';
/**
* The type alias for this content type.
*
* @var string
* @since 3.2
*/
public $typeAlias = 'com_depot.depot';
/**
* Batch copy/move command. If set to false, the batch copy/move command is not supported
*
* @var string
*/
protected $batch_copymove = 'category_id';
/**
* Allowed batch commands
*
* @var array
*/
protected $batch_commands = [
'client_id' => 'batchClient',
'language_id' => 'batchLanguage',
];
/**
* Data cleanup after batch copying data
*
* @param TableInterface $table The table object containing the newly created item
* @param integer $newId The id of the new item
* @param integer $oldId The original item id
*
* @return void
*
* @since 4.3.2
*/
protected function cleanupPostBatchCopy(TableInterface $table, $newId, $oldId)
{
// Initialise clicks and impmade
$db = $this->getDatabase();
$query = $db->getQuery(true)
->update($db->quoteName('#__depot'))
->set($db->quoteName('clicks') . ' = 0')
->set($db->quoteName('impmade') . ' = 0')
->where($db->quoteName('id') . ' = :newId')
->bind(':newId', $newId, ParameterType::INTEGER);
$db->setQuery($query);
$db->execute();
}
/**
* Batch client changes for a group of banners.
*
* @param string $value The new value matching a client.
* @param array $pks An array of row IDs.
* @param array $contexts An array of item contexts.
*
* @return boolean True if successful, false otherwise and internal error is set.
*
* @since 2.5
*/
protected function batchClient($value, $pks, $contexts)
{
// Set the variables
$user = $this->getCurrentUser();
/** @var \Joomla\Component\Banners\Administrator\Table\BannerTable $table */
$table = $this->getTable();
foreach ($pks as $pk) {
if (!$user->authorise('core.edit', $contexts[$pk])) {
$this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT'));
return false;
}
$table->reset();
$table->load($pk);
$table->cid = (int) $value;
if (!$table->store()) {
$this->setError($table->getError());
return false;
}
}
// Clean the cache
$this->cleanCache();
return true;
}
/**
* Method to test whether a record can be deleted.
*
* @param object $record A record object.
*
* @return boolean True if allowed to delete the record. Defaults to the permission set in the component.
*
* @since 1.6
*/
protected function canDelete($record)
{
if (empty($record->id) || $record->state != -2) {
return false;
}
if (!empty($record->catid)) {
return $this->getCurrentUser()->authorise('core.delete', 'com_banners.category.' . (int) $record->catid);
}
return parent::canDelete($record);
}
/**
* A method to preprocess generating a new title in order to allow tables with alternative names
* for alias and title to use the batch move and copy methods
*
* @param integer $categoryId The target category id
* @param Table $table The \Joomla\CMS\Table\Table within which move or copy is taking place
*
* @return void
*
* @since 3.8.12
*/
public function generateTitle($categoryId, $table)
{
// Alter the title & alias
$data = $this->generateNewTitle($categoryId, $table->alias, $table->name);
$table->name = $data['0'];
$table->alias = $data['1'];
}
/**
* Method to test whether a record can have its state changed.
*
* @param object $record A record object.
*
* @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component.
*
* @since 1.6
*/
protected function canEditState($record)
{
// Check against the category.
if (!empty($record->catid)) {
return $this->getCurrentUser()->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid);
}
// Default to component settings if category not known.
return parent::canEditState($record);
}
/**
* Method to get the record form.
*
* @param array $data Data for the form. [optional]
* @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional]
*
* @return Form|boolean A Form object on success, false on failure
*
* @since 1.6
*/
public function getForm($data = [], $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_depot.depot', 'depot', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
// Modify the form based on access controls.
if (!$this->canEditState((object) $data)) {
// Disable fields for display.
$form->setFieldAttribute('ordering', 'disabled', 'true');
//$form->setFieldAttribute('publish_up', 'disabled', 'true');
//$form->setFieldAttribute('publish_down', 'disabled', 'true');
$form->setFieldAttribute('state', 'disabled', 'true');
//$form->setFieldAttribute('sticky', 'disabled', 'true');
// Disable fields while saving.
// The controller has already verified this is a record you can edit.
$form->setFieldAttribute('ordering', 'filter', 'unset');
//$form->setFieldAttribute('publish_up', 'filter', 'unset');
//$form->setFieldAttribute('publish_down', 'filter', 'unset');
$form->setFieldAttribute('state', 'filter', 'unset');
//$form->setFieldAttribute('sticky', 'filter', 'unset');
}
// Don't allow to change the created_by user if not allowed to access com_users.
if (!$this->getCurrentUser()->authorise('core.manage', 'com_users')) {
$form->setFieldAttribute('created_by', 'filter', 'unset');
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
*
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$app = Factory::getApplication();
$data = $app->getUserState('com_depot.edit.depot.data', []);
if (empty($data)) {
$data = $this->getItem();
// Prime some default values.
if ($this->getState('depot.id') == 0) {
$filters = (array) $app->getUserState('com_depot.depots.filter');
$filterCatId = $filters['category_id'] ?? null;
$data->set('catid', $app->getInput()->getInt('catid', $filterCatId));
}
}
$this->preprocessData('com_depot.depot', $data);
return $data;
}
/**
* Method to stick records.
*
* @param array $pks The ids of the items to publish.
* @param integer $value The value of the published state
*
* @return boolean True on success.
*
* @since 1.6
*/
public function stick(&$pks, $value = 1)
{
/** @var \Joomla\Component\Banners\Administrator\Table\BannerTable $table */
$table = $this->getTable();
$pks = (array) $pks;
// Access checks.
foreach ($pks as $i => $pk) {
if ($table->load($pk)) {
if (!$this->canEditState($table)) {
// Prune items that you can't change.
unset($pks[$i]);
Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error');
}
}
}
// Attempt to change the state of the records.
if (!$table->stick($pks, $value, $this->getCurrentUser()->id)) {
$this->setError($table->getError());
return false;
}
return true;
}
/**
* A protected method to get a set of ordering conditions.
*
* @param Table $table A record object.
*
* @return array An array of conditions to add to ordering queries.
*
* @since 1.6
*/
protected function getReorderConditions($table)
{
$db = $this->getDatabase();
return [
$db->quoteName('catid') . ' = ' . (int) $table->catid,
$db->quoteName('state') . ' >= 0',
];
}
/**
* Prepare and sanitise the table prior to saving.
*
* @param Table $table A Table object.
*
* @return void
*
* @since 1.6
*/
protected function prepareTable($table)
{
$date = Factory::getDate();
$user = $this->getCurrentUser();
if (empty($table->id)) {
// Set the values
$table->created = $date->toSql();
$table->created_by = $user->id;
// Set ordering to the last item if not set
if (empty($table->ordering)) {
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('MAX(' . $db->quoteName('ordering') . ')')
->from($db->quoteName('#__banners'));
$db->setQuery($query);
$max = $db->loadResult();
$table->ordering = $max + 1;
}
} else {
// Set the values
$table->modified = $date->toSql();
$table->modified_by = $user->id;
}
// Increment the content version number.
$table->version++;
}
/**
* Allows preprocessing of the Form object.
*
* @param Form $form The form object
* @param array $data The data to be merged into the form object
* @param string $group The plugin group to be executed
*
* @return void
*
* @since 3.6.1
*/
protected function preprocessForm(Form $form, $data, $group = 'content')
{
if ($this->canCreateCategory()) {
$form->setFieldAttribute('catid', 'allowAdd', 'true');
// Add a prefix for categories created on the fly.
$form->setFieldAttribute('catid', 'customPrefix', '#new#');
}
parent::preprocessForm($form, $data, $group);
}
/**
* Method to save the form data.
*
* @param array $data The form data.
*
* @return boolean True on success.
*
* @since 1.6
*/
public function save($data)
{
$input = Factory::getApplication()->getInput();
// Create new category, if needed.
$createCategory = true;
// If category ID is provided, check if it's valid.
if (is_numeric($data['catid']) && $data['catid']) {
$createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_banners');
}
// Save New Category
if ($createCategory && $this->canCreateCategory()) {
$category = [
// Remove #new# prefix, if exists.
'title' => strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid'],
'parent_id' => 1,
'extension' => 'com_banners',
'language' => $data['language'],
'published' => 1,
];
/** @var \Joomla\Component\Categories\Administrator\Model\CategoryModel $categoryModel */
$categoryModel = Factory::getApplication()->bootComponent('com_categories')
->getMVCFactory()->createModel('Category', 'Administrator', ['ignore_request' => true]);
// Create new category.
if (!$categoryModel->save($category)) {
$this->setError($categoryModel->getError());
return false;
}
// Get the new category ID.
$data['catid'] = $categoryModel->getState('category.id');
}
// Alter the name for save as copy
if ($input->get('task') == 'save2copy') {
/** @var \Joomla\Component\Banners\Administrator\Table\BannerTable $origTable */
$origTable = clone $this->getTable();
$origTable->load($input->getInt('id'));
if ($data['name'] == $origTable->name) {
list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']);
$data['name'] = $name;
$data['alias'] = $alias;
} else {
if ($data['alias'] == $origTable->alias) {
$data['alias'] = '';
}
}
$data['state'] = 0;
}
if ($input->get('task') == 'save2copy' || $input->get('task') == 'copy') {
$data['clicks'] = 0;
$data['impmade'] = 0;
}
return parent::save($data);
}
/**
* Is the user allowed to create an on the fly category?
*
* @return boolean
*
* @since 3.6.1
*/
private function canCreateCategory()
{
return $this->getCurrentUser()->authorise('core.create', 'com_depot');
}
}
-189
Datei anzeigen
@@ -1,189 +0,0 @@
<?php
namespace KW4NZ\Component\Jron\Administrator\Model;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\CMS\Table\Table;
use Joomla\Database\ParameterType;
//use Joomla\CMS\Factory;
//use Joomla\Database\DatabaseInterface;
//use Joomla\CMS\Language\Associations;
\defined('_JEXEC') or die;
class JronitemsModel extends ListModel {
public function __construct($config = array())
{
if (empty($config['filter_fields'])) {
$config['filter_fields'] = [
'id', 'a.id',
'component_name',
'alias',
'description',
'quantity',
'quantity_exp',
'asset_id',
'state',
'ordering',
'author',
'created',
'created_by',
'checked_out',
'checked_out_time',
'modifier',
'language',
'lft',
'access',
'association',
'category_id',
'published',
'level', 'c.level',
];
}
parent::__construct($config);
}
protected function populateState($ordering = null, $direction = null) {
$app = Factory::getApplication();
// Adjust the context to support modal layouts.
if ($layout = $app->input->get('layout')) {
$this->context .= '.' . $layout;
}
// Adjust the context to support forced languages.
$forcedLanguage = $app->input->get('forcedLanguage', '', 'CMD');
if ($forcedLanguage) {
$this->context .= '.' . $forcedLanguage;
}
parent::populateState($ordering, $direction);
// If there's a forced language then define that filter for the query where clause
if (!empty($forcedLanguage)) {
$this->setState('filter.language', $forcedLanguage);
}
}
/**
* Build an SQL query to load the list data.
*
* @return \Joomla\Database\DatabaseQuery
*
* @since 1.6
*/
protected function getListQuery() {
// Initialize variables.
$db = $this->getDatabase();
$query = $db->getQuery(true);
$user = Factory::getApplication()->getIdentity();
// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
[
$db->quoteName('a.id'),
$db->quoteName('a.component_name'),
$db->quoteName('a.alias'),
$db->quoteName('a.description'),
$db->quoteName('a.quantity'),
$db->quoteName('a.quantity_exp'),
$db->quoteName('a.asset_id'),
$db->quoteName('a.checked_out'),
$db->quoteName('a.checked_out_time'),
$db->quoteName('a.category_id'),
$db->quoteName('a.state'),
$db->quoteName('a.ordering'),
]
)
)
/*
$query->select('a.id as id, a.name as name, a.quantity as quantity,
a.quantity_exp as quantity_exp, a.manufacturer_id as manufacturer_id,
a.datasheet_id as datasheet_id, a.datasheet_alt as datasheet_alt,
a.stock_id as stock_id,
a.greeting as greeting,
a.state as state, a.created as created, a.access as access,
a.modified as modified,
a.checked_out as checked_out, a.checked_out_time as checked_out_time, a.catid as catid,
a.lft as lft, a.rgt as rgt, a.parent_id as parent_id, a.level as level, a.path as path,
a.image as imageInfo, a.latitude as latitude, a.longitude as longitude, a.alias as alias, a.language as language')
->from($db->quoteName('#__jron', 'a'));
*/
->select(
[
$db->quoteName('u.name', 'editor'),
$db->quoteName('c.title', 'category_title'),
// @TODO add manufacturers and stocks too
]
)
->from($db->quoteName('#__depot', 'a'))
->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('a.checked_out'))
->join('LEFT', $db->quoteName('#__categories', 'c'), $db->quoteName('c.id') . ' = ' . $db->quoteName('a.category_id'))
// @TODO join also with manufacturers and stocks
;
//
$published = (string) $this->getState('filter.published');
if (is_numeric($published)) {
$published = (int) $published;
$query->where($db->quoteName('a.state') . ' = :published')
->bind(':published', $published, ParameterType::INTEGER);
} elseif ($published === '') {
$query->where($db->quoteName('a.state') . ' IN (0, 1)');
}
// Filter by category
$category_id = $this->getState('filter.category_id');
if (is_numeric($category_id)) {
$category_id = (int) $category_id;
$query->where($db->quoteName('a.category_id') . ' = :category_id')
->bind(':category_id', $category_id, ParameterType::INTEGER);
}
// @TODO Filter by manufacturer and stock
// Filter by search in title
if ($search = $this->getState('filter.search')) {
if (stripos($search, 'id:') === 0) {
$search = (int) substr($search, 3);
$query->where($db->quoteName('a.id') . ' = :search')
->bind(':search', $search, ParameterType::INTEGER);
} else {
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
$query->where('(' . $db->quoteName('a.component_name') . ' LIKE :search1 OR ' . $db->quoteName('a.alias') . ' LIKE :search2)')
->bind([':search1', ':search2'], $search);
}
}
// Filter on the level.
if ($level = (int) $this->getState('filter.level')) {
$query->where($db->quoteName('c.level') . ' <= :level')
->bind(':level', $level, ParameterType::INTEGER);
}
// Add the list ordering clause.
$orderCol = $this->state->get('list.ordering', 'a.component_name');
$orderDirn = $this->state->get('list.direction', 'ASC');
if ($orderCol === 'a.ordering' || $orderCol === 'category_title') {
$ordering = [
$db->quoteName('c.title') . ' ' . $db->escape($orderDirn),
$db->quoteName('a.ordering') . ' ' . $db->escape($orderDirn),
];
} else {
if ($orderCol === 'client_name') {
$orderCol = 'cl.name';
}
$ordering = $db->escape($orderCol) . ' ' . $db->escape($orderDirn);
}
$query->order($ordering);
return $query;
}
}
+64
Datei anzeigen
@@ -0,0 +1,64 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.1
*/
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\AdminModel;
\defined('_JEXEC') or die;
class ManufacturerModel extends AdminModel
{
public function getForm($data = [], $loadData = true)
{
$form = $this->loadForm('com_depot.manufacturer', 'manufacturer', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
return $form;
}
protected function loadFormData()
{
$app = Factory::getApplication();
$data = $app->getUserState('com_depot.edit.manufacturer.data', []);
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
public function save($data)
{
/* Add code to modify data before saving */
// if (Factory::getConfig()->get('unicodeslugs') == 1) {
// $data['alias'] = OutputFilter::stringURLUnicodeSlug($data['component_name']);
// } else {
// $data['alias'] = OutputFilter::stringURLSafe($data['component_name']);
// }
/* replaced by: */
if (empty($data['alias'])) {
$data['alias'] = ApplicationHelper::stringURLSafe($data['name_short']);
}
$result = parent::save($data);
// if ($result) {
// $this->getTable('', 'Administrator')->rebuild(1);
// }
return $result;
}
}
+75
Datei anzeigen
@@ -0,0 +1,75 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.3
*/
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\CMS\Table\Table;
\defined('_JEXEC') or die;
class ManufacturersModel extends ListModel
{
/**
* Build an SQL query to load the list data.
*
* @return \Joomla\Database\DatabaseQuery
*
* @since 1.6
*/
protected function getListQuery()
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
// $query->select('*')
// ->from($db->quoteName('#__depot', 'd'));
// order by
// $query->order('d.id ASC');
// if (true) {
// return $query;
// }
// select the required fields from the table
$query->select(
$this->getState(
'list.select',
[
$db->quoteName('m.id'),
$db->quoteName('m.name_short'),
$db->quoteName('m.name_long'),
$db->quoteName('m.alias'),
$db->quoteName('m.description'),
]
)
)
->select(
[
$db->quoteName('u.name', 'creator'),
]
)
->from($db->quoteName('#__depot_manufacturer', 'm'))
->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('m.checked_out'));
// Filter by published state
$published = (string) $this->getState('filter.published');
if (is_numeric($published)) {
$published = (int) $published;
$query->where($db->quoteName('m.state') . ' = :published')
->bind(':published', $published, ParameterType::INTEGER);
} elseif ($published === '') {
$query->where($db->quoteName('m.state') . ' IN (0, 1)');
}
return $query;
}
}
+64
Datei anzeigen
@@ -0,0 +1,64 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.3
*/
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\AdminModel;
\defined('_JEXEC') or die;
class PartModel extends AdminModel
{
public function getForm($data = [], $loadData = true)
{
$form = $this->loadForm('com_depot.part', 'part', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
return $form;
}
protected function loadFormData()
{
$app = Factory::getApplication();
$data = $app->getUserState('com_depot.edit.part.data', []);
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
public function save($data)
{
/* Add code to modify data before saving */
// if (Factory::getConfig()->get('unicodeslugs') == 1) {
// $data['alias'] = OutputFilter::stringURLUnicodeSlug($data['component_name']);
// } else {
// $data['alias'] = OutputFilter::stringURLSafe($data['component_name']);
// }
/* replaced by: */
if (empty($data['alias'])) {
$data['alias'] = ApplicationHelper::stringURLSafe($data['component_name']);
}
$result = parent::save($data);
// if ($result) {
// $this->getTable('', 'Administrator')->rebuild(1);
// }
return $result;
}
}
+82
Datei anzeigen
@@ -0,0 +1,82 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.1
*/
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\CMS\Table\Table;
\defined('_JEXEC') or die;
class PartsModel extends ListModel
{
/**
* Build an SQL query to load the list data.
*
* @return \Joomla\Database\DatabaseQuery
*
* @since 1.6
*/
protected function getListQuery()
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
// $query->select('*')
// ->from($db->quoteName('#__depot', 'd'));
// order by
// $query->order('d.id ASC');
// if (true) {
// return $query;
// }
// select the required fields from the table
$query->select(
$this->getState(
'list.select',
[
$db->quoteName('d.id'),
$db->quoteName('d.component_name'),
$db->quoteName('d.alias'),
$db->quoteName('d.description'),
$db->quoteName('d.quantity'),
$db->quoteName('d.quantity_exp'),
$db->quoteName('d.ordering'),
]
)
)
->select(
[
$db->quoteName('u.name', 'creator'),
$db->quoteName('m.name_short', 'manufacturer'),
$db->quoteName('m.name_long', 'manufacturer_long'),
$db->quoteName('s.name', 'stock_name'),
]
)
->from($db->quoteName('#__depot', 'd'))
->join('LEFT', $db->quoteName('#__depot_manufacturer', 'm'), $db->quoteName('m.id') . ' = ' . $db->quoteName('d.manufacturer_id'))
->join('LEFT', $db->quoteName('#__depot_stock', 's'), $db->quoteName('s.id') . ' = ' . $db->quoteName('d.stock_id'))
->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('d.checked_out'));
// Filter by published state
$published = (string) $this->getState('filter.published');
if (is_numeric($published)) {
$published = (int) $published;
$query->where($db->quoteName('d.state') . ' = :published')
->bind(':published', $published, ParameterType::INTEGER);
} elseif ($published === '') {
$query->where($db->quoteName('d.state') . ' IN (0, 1)');
}
return $query;
}
}
+64
Datei anzeigen
@@ -0,0 +1,64 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.2
*/
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\AdminModel;
\defined('_JEXEC') or die;
class StockModel extends AdminModel
{
public function getForm($data = [], $loadData = true)
{
$form = $this->loadForm('com_depot.stock', 'stock', ['control' => 'jform', 'load_data' => $loadData]);
if (empty($form)) {
return false;
}
return $form;
}
protected function loadFormData()
{
$app = Factory::getApplication();
$data = $app->getUserState('com_depot.edit.stock.data', []);
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
public function save($data)
{
/* Add code to modify data before saving */
// if (Factory::getConfig()->get('unicodeslugs') == 1) {
// $data['alias'] = OutputFilter::stringURLUnicodeSlug($data['component_name']);
// } else {
// $data['alias'] = OutputFilter::stringURLSafe($data['component_name']);
// }
/* replaced by: */
if (empty($data['alias'])) {
$data['alias'] = ApplicationHelper::stringURLSafe($data['name_short']);
}
$result = parent::save($data);
// if ($result) {
// $this->getTable('', 'Administrator')->rebuild(1);
// }
return $result;
}
}
+74
Datei anzeigen
@@ -0,0 +1,74 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.3
*/
namespace KW4NZ\Component\Depot\Administrator\Model;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\CMS\Table\Table;
\defined('_JEXEC') or die;
class StocksModel extends ListModel
{
/**
* Build an SQL query to load the list data.
*
* @return \Joomla\Database\DatabaseQuery
*
* @since 1.6
*/
protected function getListQuery()
{
$db = $this->getDatabase();
$query = $db->getQuery(true);
// $query->select('*')
// ->from($db->quoteName('#__depot', 'd'));
// order by
// $query->order('d.id ASC');
// if (true) {
// return $query;
// }
// select the required fields from the table
$query->select(
$this->getState(
'list.select',
[
$db->quoteName('s.id'),
$db->quoteName('s.name'),
$db->quoteName('s.alias'),
$db->quoteName('s.description'),
]
)
)
->select(
[
$db->quoteName('u.name', 'creator'),
]
)
->from($db->quoteName('#__depot_stock', 's'))
->join('LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('s.checked_out'));
// Filter by published state
$published = (string) $this->getState('filter.published');
if (is_numeric($published)) {
$published = (int) $published;
$query->where($db->quoteName('s.state') . ' = :published')
->bind(':published', $published, ParameterType::INTEGER);
} elseif ($published === '') {
$query->where($db->quoteName('s.state') . ' IN (0, 1)');
}
return $query;
}
}
-126
Datei anzeigen
@@ -1,126 +0,0 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_banners
*
* @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace KW4NZ\Component\Depot\Administrator\Service\Html;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\Database\DatabaseAwareTrait;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Banner HTML class.
*
* @since 2.5
*/
class Depot
{
use DatabaseAwareTrait;
/**
* Display a batch widget for the client selector.
*
* @return string The necessary HTML for the widget.
*
* @since 2.5
*/
public function clients()
{
// Create the batch selector to change the client on a selection list.
return implode(
"\n",
[
'<label id="batch-client-lbl" for="batch-client-id">',
Text::_('COM_BANNERS_BATCH_CLIENT_LABEL'),
'</label>',
'<select class="form-select" name="batch[client_id]" id="batch-client-id">',
'<option value="">' . Text::_('COM_BANNERS_BATCH_CLIENT_NOCHANGE') . '</option>',
'<option value="0">' . Text::_('COM_BANNERS_NO_CLIENT') . '</option>',
HTMLHelper::_('select.options', static::clientlist(), 'value', 'text'),
'</select>',
]
);
}
/**
* Method to get the field options.
*
* @return array The field option objects.
*
* @since 1.6
*/
public function clientlist()
{
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select(
[
$db->quoteName('id', 'value'),
$db->quoteName('component_name', 'text'),
]
)
->from($db->quoteName('#__depot_clients'))
->order($db->quoteName('component_name'));
// Get the options.
$db->setQuery($query);
try {
$options = $db->loadObjectList();
} catch (\RuntimeException $e) {
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
}
return $options;
}
/**
* Returns a pinned state on a grid
*
* @param integer $value The state value.
* @param integer $i The row index
* @param boolean $enabled An optional setting for access control on the action.
* @param string $checkbox An optional prefix for checkboxes.
*
* @return string The Html code
*
* @see HTMLHelperJGrid::state
* @since 2.5.5
*/
public function pinned($value, $i, $enabled = true, $checkbox = 'cb')
{
$states = [
1 => [
'sticky_unpublish',
'COM_BANNERS_BANNERS_PINNED',
'COM_BANNERS_BANNERS_HTML_UNPIN_BANNER',
'COM_BANNERS_BANNERS_PINNED',
true,
'publish',
'publish',
],
0 => [
'sticky_publish',
'COM_BANNERS_BANNERS_UNPINNED',
'COM_BANNERS_BANNERS_HTML_PIN_BANNER',
'COM_BANNERS_BANNERS_UNPINNED',
true,
'unpublish',
'unpublish',
],
];
return HTMLHelper::_('jgrid.state', $states, $value, $i, 'depots.', $enabled, true, $checkbox);
}
}
+74
Datei anzeigen
@@ -0,0 +1,74 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.1
*/
namespace KW4NZ\Component\Depot\Administrator\Table;
use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
\defined('_JEXEC') or die;
class ManufacturerTable extends Table
{
function __construct(DatabaseDriver $db)
{
parent::__construct('#__depot_manufacturer', 'id', $db);
// add an alias for published:
$this->setColumnAlias('published', 'state');
}
public function store($updateNulls = true)
{
$app = Factory::getApplication();
$date = Factory::getDate()->toSql();
// $user = Factory::getUser();
// $user = $this->getCurrentUser();
$user = $app->getIdentity();
if (!$this->created) {
$this->created = $date;
}
if (!$this->created_by) {
$this->created_by = $user->get('id');
}
if ($this->id) {
// existing item
$this->modified_by = $user->get('id');
$this->modified = $date;
} else {
// set modified to created date if not set
if (!$this->modified) {
$this->modified = $this->created;
}
if (empty($this->modified_by)) {
$this->modified_by = $this->created_by;
}
}
// Verify that the alias is unique
$table = $app->bootComponent('com_depot')->getMVCFactory()->createTable('Manufacturer', 'Administrator');
if ($table->load(['alias' => $this->alias]) && ($table->id != $this->id || $this->id == 0)) {
$this->setError('Alias is not unique.');
if ($table->state == -2) {
$this->setError('Alias is not unique. The item is in Trash.');
}
return false;
}
return parent::store($updateNulls);
}
}
+74
Datei anzeigen
@@ -0,0 +1,74 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.2
*/
namespace KW4NZ\Component\Depot\Administrator\Table;
use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
\defined('_JEXEC') or die;
class PartTable extends Table
{
function __construct(DatabaseDriver $db)
{
parent::__construct('#__depot', 'id', $db);
// add an alias for published:
$this->setColumnAlias('published', 'state');
}
public function store($updateNulls = true)
{
$app = Factory::getApplication();
$date = Factory::getDate()->toSql();
// $user = Factory::getUser();
// $user = $this->getCurrentUser();
$user = $app->getIdentity();
if (!$this->created) {
$this->created = $date;
}
if (!$this->created_by) {
$this->created_by = $user->get('id');
}
if ($this->id) {
// existing item
$this->modified_by = $user->get('id');
$this->modified = $date;
} else {
// set modified to created date if not set
if (!$this->modified) {
$this->modified = $this->created;
}
if (empty($this->modified_by)) {
$this->modified_by = $this->created_by;
}
}
// Verify that the alias is unique
$table = $app->bootComponent('com_depot')->getMVCFactory()->createTable('Part', 'Administrator');
if ($table->load(['alias' => $this->alias]) && ($table->id != $this->id || $this->id == 0)) {
$this->setError('Alias is not unique.');
if ($table->state == -2) {
$this->setError('Alias is not unique. The item is in Trash.');
}
return false;
}
return parent::store($updateNulls);
}
}
+74
Datei anzeigen
@@ -0,0 +1,74 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.2
*/
namespace KW4NZ\Component\Depot\Administrator\Table;
use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\Database\DatabaseDriver;
\defined('_JEXEC') or die;
class StockTable extends Table
{
function __construct(DatabaseDriver $db)
{
parent::__construct('#__depot_stock', 'id', $db);
// add an alias for published:
$this->setColumnAlias('published', 'state');
}
public function store($updateNulls = true)
{
$app = Factory::getApplication();
$date = Factory::getDate()->toSql();
// $user = Factory::getUser();
// $user = $this->getCurrentUser();
$user = $app->getIdentity();
if (!$this->created) {
$this->created = $date;
}
if (!$this->created_by) {
$this->created_by = $user->get('id');
}
if ($this->id) {
// existing item
$this->modified_by = $user->get('id');
$this->modified = $date;
} else {
// set modified to created date if not set
if (!$this->modified) {
$this->modified = $this->created;
}
if (empty($this->modified_by)) {
$this->modified_by = $this->created_by;
}
}
// Verify that the alias is unique
$table = $app->bootComponent('com_depot')->getMVCFactory()->createTable('Stock', 'Administrator');
if ($table->load(['alias' => $this->alias]) && ($table->id != $this->id || $this->id == 0)) {
$this->setError('Alias is not unique.');
if ($table->state == -2) {
$this->setError('Alias is not unique. The item is in Trash.');
}
return false;
}
return parent::store($updateNulls);
}
}
-209
Datei anzeigen
@@ -1,209 +0,0 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_depot
*
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace KW4NZ\Component\Depot\Administrator\View\Depots;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Pagination\Pagination;
use Joomla\CMS\Toolbar\Button\DropdownButton;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
use Joomla\Registry\Registry;
use KW4NZ\Component\Depot\Administrator\Model\DepotsModel;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* View class for a list of banners.
*
* @since 1.6
*/
class HtmlView extends BaseHtmlView
{
/**
* The search tools form
*
* @var Form
* @since 1.6
*/
public $filterForm;
/**
* The active search filters
*
* @var array
* @since 1.6
*/
public $activeFilters = [];
/**
* Category data
*
* @var array
* @since 1.6
*/
protected $categories = [];
/**
* An array of items
*
* @var array
* @since 1.6
*/
protected $items = [];
/**
* The pagination object
*
* @var Pagination
* @since 1.6
*/
protected $pagination;
/**
* The model state
*
* @var Registry
* @since 1.6
*/
protected $state;
/**
* Is this view an Empty State
*
* @var boolean
* @since 4.0.0
*/
private $isEmptyState = false;
/**
* Method to display the view.
*
* @param string $tpl A template file to load. [optional]
*
* @return void
*
* @since 1.6
* @throws \Exception
*/
public function display($tpl = null): void
{
/** @var DepotsModel $model */
$model = $this->getModel();
$this->categories = $model->getCategoryOrders();
$this->items = $model->getItems();
$this->pagination = $model->getPagination();
$this->state = $model->getState();
$this->filterForm = $model->getFilterForm();
$this->activeFilters = $model->getActiveFilters();
if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) {
$this->setLayout('emptystate');
}
// Check for errors.
if (\count($errors = $this->get('Errors'))) {
throw new GenericDataException(implode("\n", $errors), 500);
}
$this->addToolbar();
// We do not need to filter by language when multilingual is disabled
if (!Multilanguage::isEnabled()) {
unset($this->activeFilters['language']);
$this->filterForm->removeField('language', 'filter');
}
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 1.6
*/
protected function addToolbar(): void
{
$canDo = ContentHelper::getActions('com_depot', 'category', $this->state->get('filter.category_id'));
$user = $this->getCurrentUser();
$toolbar = Toolbar::getInstance();
ToolbarHelper::title(Text::_('COM_DEPOT_MANAGER_DEPOTS'), 'bookmark depot');
if ($canDo->get('core.create') || \count($user->getAuthorisedCategories('com_depot', 'core.create')) > 0) {
$toolbar->addNew('depot.add');
}
if (!$this->isEmptyState && ($canDo->get('core.edit.state') || ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')))) {
/** @var DropdownButton $dropdown */
$dropdown = $toolbar->dropdownButton('status-group', 'JTOOLBAR_CHANGE_STATUS')
->toggleSplit(false)
->icon('icon-ellipsis-h')
->buttonClass('btn btn-action')
->listCheck(true);
$childBar = $dropdown->getChildToolbar();
if ($canDo->get('core.edit.state')) {
if ($this->state->get('filter.published') != 2) {
$childBar->publish('depot.publish')->listCheck(true);
$childBar->unpublish('depot.unpublish')->listCheck(true);
}
if ($this->state->get('filter.published') != -1) {
if ($this->state->get('filter.published') != 2) {
$childBar->archive('depot.archive')->listCheck(true);
} elseif ($this->state->get('filter.published') == 2) {
$childBar->publish('publish')->task('depot.publish')->listCheck(true);
}
}
$childBar->checkin('depot.checkin');
if ($this->state->get('filter.published') != -2) {
$childBar->trash('depot.trash')->listCheck(true);
}
}
if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) {
$toolbar->delete('depot.delete', 'JTOOLBAR_EMPTY_TRASH')
->message('JGLOBAL_CONFIRM_DELETE')
->listCheck(true);
}
// Add a batch button
if (
$user->authorise('core.create', 'com_depot')
&& $user->authorise('core.edit', 'com_depot')
&& $user->authorise('core.edit.state', 'com_depot')
) {
$childBar->popupButton('batch', 'JTOOLBAR_BATCH')
->selector('collapseModal')
->listCheck(true);
}
}
if ($user->authorise('core.admin', 'com_depot') || $user->authorise('core.options', 'com_depot')) {
$toolbar->preferences('com_depot');
}
$toolbar->help('Depots');
}
}
@@ -0,0 +1,75 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.1
*/
namespace KW4NZ\Component\Depot\Administrator\View\Manufacturer;
use Joomla\CMS\Factory;
// use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
\defined('_JEXEC') or die;
/**
* View to edit an article.
*
* @since 1.6
*/
class HtmlView extends BaseHtmlView
{
/**
* The \JForm object
*
* @var \JForm
*/
protected $form;
/**
* The active item
*
* @var object
*/
protected $item;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @throws \Exception
* @since 1.6
*/
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
// if (count($errors = $this->get('Errors'))) {
// throw new GenericDataException(implode("\n", $errors), 500);
// }
$this->addToolbar();
return parent::display($tpl);
}
protected function addToolbar()
{
Factory::getApplication()->getInput()->set('hidemainmenu', true);
ToolbarHelper::title('Manufacturer: Add');
ToolbarHelper::apply('manufacturer.apply');
ToolbarHelper::save('manufacturer.save');
ToolbarHelper::cancel('manufacturer.cancel', 'JTOOLBAR_CLOSE');
}
}
@@ -0,0 +1,47 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.3
*/
namespace KW4NZ\Component\Depot\Administrator\View\Manufacturers;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
// use Joomla\CMS\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
// use Joomla\CMS\Language\Text;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null)
{
// Get application
$app = Factory::getApplication();
$this->items = $this->get('Items');
// set the toolbar
$this->addToolbar();
parent::display($tpl);
}
protected function addToolbar()
{
ToolbarHelper::title(Text::_('COM_DEPOT_MANAGER_MANUFACTURERS'));
ToolbarHelper::addNew('manufacturer.add');
ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'manufacturers.delete');
ToolbarHelper::publish('manufacturers.publish', 'JTOOLBAR_PUBLISH', true);
ToolbarHelper::unpublish('manufacturers.unpublish', 'JTOOLBAR_UNPUBLISH', true);
}
}
+75
Datei anzeigen
@@ -0,0 +1,75 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.3
*/
namespace KW4NZ\Component\Depot\Administrator\View\Part;
use Joomla\CMS\Factory;
// use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
\defined('_JEXEC') or die;
/**
* View to edit an article.
*
* @since 1.6
*/
class HtmlView extends BaseHtmlView
{
/**
* The \JForm object
*
* @var \JForm
*/
protected $form;
/**
* The active item
*
* @var object
*/
protected $item;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @throws \Exception
* @since 1.6
*/
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
// if (count($errors = $this->get('Errors'))) {
// throw new GenericDataException(implode("\n", $errors), 500);
// }
$this->addToolbar();
return parent::display($tpl);
}
protected function addToolbar()
{
Factory::getApplication()->getInput()->set('hidemainmenu', true);
ToolbarHelper::title('Part: Add');
ToolbarHelper::apply('part.apply');
ToolbarHelper::save('part.save');
ToolbarHelper::cancel('part.cancel', 'JTOOLBAR_CLOSE');
}
}
+47
Datei anzeigen
@@ -0,0 +1,47 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.1
*/
namespace KW4NZ\Component\Depot\Administrator\View\Parts;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
// use Joomla\CMS\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
// use Joomla\CMS\Language\Text;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null)
{
// Get application
$app = Factory::getApplication();
$this->items = $this->get('Items');
// set the toolbar
$this->addToolbar();
parent::display($tpl);
}
protected function addToolbar()
{
ToolbarHelper::title(Text::_('COM_DEPOT_MANAGER_PARTS'));
ToolbarHelper::addNew('part.add');
ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'parts.delete');
ToolbarHelper::publish('parts.publish', 'JTOOLBAR_PUBLISH', true);
ToolbarHelper::unpublish('parts.unpublish', 'JTOOLBAR_UNPUBLISH', true);
}
}
+74
Datei anzeigen
@@ -0,0 +1,74 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.2
*/
namespace KW4NZ\Component\Depot\Administrator\View\Stock;
use Joomla\CMS\Factory;
// use Joomla\CMS\MVC\View\GenericDataException;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
\defined('_JEXEC') or die;
/**
* View to edit an article.
*
* @since 1.6
*/
class HtmlView extends BaseHtmlView
{
/**
* The \JForm object
*
* @var \JForm
*/
protected $form;
/**
* The active item
*
* @var object
*/
protected $item;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return mixed A string if successful, otherwise an Error object.
*
* @throws \Exception
* @since 1.6
*/
public function display($tpl = null)
{
$this->form = $this->get('Form');
$this->item = $this->get('Item');
// if (count($errors = $this->get('Errors'))) {
// throw new GenericDataException(implode("\n", $errors), 500);
// }
$this->addToolbar();
return parent::display($tpl);
}
protected function addToolbar()
{
Factory::getApplication()->getInput()->set('hidemainmenu', true);
ToolbarHelper::title('Stock: Add');
ToolbarHelper::apply('stock.apply');
ToolbarHelper::save('stock.save');
ToolbarHelper::cancel('stock.cancel', 'JTOOLBAR_CLOSE');
}
}
+47
Datei anzeigen
@@ -0,0 +1,47 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.3
*/
namespace KW4NZ\Component\Depot\Administrator\View\Stocks;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
// use Joomla\CMS\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
// use Joomla\CMS\Language\Text;
class HtmlView extends BaseHtmlView
{
public function display($tpl = null)
{
// Get application
$app = Factory::getApplication();
$this->items = $this->get('Items');
// set the toolbar
$this->addToolbar();
parent::display($tpl);
}
protected function addToolbar()
{
ToolbarHelper::title(Text::_('COM_DEPOT_MANAGER_STOCKS'));
ToolbarHelper::addNew('stock.add');
ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'stocks.delete');
ToolbarHelper::publish('stocks.publish', 'JTOOLBAR_PUBLISH', true);
ToolbarHelper::unpublish('stocks.unpublish', 'JTOOLBAR_UNPUBLISH', true);
}
}
Datei anzeigen
-195
Datei anzeigen
@@ -1,195 +0,0 @@
<?php
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
\defined('_JEXEC') or die;
/** @var \Joomla\Component\Banners\Administrator\View\Banners\HtmlView $this */
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('table.columns')
->useScript('multiselect');
$user = $this->getCurrentUser();
$userId = $user->get('id');
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
$saveOrder = $listOrder == 'a.ordering';
if ($saveOrder && !empty($this->items)) {
$saveOrderingUrl = 'index.php?option=com_depot&task=depots.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1';
HTMLHelper::_('draggablelist.draggable');
}
?>
<form action="<?php echo Route::_('index.php?option=com_depot&view=depots'); ?>" method="post" name="adminForm" id="adminForm">
<div class="row">
<div class="col-md-12">
<div id="j-main-container" class="j-main-container">
<?php
// Search tools bar
echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this]);
?>
<?php if (empty($this->items)) : ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table" id="bannerList">
<caption class="visually-hidden">
<?php echo Text::_('COM_BANNERS_BANNERS_TABLE_CAPTION'); ?>,
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
</caption>
<thead>
<tr>
<td class="w-1 text-center">
<?php echo HTMLHelper::_('grid.checkall'); ?>
</td>
<th scope="col" class="w-1 text-center d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', '', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING', 'icon-sort'); ?>
</th>
<th scope="col" class="w-1 text-center">
<?php echo HTMLHelper::_('searchtools.sort', 'JSTATUS', 'a.state', $listDirn, $listOrder); ?>
</th>
<th scope="col">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_BANNERS_HEADING_NAME', 'a.name', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-10 text-center d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_BANNERS_HEADING_STICKY', 'a.sticky', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-10 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_BANNERS_HEADING_CLIENT', 'client_name', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-10 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_BANNERS_HEADING_IMPRESSIONS', 'impmade', $listDirn, $listOrder); ?>
</th>
<th scope="col" class="w-10 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_BANNERS_HEADING_CLICKS', 'clicks', $listDirn, $listOrder); ?>
</th>
<?php if (Multilanguage::isEnabled()) : ?>
<th scope="col" class="w-10 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_LANGUAGE', 'a.language', $listDirn, $listOrder); ?>
</th>
<?php endif; ?>
<th scope="col" class="w-5 d-none d-md-table-cell">
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
</th>
</tr>
</thead>
<tbody <?php if ($saveOrder) :
?> class="js-draggable" data-url="<?php echo $saveOrderingUrl; ?>" data-direction="<?php echo strtolower($listDirn); ?>" data-nested="true"<?php
endif; ?>>
<?php foreach ($this->items as $i => $item) :
$ordering = ($listOrder == 'ordering');
$item->cat_link = Route::_('index.php?option=com_categories&extension=com_banners&task=edit&type=other&cid[]=' . $item->catid);
$canCreate = $user->authorise('core.create', 'com_banners.category.' . $item->catid);
$canEdit = $user->authorise('core.edit', 'com_banners.category.' . $item->catid);
$canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || is_null($item->checked_out);
$canChange = $user->authorise('core.edit.state', 'com_banners.category.' . $item->catid) && $canCheckin;
?>
<tr class="row<?php echo $i % 2; ?>" data-draggable-group="<?php echo $item->catid; ?>">
<td class="text-center">
<?php echo HTMLHelper::_('grid.id', $i, $item->id, false, 'cid', 'cb', $item->name); ?>
</td>
<td class="text-center d-none d-md-table-cell">
<?php
$iconClass = '';
if (!$canChange) {
$iconClass = ' inactive';
} elseif (!$saveOrder) {
$iconClass = ' inactive" title="' . Text::_('JORDERINGDISABLED');
}
?>
<span class="sortable-handler <?php echo $iconClass ?>">
<span class="icon-ellipsis-v" aria-hidden="true"></span>
</span>
<?php if ($canChange && $saveOrder) : ?>
<input type="text" name="order[]" size="5"
value="<?php echo $item->ordering; ?>" class="width-20 text-area-order hidden">
<?php endif; ?>
</td>
<td class="text-center">
<?php echo HTMLHelper::_('jgrid.published', $item->state, $i, 'banners.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?>
</td>
<th scope="row">
<div class="break-word">
<?php if ($item->checked_out) : ?>
<?php echo HTMLHelper::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'banners.', $canCheckin); ?>
<?php endif; ?>
<?php if ($canEdit) : ?>
<a href="<?php echo Route::_('index.php?option=com_banners&task=banner.edit&id=' . (int) $item->id); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape($item->name); ?>">
<?php echo $this->escape($item->name); ?></a>
<?php else : ?>
<?php echo $this->escape($item->name); ?>
<?php endif; ?>
<div class="small break-word">
<?php echo Text::sprintf('JGLOBAL_LIST_ALIAS', $this->escape($item->alias)); ?>
</div>
<div class="small">
<?php echo Text::_('JCATEGORY') . ': ' . $this->escape($item->category_title); ?>
</div>
</div>
</th>
<td class="text-center d-none d-md-table-cell">
<?php echo HTMLHelper::_('banner.pinned', $item->sticky, $i, $canChange); ?>
</td>
<td class="small d-none d-md-table-cell">
<?php echo $item->client_name; ?>
</td>
<td class="small d-none d-md-table-cell">
<?php echo Text::sprintf('COM_BANNERS_IMPRESSIONS', $item->impmade, $item->imptotal ?: Text::_('COM_BANNERS_UNLIMITED')); ?>
</td>
<td class="small d-none d-md-table-cell">
<?php echo $item->clicks; ?> -
<?php echo sprintf('%.2f%%', $item->impmade ? 100 * $item->clicks / $item->impmade : 0); ?>
</td>
<?php if (Multilanguage::isEnabled()) : ?>
<td class="small d-none d-md-table-cell">
<?php echo LayoutHelper::render('joomla.content.language', $item); ?>
</td>
<?php endif; ?>
<td class="d-none d-md-table-cell">
<?php echo $item->id; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php // Load the pagination. ?>
<?php echo $this->pagination->getListFooter(); ?>
<?php // Load the batch processing form. ?>
<?php
if (
$user->authorise('core.create', 'com_banners')
&& $user->authorise('core.edit', 'com_banners')
&& $user->authorise('core.edit.state', 'com_banners')
) : ?>
<?php echo HTMLHelper::_(
'bootstrap.renderModal',
'collapseModal',
[
'title' => Text::_('COM_BANNERS_BATCH_OPTIONS'),
'footer' => $this->loadTemplate('batch_footer')
],
$this->loadTemplate('batch_body')
); ?>
<?php endif; ?>
<?php endif; ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?php echo HTMLHelper::_('form.token'); ?>
</div>
</div>
</div>
</form>
Datei anzeigen
+62
Datei anzeigen
@@ -0,0 +1,62 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.3
*/
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('form.validate')
->useScript('keepalive');
?>
<form action="<?= Route::_('index.php?option=com_depot&view=manufactuerer&layout=edit&id=' . (int) $this->item->id); ?>"
method="post" name="adminForm" id="item-form" class="form-validate">
<?= HtmlHelper::_('uitab.startTabSet', 'myTab', ['active' => 'details']); ?>
<?= HTMLHelper::_(
'uitab.addTab',
'myTab',
'details',
empty($this->item->id) ? Text::_('COM_DEPOT_TAB_NEW_MANUFACTURER') :
Text::_('COM_DEPOT_TAB_EDIT_MANUFACTURER')
); ?>
<fieldset id="fieldset-details" class="options-form">
<legend>
<?= Text::_('COM_DEPOT_LEGEND_MANUFACTURER_DETAILS') ?>
</legend>
<div class="row">
<div class="col-12 col-lg-6">
<?= $this->form->renderFieldset('details'); ?>
</div>
<div class="col-12 col-lg-6">
<?= $this->form->getInput('description'); ?>
</div>
</div>
</fieldset>
<?= HtmlHelper::_('uitab.endTab'); ?>
<?= HTMLHelper::_('uitab.addTab', 'myTab', 'statistics', Text::_('COM_DEPOT_TAB_STATISTICS')); ?>
<fieldset class="options-form">
<legend>
<?= Text::_('COM_DEPOT_LEGEND_STATISTICS') ?>
</legend>
<div class="row">
<div class="col-12 col-lg-9">
<?= $this->form->renderFieldset('statistics'); ?>
</div>
</div>
</fieldset>
<?= HTMLHelper::_('uitab.endTab'); ?>
<?= HtmlHelper::_('uitab.endTabSet'); ?>
<input type="hidden" name="task" value="manufacturer.edit" />
<?= HTMLHelper::_('form.token'); ?>
</form>
+73
Datei anzeigen
@@ -0,0 +1,73 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.3
*/
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
?>
<form action="<?= Route::_('index.php?option=com_depot&view=manufacturers'); ?>" method="post" name="adminForm"
id="adminForm">
<?php if (empty($this->items)): ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true">
</span>
<?= Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else: ?>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>
<?= HTMLHelper::_('grid.checkall'); ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_ID') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_MANUFACTURER_ACRONYM') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_MANUFACTURER') ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $item): ?>
<tr>
<td>
<?= HTMLHelper::_('grid.id', $i, $item->id); ?>
</td>
<td>
<?= $item->id ?>
</td>
<td>
<a href="<?= Route::_('index.php?option=com_depot&task=manufacturer.edit&id=' .
(int) $item->id) ?>" title="<?= Text::_('JACTION_EDIT') ?>">
<?= $this->escape($item->name_short); ?>
</a>
</td>
<td>
<?= $this->escape($item->name_long); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?= HTMLHelper::_('form.token'); ?>
</form>
+62
Datei anzeigen
@@ -0,0 +1,62 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.2
*/
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('form.validate')
->useScript('keepalive');
?>
<form action="<?= Route::_('index.php?option=com_depot&view=part&layout=edit&id=' . (int) $this->item->id); ?>"
method="post" name="adminForm" id="item-form" class="form-validate">
<?= HtmlHelper::_('uitab.startTabSet', 'myTab', ['active' => 'details']); ?>
<?= HTMLHelper::_(
'uitab.addTab',
'myTab',
'details',
empty($this->item->id) ? Text::_('COM_DEPOT_TAB_NEW_PART') :
Text::_('COM_DEPOT_TAB_EDIT_PART')
); ?>
<fieldset id="fieldset-details" class="options-form">
<legend>
<?= Text::_('COM_DEPOT_LEGEND_PART_DETAILS') ?>
</legend>
<div class="row">
<div class="col-12 col-lg-6">
<?= $this->form->renderFieldset('details'); ?>
</div>
<div class="col-12 col-lg-6">
<?= $this->form->getInput('description'); ?>
</div>
</div>
</fieldset>
<?= HtmlHelper::_('uitab.endTab'); ?>
<?= HTMLHelper::_('uitab.addTab', 'myTab', 'statistics', Text::_('COM_DEPOT_TAB_STATISTICS')); ?>
<fieldset class="options-form">
<legend>
<?= Text::_('COM_DEPOT_LEGEND_STATISTICS') ?>
</legend>
<div class="row">
<div class="col-12 col-lg-9">
<?= $this->form->renderFieldset('statistics'); ?>
</div>
</div>
</fieldset>
<?= HTMLHelper::_('uitab.endTab'); ?>
<?= HtmlHelper::_('uitab.endTabSet'); ?>
<input type="hidden" name="task" value="part.edit" />
<?= HTMLHelper::_('form.token'); ?>
</form>
+96
Datei anzeigen
@@ -0,0 +1,96 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.1
*/
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
?>
<form action="<?= Route::_('index.php?option=com_depot&view=parts'); ?>" method="post" name="adminForm" id="adminForm">
<?php if (empty($this->items)): ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true">
</span>
<?= Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else: ?>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>
<?= HTMLHelper::_('grid.checkall'); ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_ID') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_NAME') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_QUANTITY') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_QUANTITY_EXP') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_MANUFACTURER') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_STOCK') ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $item): ?>
<tr>
<td>
<?= HTMLHelper::_('grid.id', $i, $item->id); ?>
</td>
<td>
<?= $item->id ?>
</td>
<td>
<a href="<?= Route::_('index.php?option=com_depot&task=part.edit&id=' .
(int) $item->id) ?>" title="<?= Text::_('JACTION_EDIT') ?>">
<?= $this->escape($item->component_name); ?>
</a>
</td>
<td>
<?= $this->escape($item->quantity); ?>
</td>
<td>
<?= "10^" . $item->quantity_exp; ?>
</td>
<td>
<a href="<?= Route::_('index.php?option=com_depot&task=manufacturer.edit&id=' .
(int) $item->id) ?>" title="<?= Text::_('JACTION_EDIT') ?>">
<?= $this->escape($item->manufacturer); ?>
</a>
</td>
<td>
<a href="<?= Route::_('index.php?option=com_depot&task=stock.edit&id=' .
(int) $item->id) ?>" title="<?= Text::_('JACTION_EDIT') ?>">
<?= $this->escape($item->stock_name); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?= HTMLHelper::_('form.token'); ?>
</form>
+62
Datei anzeigen
@@ -0,0 +1,62 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.0.3
*/
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = $this->document->getWebAssetManager();
$wa->useScript('form.validate')
->useScript('keepalive');
?>
<form action="<?= Route::_('index.php?option=com_depot&view=stock&layout=edit&id=' . (int) $this->item->id); ?>"
method="post" name="adminForm" id="item-form" class="form-validate">
<?= HtmlHelper::_('uitab.startTabSet', 'myTab', ['active' => 'details']); ?>
<?= HTMLHelper::_(
'uitab.addTab',
'myTab',
'details',
empty($this->item->id) ? Text::_('COM_DEPOT_TAB_NEW_STOCK') :
Text::_('COM_DEPOT_TAB_EDIT_STOCK')
); ?>
<fieldset id="fieldset-details" class="options-form">
<legend>
<?= Text::_('COM_DEPOT_LEGEND_STOCK_DETAILS') ?>
</legend>
<div class="row">
<div class="col-12 col-lg-6">
<?= $this->form->renderFieldset('details'); ?>
</div>
<div class="col-12 col-lg-6">
<?= $this->form->getInput('description'); ?>
</div>
</div>
</fieldset>
<?= HtmlHelper::_('uitab.endTab'); ?>
<?= HTMLHelper::_('uitab.addTab', 'myTab', 'statistics', Text::_('COM_DEPOT_TAB_STATISTICS')); ?>
<fieldset class="options-form">
<legend>
<?= Text::_('COM_DEPOT_LEGEND_STATISTICS') ?>
</legend>
<div class="row">
<div class="col-12 col-lg-9">
<?= $this->form->renderFieldset('statistics'); ?>
</div>
</div>
</fieldset>
<?= HTMLHelper::_('uitab.endTab'); ?>
<?= HtmlHelper::_('uitab.endTabSet'); ?>
<input type="hidden" name="task" value="stock.edit" />
<?= HTMLHelper::_('form.token'); ?>
</form>
+71
Datei anzeigen
@@ -0,0 +1,71 @@
<?php
/**
* @package Depot.Administrator
* @subpackage com_depot
* @author Thomas Kuschel <thomas@kuschel.at>
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
* @license GNU General Public License version 2 or later; see LICENSE.md
* @since 0.9.3
*/
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
?>
<form action="<?= Route::_('index.php?option=com_depot&view=stocks'); ?>" method="post" name="adminForm" id="adminForm">
<?php if (empty($this->items)): ?>
<div class="alert alert-info">
<span class="icon-info-circle" aria-hidden="true">
</span>
<?= Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else: ?>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>
<?= HTMLHelper::_('grid.checkall'); ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_ID') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_STOCK') ?>
</th>
<th>
<?= Text::_('COM_DEPOT_TABLE_HEAD_DESCRIPTION') ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $i => $item): ?>
<tr>
<td>
<?= HTMLHelper::_('grid.id', $i, $item->id); ?>
</td>
<td>
<?= $item->id ?>
</td>
<td>
<a href="<?= Route::_('index.php?option=com_depot&task=stock.edit&id=' .
(int) $item->id) ?>" title="<?= Text::_('JACTION_EDIT') ?>">
<?= $this->escape($item->name); ?>
</a>
</td>
<td>
<?= $this->escape($item->description); ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<input type="hidden" name="task" value="">
<input type="hidden" name="boxchecked" value="0">
<?= HTMLHelper::_('form.token'); ?>
</form>
+16 -37
Datei anzeigen
@@ -2,15 +2,14 @@
<extension type="component" method="upgrade">
<name>Depot</name>
<author>KW4NZ</author>
<creationDate>2023-10-01</creationDate>
<creationDate>2023-10-15</creationDate>
<copyright>(C) KW4NZ Thomas Kuschel</copyright>
<license>GPL v3; see LICENSE.txt</license>
<license>GPL v2 +; see LICENSE.md</license>
<authorEmail>thomas@kuschel.at</authorEmail>
<authorUrl>https://kuschel.at</authorUrl>
<version>0.0.1</version>
<version>0.9.3</version>
<description>COM_DEPOT_XML_DESCRIPTION</description>
<namespace path="src/">KW4NZ\Component\Depot</namespace>
<scriptfile>depot_installer_script.php</scriptfile>
<install> <!-- Runs on install -->
<sql>
<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
@@ -21,78 +20,58 @@
<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
</sql>
</uninstall>
<update> <!-- Runs on update -->
<update>
<schemas>
<schemapath type="mysql">sql/updates/mysql</schemapath>
</schemas>
</update>
<files folder="site/">
<folder>forms</folder>
<folder>helpers</folder>
<folder>src</folder>
<folder>tmpl</folder>
<file>CODING_STANDARDS.md</file>
<file>LICENSE.md</file>
<file>README.md</file>
</files>
<languages folder="site/language">
<language tag="de-DE">de-DE/com_depot.ini</language>
<language tag="en-GB">en-GB/com_depot.ini</language>
</languages>
<media destination="com_depot" folder="media">
<filename>joomla.asset.json</filename>
<folder>js</folder>
<folder>css</folder>
</media>
<administration>
<!--
Note that all & must be escaped to &amp; for the file to be valid
XML and be parsed by the installer
-->
<menu img="class:bookmark">COM_DEPOT_MENU</menu>
<menu img="class:barcode">COM_DEPOT_MENU</menu>
<submenu>
<menu
link="option=com_depot"
view="depots"
img="class:depots"
alt="Depot/Depots"
view="parts"
img="class:depot"
alt="Depot/Parts"
>
COM_DEPOT_MENU
</menu>
<menu
link="option=com_depot"
link="option=com_depot&amp;view=manufacturers"
view="manufacturers"
img="class:depot-manufacturers"
img="class:depot-manufacturer"
alt="Depot/Manufacturers"
>
COM_DEPOT_MENU_MANUFACTURERS
</menu>
<menu
link="option=com_depot"
link="option=com_depot&amp;view=stocks"
view="stocks"
img="class:depot-stocks"
img="class:depot-stock"
alt="Depot/Stocks"
>
COM_DEPOT_MENU_STOCKS
</menu>
<menu link="option=com_categories&amp;extension=com_depot">COM_DEPOT_CATEGORIES</menu>
<menu link="option=com_fields&amp;view=fields&amp;context=com_depot.part">MOD_MENU_FIELDS</menu>
<menu link="option=com_fields&amp;view=groups&amp;context=com_depot.part">MOD_MENU_FIELDS_GROUP</menu>
</submenu>
<files folder="admin">
<!-- <filename>access.xml</filename> -->
<!-- <filename>config.xml</filename> -->
<folder>forms</folder>
<folder>layouts</folder>
<folder>services</folder>
<folder>sql</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages folder="admin/language">
<language tag="de-DE">en-GB/com_depot.ini</language>
<language tag="de-DE">en-GB/com_depot.sys.ini</language>
<language tag="en-GB">en-GB/com_depot.ini</language>
<language tag="en-GB">en-GB/com_depot.sys.ini</language>
</languages>
</administration>
<updateservers>
<server type="extension" priority="1" name="COM_DEPOT_XML_DESCRIPTION">https://kuschel.at/updates/depot.xml</server>
</updateservers>
</extension>
-117
Datei anzeigen
@@ -1,117 +0,0 @@
<?php
use Joomla\CMS\Log\Log;
\defined('_JEXEC') or die;
class DepotInstallerScript
{
/**
* The Depot version we are updating from
*/
protected $fromVersion = null;
/**
* Callback for collectiong errors. Like function(string $context, \Throwable $error){};
*
* @var callable
*
* @since 4.4.0
*/
protected $errorCollector;
/**
* Set the callback for collecting errors.
*
* @param callable $callback The callback Like function(string $context, \Throwable $error){};
*
* @return void
*
* @since 4.4.0
*/
public function setErrorCollector(callable $callback) {
$this->errorCollector = $callback;
}
/**
* Collect errors.
*
* @param string $context A context/place where error happened
* @param \Throwable $error The error that occurred
*
* @return void
*
* @since 4.4.0
*/
protected function collectError(string $context, \Throwable $error) {
// The errorCollector are required
// However when someone already running the script manually the code may fail.
if ($this->errorCollector) {
call_user_func($this->errorCollector, $context, $error);
} else {
Log::add($error->getMessage(), Log::ERROR, 'Update');
}
}
/**
* Function to act prior to installation process begins
*
* @param string $action Which action is happening (install|uninstall|discover_install|update)
* @param Installer $installer The class calling this method
*
* @return boolean True on success
*
* @since 3.7.0
*/
public function preflight($action, $installer) {
if ($action === 'update') {
// Get the version we are updating from
if (!empty($installer->extension->manifest_cache)) {
$manifestValues = json_decode($installer->extension->manifest_cache, true);
if (array_key_exists('version', $manifestValues)) {
$this->fromVersion = $manifestValues['version'];
Log::add(Text::_('COM_DEPOT_PREFLIGHT_FROM_VERSION'), Log::INFO, 'Update');
return true;
}
}
return false;
}
return true;
}
/**
* Method to update Depot
*
* @param Installer $installer The class calling this method
*
* @return void
*/
public function update($installer) {
}
/**
* Called after any type of action
*
* @param string $action Which action is happening (install|uninstall|discover_install|update)
* @param Installer $installer The class calling this method
*
* @return boolean True on success
*
* @since 4.0.0
*/
public function postflight($action, $installer)
{
if ($action !== 'update') {
return true;
}
if (empty($this->fromVersion) || version_compare($this->fromVersion, '0.0.1', 'ge')) {
return true;
}
return true;
}
}
-34
Datei anzeigen
@@ -1,34 +0,0 @@
.map {
height:400px;
width:100%;
}
/* from http://cssdeck.com/labs/bv45bh6p */
div.map-callout {
min-height:50px;
width:200px;
float:left;
left:-20px;
top:10px;
background-color:#444;
position:relative;
color:#ccc;
padding:10px;
border-radius:3px;
box-shadow:0px 0px 20px #999;
margin:0px;
border:1px solid #333;
border-radius:5px;
text-shadow:0 0 1px #000;
}
.map-callout::before {
content:"";
width:0px;
height:0px;
border:0.8em solid transparent;
position:absolute;
}
.map-callout.map-callout-bottom::before {
left:5%;
top:-20px;
border-bottom:10px solid #444;
}
-41
Datei anzeigen
@@ -1,41 +0,0 @@
{
"$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
"name": "com_depot",
"version": "1.0.0",
"description": "Joomla CMS",
"license": "GPL-2.0-or-later",
"assets": [
{
"name": "com_depot.openstreetmap",
"type": "preset",
"dependencies": [
"com_depot.openstreetmap#style",
"com_depot.openstreetmap#script"
]
},
{
"name": "com_depot.openstreetmap",
"type": "script",
"uri": "com_depot/openstreetmap.js",
"dependencies": [
"com_depot.openlayers"
],
"attributes": {
"defer": true
},
"version": "1.0.0"
},
{
"name": "com_depot.openstreetmap",
"type": "style",
"uri": "com_depot/openstreetmap.css",
"dependencies": [
"com_depot.openlayers"
],
"attributes": {
"defer": true
},
"version": "1.0.0"
}
]
}
-137
Datei anzeigen
@@ -1,137 +0,0 @@
var map;
var ajaxurl;
jQuery(document).ready(function() {
// get the data passed from Joomla PHP
// params is a Javascript object with properties for the map display:
// centre latitude, centre longitude and zoom, and the helloworld greeting
const params = Joomla.getOptions('params');
ajaxurl = params.ajaxurl;
// We'll use OpenLayers to draw the map (http://openlayers.org/)
// Openlayers uses an x,y coordinate system for positions
// We need to convert our lat/long into an x,y pair which is relative
// to the map projection we're using, viz Spherical Mercator WGS 84
const x = parseFloat(params.longitude);
const y = parseFloat(params.latitude);
const mapCentre = ol.proj.fromLonLat([x, y]); // Spherical Mercator is assumed by default
// To draw a map, Openlayers needs:
// 1. a target HTML element into which the map is put
// 2. a map layer, which can be eg a Vector layer with details of polygons for
// country boundaries, lines for roads, etc, or a Tile layer, with individual
// .png files for each map tile (256 by 256 pixel square).
// 3. a view, specifying the 2D projection of the map (default Spherical Mercator),
// map centre coordinates and zoom level
map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({ // we'll get the tiles from the OSM server
source: new ol.source.OSM()
})
],
view: new ol.View({ // default is Spherical Mercator projection
center: mapCentre,
zoom: params.zoom
})
});
// Now we add a marker for our Helloworld position
// To do that, we specify it as a Point Feature, and we add styling
// to define how that Feature is presented on the map
var helloworldPoint = new ol.Feature({geometry: new ol.geom.Point(mapCentre)});
// we'll define the style as a red 5 point star with blue edging
const redFill = new ol.style.Fill({
color: 'red'
});
const blueStroke = new ol.style.Stroke({
color: 'blue',
width: 3
});
const star = new ol.style.RegularShape({
fill: redFill,
stroke: blueStroke,
points: 5,
radius1: 20, // outer radius of star
radius2: 10, // inner radius of star
})
helloworldPoint.setStyle(new ol.style.Style({
image: star
}));
// now we add the feature to the map via a Vector source and Vector layer
const vectorSource = new ol.source.Vector({});
vectorSource.addFeature(helloworldPoint);
const vector = new ol.layer.Vector({
source: vectorSource
});
map.addLayer(vector);
// If a user clicks on the star, then we'll show the helloworld greeting
// The greeting will go into another HTML element, with id="greeting-container"
// and this will be shown as an Overlay on the map
var overlay = new ol.Overlay({
element: document.getElementById('greeting-container'),
});
map.addOverlay(overlay);
// Finally we add the onclick listener to display the greeting when the star is clicked
// The way this works is that the onclick listener is attached to the map,
// and then it works out which Feature or Features have been hit
map.on('click', function(e) {
let markup = '';
let position;
map.forEachFeatureAtPixel(e.pixel, function(feature) { // for each Feature hit
markup = params.greeting;
position = feature.getGeometry().getCoordinates();
}, {hitTolerance: 5}); // tolerance of 5 pixels
if (markup) {
document.getElementById('greeting-container').innerHTML = markup;
overlay.setPosition(position);
} else {
overlay.setPosition(); // this hides it, if we click elsewhere
}
});
});
function getMapBounds(){
var mercatorMapbounds = map.getView().calculateExtent(map.getSize());
var latlngMapbounds = ol.proj.transformExtent(mercatorMapbounds,'EPSG:3857','EPSG:4326');
return { minlat: latlngMapbounds[1],
maxlat: latlngMapbounds[3],
minlng: latlngMapbounds[0],
maxlng: latlngMapbounds[2] }
}
function searchHere() {
var mapBounds = getMapBounds();
var token = jQuery("#token").attr("name");
jQuery.ajax({
url: ajaxurl,
data: { [token]: "1", task: "mapsearch", view: "helloworld", format: "json", mapBounds: mapBounds },
success: function(result, status, xhr) { displaySearchResults(result); },
error: function() { console.log('ajax call failed'); },
});
}
function displaySearchResults(result) {
if (result.success) {
var html = "";
for (var i=0; i<result.data.length; i++) {
html += '<p><a href="' + result.data[i].url + '">' +
result.data[i].greeting + '</a>' +
" @ " + result.data[i].latitude +
", " + result.data[i].longitude + "</p>";
}
jQuery("#searchresults").html(html);
} else {
var msg = result.message;
if ((result.messages) && (result.messages.error)) {
for (var j=0; j<result.messages.error.length; j++) {
msg += "<br/>" + result.messages.error[j];
}
}
jQuery("#searchresults").html(msg);
}
}
Datei anzeigen
Datei anzeigen
Datei anzeigen
Datei anzeigen
Datei anzeigen
Datei anzeigen