Created the new PHP branch
git-svn-id: https://rosehill.googlecode.com/svn/branches/php@2 100bd78a-fc82-11de-b5bc-ffd2847a4b57
This commit is contained in:
commit
eb914b54f9
|
@ -0,0 +1,661 @@
|
|||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
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
|
||||
them 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.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey 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;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If 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 convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero 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 that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
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.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
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.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
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
|
||||
state 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 Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,67 @@
|
|||
Copyright (C) 2006-2008 City of Bloomington, Indiana. All rights reserved.
|
||||
|
||||
This Scaffolding is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
|
||||
|
||||
This Scaffolding 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 scaffolding; if not, you can get a copy at:
|
||||
http://www.gnu.org/copyleft/gpl.html
|
||||
|
||||
Or, write to
|
||||
Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor
|
||||
Boston, MA 02110-1301, USA
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
Yahoo's YUI Javascript Toolkit
|
||||
---------------------------------------------------------------------
|
||||
This scaffolding includes an installation of the YUI Javascript Toolkit
|
||||
The YUI Toolkit is released under the BSD license
|
||||
|
||||
Software License Agreement (BSD License)
|
||||
Copyright (c) 2008, Yahoo! Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms, with or
|
||||
without modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
* Neither the name of Yahoo! Inc. nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without specific
|
||||
prior written permission of Yahoo! Inc.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
$ZEND_ACL = new Zend_Acl();
|
||||
/**
|
||||
* Load the roles from the database
|
||||
*/
|
||||
$roles = new RoleList();
|
||||
$roles->find();
|
||||
foreach ($roles as $role) {
|
||||
$ZEND_ACL = $ZEND_ACL->addRole(new Zend_Acl_Role($role->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare all the resources
|
||||
*/
|
||||
$ZEND_ACL->add(new Zend_Acl_Resource('Users'));
|
||||
$ZEND_ACL->add(new Zend_Acl_Resource('Deeds'));
|
||||
$ZEND_ACL->add(new Zend_Acl_Resource('Internments'));
|
||||
$ZEND_ACL->add(new Zend_Acl_Resource('Cemeteries'));
|
||||
|
||||
|
||||
/**
|
||||
* Assign permissions to the resources
|
||||
*/
|
||||
// Administrator is allowed access to everything
|
||||
$ZEND_ACL->allow('Administrator');
|
||||
|
||||
$ZEND_ACL->allow('Editor','Deeds');
|
||||
$ZEND_ACL->allow('Editor','Internments');
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
?>
|
||||
<h1>Add Deed</h1>
|
||||
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<fieldset><legend>Deed Info</legend>
|
||||
<table>
|
||||
|
||||
<tr><td><label for="deed-section">section</label></td>
|
||||
<td><input name="deed[section]" id="deed-section" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lot">lot</label></td>
|
||||
<td><input name="deed[lot]" id="deed-lot" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lastname1">lastname1</label></td>
|
||||
<td><input name="deed[lastname1]" id="deed-lastname1" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-firstname1">firstname1</label></td>
|
||||
<td><input name="deed[firstname1]" id="deed-firstname1" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-middleInitial1">middleInitial1</label></td>
|
||||
<td><input name="deed[middleInitial1]" id="deed-middleInitial1" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lastname2">lastname2</label></td>
|
||||
<td><input name="deed[lastname2]" id="deed-lastname2" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-firstname2">firstname2</label></td>
|
||||
<td><input name="deed[firstname2]" id="deed-firstname2" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-middleInitial2">middleInitial2</label></td>
|
||||
<td><input name="deed[middleInitial2]" id="deed-middleInitial2" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-issueDate-mon">issueDate</label></td>
|
||||
<td><select name="deed[issueDate][mon]" id="deed-issueDate-mon">
|
||||
<option></option>
|
||||
<?php
|
||||
$now = getdate();
|
||||
for ($i=1; $i<=12; $i++) {
|
||||
$selected = ($i==$now['mon']) ? 'selected="selected"' : '';
|
||||
echo "<option $selected>$i</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name="deed[issueDate][mday]">
|
||||
<option></option>
|
||||
<?php
|
||||
for ($i=1; $i<=31; $i++) {
|
||||
$selected = ($i==$now['mday']) ? 'selected="selected"' : '';
|
||||
echo "<option $selected>$i</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input name="deed[issueDate][year]" id="deed-issueDate-year" size="4" maxlength="4" value="<?php echo $now['year']; ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><label for="deed-notes">notes</label></td>
|
||||
<td><textarea name="deed[notes]" id="deed-notes" rows="3" cols="60"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lot2">lot2</label></td>
|
||||
<td><input name="deed[lot2]" id="deed-lot2" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-whiteoak">whiteoak</label></td>
|
||||
<td><input name="deed[whiteoak]" id="deed-whiteoak" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<button type="submit" class="submit">Submit</button>
|
||||
<button type="button" class="cancel" onclick="document.location.href='<?php echo BASE_URL; ?>/deeds';">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
?>
|
||||
<div class="interfaceBox">
|
||||
<h1>
|
||||
<?php
|
||||
if (userIsAllowed('Deeds')) {
|
||||
echo "
|
||||
<button type=\"button\" class=\"add\" onclick=\"document.location.href='".BASE_URL."/deeds/addDeed.php';\">
|
||||
Add
|
||||
</button>
|
||||
";
|
||||
}
|
||||
?>
|
||||
Deeds
|
||||
</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th></th>
|
||||
<th>Section, Lot</th>
|
||||
<th>Owner 1</th>
|
||||
<th>Owner 2</th>
|
||||
<th>Issue Date</th>
|
||||
<th>Cemetery</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach ($this->deedList as $deed) {
|
||||
$editButton = '';
|
||||
if (userIsAllowed('Deeds')) {
|
||||
$url = new URL(BASE_URL.'/deeds/updateDeed.php');
|
||||
$url->id = $deed->getId();
|
||||
$editButton = "
|
||||
<button type=\"button\" class=\"edit\" onclick=\"document.location.href='$url';\">
|
||||
Edit
|
||||
</button>
|
||||
";
|
||||
}
|
||||
$section = View::escape($deed->getSection());
|
||||
$lot = View::escape($deed->getLot());
|
||||
$owner1 = View::escape($deed->getOwner(1));
|
||||
$owner2 = View::escape($deed->getOwner(2));
|
||||
$date = $deed->getIssueDate('n/j/Y');
|
||||
echo "
|
||||
<tr><td>$editButton</td>
|
||||
<td>{$deed->getSection()}, {$deed->getLot()}</td>
|
||||
<td>
|
||||
";
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
?>
|
||||
<h1>Update Deed</h1>
|
||||
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<fieldset><legend>Deed Info</legend>
|
||||
<input name="id" type="hidden" value="<?php echo $this->deed->getId(); ?>" />
|
||||
<table>
|
||||
|
||||
<tr><td><label for="deed-section">section</label></td>
|
||||
<td><input name="deed[section]" id="deed-section" value="<?php echo $this->deed->getSection(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lot">lot</label></td>
|
||||
<td><input name="deed[lot]" id="deed-lot" value="<?php echo $this->deed->getLot(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lastname1">lastname1</label></td>
|
||||
<td><input name="deed[lastname1]" id="deed-lastname1" value="<?php echo $this->deed->getLastname1(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-firstname1">firstname1</label></td>
|
||||
<td><input name="deed[firstname1]" id="deed-firstname1" value="<?php echo $this->deed->getFirstname1(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-middleInitial1">middleInitial1</label></td>
|
||||
<td><input name="deed[middleInitial1]" id="deed-middleInitial1" value="<?php echo $this->deed->getMiddleInitial1(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lastname2">lastname2</label></td>
|
||||
<td><input name="deed[lastname2]" id="deed-lastname2" value="<?php echo $this->deed->getLastname2(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-firstname2">firstname2</label></td>
|
||||
<td><input name="deed[firstname2]" id="deed-firstname2" value="<?php echo $this->deed->getFirstname2(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-middleInitial2">middleInitial2</label></td>
|
||||
<td><input name="deed[middleInitial2]" id="deed-middleInitial2" value="<?php echo $this->deed->getMiddleInitial2(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-issueDate-mon">issueDate</label></td>
|
||||
<td><select name="deed[issueDate][mon]" id="deed-issueDate-mon">
|
||||
<option></option>
|
||||
<?php
|
||||
$issueDate = $this->deed->dateStringToArray($this->deed->getIssueDate());
|
||||
for ($i=1; $i<=12; $i++) {
|
||||
$selected = ($i==$issueDate['mon']) ? 'selected="selected"' : '';
|
||||
echo "<option $selected>$i</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name="deed[issueDate][mday]">
|
||||
<option></option>
|
||||
<?php
|
||||
for ($i=1; $i<=31; $i++) {
|
||||
$selected = ($i==$issueDate['mday']) ? 'selected="selected"' : '';
|
||||
echo "<option $selected>$i</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input name="deed[issueDate][year]" id="deed-issueDate-year" size="4" maxlength="4" value="<?php echo $issueDate['year']; ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><label for="deed-notes">notes</label></td>
|
||||
<td><textarea name="deed[notes]" id="deed-notes" rows="3" cols="60"><?php echo $this->deed->getNotes(); ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-lot2">lot2</label></td>
|
||||
<td><input name="deed[lot2]" id="deed-lot2" value="<?php echo $this->deed->getLot2(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="deed-whiteoak">whiteoak</label></td>
|
||||
<td><input name="deed[whiteoak]" id="deed-whiteoak" value="<?php echo $this->deed->getWhiteoak(); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<button type="submit" class="submit">Submit</button>
|
||||
<button type="button" class="cancel" onclick="document.location.href='<?php echo BASE_URL; ?>/deeds';">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2007,2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param array $this->errorMessages
|
||||
*/
|
||||
?>
|
||||
<div id="errorMessages">
|
||||
<h1>No That's wrong</h1>
|
||||
<?php
|
||||
foreach ($this->errorMessages as $e)
|
||||
{
|
||||
$error = $e->getMessage();
|
||||
if (file_exists(APPLICATION_HOME."/blocks/html/errorMessages/$error.inc"))
|
||||
{
|
||||
include APPLICATION_HOME."/blocks/html/errorMessages/$error.inc";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<p>$error</p>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
<p>You provided an invalid date.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>The username and password combination you entered is not correct.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>That username is not in LDAP. You cannot set LDAP authentication if the user is not in LDAP.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>You did not include all the required fields.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>Sorry, you're not allowed to go there.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>You are not logged into this site anymore.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>Your password is corrupted. Please contact a system administrator for help.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>That username is not in our system</p>
|
|
@ -0,0 +1 @@
|
|||
<p>You can only create user accounts for people who are already in the system, or are in LDAP.</p>
|
|
@ -0,0 +1 @@
|
|||
<p>The password you entered is not correct.</p>
|
|
@ -0,0 +1,15 @@
|
|||
<form method="post" action="<?php echo BASE_URL; ?>/login/login.php">
|
||||
<fieldset><legend>Login</legend>
|
||||
<input name="return_url" type="hidden" value="<?php echo View::escape($_SERVER['REQUEST_URI']); ?>" />
|
||||
<table>
|
||||
<tr><th><label for="username">Username:</label></th>
|
||||
<td><input name="username" id="username" /></td><td></td>
|
||||
</tr>
|
||||
<tr><th><label for="password">Password:</label></th>
|
||||
<td><input type="password" name="password" id="password" /></td>
|
||||
<td><button type="submit" class="login">Login</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
?>
|
||||
<h1>Add Person</h1>
|
||||
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<fieldset><legend>Personal Info</legend>
|
||||
<table>
|
||||
|
||||
<tr><td><label for="person-firstname" class="required">Firstname</label></td>
|
||||
<td><input name="person[firstname]" id="person-firstname" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="person-lastname" class="required">Lastname</label></td>
|
||||
<td><input name="person[lastname]" id="person-lastname" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="person-email">Email</label></td>
|
||||
<td><input name="person[email]" id="person-email" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<button type="submit" class="submit">Submit</button>
|
||||
<button type="button" class="cancel" onclick="document.location.href='<?php echo BASE_URL; ?>/people';">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param Person $this->person
|
||||
*/
|
||||
$username = $this->person->getUsername();
|
||||
if (!$username && userIsAllowed('Users')) {
|
||||
$url = BASE_URL.'/users/addUser.php?person_id='.$this->person->getId();
|
||||
$username = "
|
||||
<button type=\"button\" onclick=\"document.location.href='$url';\">
|
||||
Create Account
|
||||
</button>";
|
||||
}
|
||||
|
||||
|
||||
$name = View::escape($this->person->getFullname());
|
||||
echo "
|
||||
<h1>$name</h1>
|
||||
<table>
|
||||
<tr><th>Username</th>
|
||||
<td>$username</td>
|
||||
</tr>
|
||||
<tr><th>Email</th>
|
||||
<td>{$this->person->getEmail()}</td>
|
||||
</tr>
|
||||
</table>
|
||||
";
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param PersonList $this->personList
|
||||
*/
|
||||
?>
|
||||
<div class="interfaceBox">
|
||||
<h1><?php
|
||||
if (userIsAllowed('Users')) {
|
||||
echo "
|
||||
<button type=\"button\" class=\"add\" onclick=\"document.location.href='".BASE_URL."/people/addPerson.php';\">
|
||||
Add A Person
|
||||
</button>
|
||||
";
|
||||
}
|
||||
?>
|
||||
People
|
||||
</h1>
|
||||
<table>
|
||||
<?php
|
||||
foreach ($this->personList as $person) {
|
||||
$editButton = '';
|
||||
|
||||
if (userIsAllowed('Users')) {
|
||||
$editButton = "
|
||||
<button type=\"button\" class=\"edit\" onclick=\"document.location.href='".BASE_URL."/people/updatePerson.php?person_id={$person->getId()}';\">
|
||||
Edit
|
||||
</button>
|
||||
";
|
||||
|
||||
}
|
||||
|
||||
$name = View::escape($person->getFullname());
|
||||
echo "
|
||||
<tr><td>$editButton</td>
|
||||
<td>{$person->getUsername()}</td>
|
||||
<td><a href=\"{$person->getURL()}\">$name</a></td>
|
||||
<td>{$person->getEmail()}</td>
|
||||
</tr>
|
||||
";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param Person $this->person
|
||||
*/
|
||||
?>
|
||||
<h1>Update Person</h1>
|
||||
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<fieldset><legend>Person Info</legend>
|
||||
<input name="person_id" type="hidden" value="<?php echo $this->person->getId(); ?>" />
|
||||
<table>
|
||||
|
||||
<tr><td><label for="person-firstname" class="required">Firstname</label></td>
|
||||
<td><input name="person[firstname]" id="person-firstname" value="<?php echo View::escape($this->person->getFirstname()); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="person-lastname" class="required">Lastname</label></td>
|
||||
<td><input name="person[lastname]" id="person-lastname" value="<?php echo View::escape($this->person->getLastname()); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td><label for="person-email">Email</label></td>
|
||||
<td><input name="person[email]" id="person-email" value="<?php echo View::escape($this->person->getEmail()); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<button type="submit" class="submit">Submit</button>
|
||||
<button type="button" class="cancel" onclick="document.location.href='<?php echo BASE_URL; ?>/people';">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
?>
|
||||
<h1>New User Account</h1>
|
||||
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<fieldset><legend>Login Info</legend>
|
||||
<table>
|
||||
<tr><td><label for="user-authenticationMethod">Authentication</label></td>
|
||||
<td><select name="user[authenticationMethod]" id="user-authenticationMethod">
|
||||
<option <?php if(isset($_POST['user']['authenticationMethod']) && $_POST['user']['authenticationMethod']=="LDAP") echo "selected=\"selected\""; ?>>
|
||||
LDAP
|
||||
</option>
|
||||
<option <?php if(isset($_POST['user']['authenticationMethod']) && $_POST['user']['authenticationMethod']=="local") echo "selected=\"selected\""; ?>>
|
||||
local
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><label for="user-username">Username</label></td>
|
||||
<td><input name="user[username]" id="user-username" value="<?php if(isset($_POST['user']['username'])) echo View::escape($_POST['user']['username']); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><label for="user-password">Password</label></td>
|
||||
<td><input name="user[password]" id="user-password" /></td>
|
||||
</tr>
|
||||
<tr><td><label for="user[roles]">Roles</label></td>
|
||||
<td><select name="user[roles][]" id="user-roles" size="5" multiple="multiple">
|
||||
<?php
|
||||
$roles = new RoleList();
|
||||
$roles->find();
|
||||
foreach ($roles as $role) {
|
||||
$selected = (isset($_POST['user']['roles']) && in_array($role,$_POST['user']['roles']))
|
||||
? 'selected="selected"'
|
||||
: '';
|
||||
echo "<option $selected>$role</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<button type="submit" class="submit">Submit</button>
|
||||
<button type="button" class="cancel" onclick="document.location.href='<?php echo BASE_URL; ?>/users';">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param User $this->user
|
||||
*/
|
||||
?>
|
||||
<h1>Edit <?php echo $this->user->getUsername(); ?></h1>
|
||||
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<fieldset><legend>Login Info</legend>
|
||||
<input name="user_id" type="hidden" value="<?php echo $this->user->getId(); ?>" />
|
||||
<table>
|
||||
<tr><td><label for="user-authenticationMethod">Authentication</label></td>
|
||||
<td><select name="user[authenticationMethod]" id="user-authenticationMethod">
|
||||
<option <?php if ($this->user->getAuthenticationMethod()=='LDAP') echo "selected=\"selected\""; ?>>
|
||||
LDAP
|
||||
</option>
|
||||
<option <?php if ($this->user->getAuthenticationMethod()=='local') echo "selected=\"selected\""; ?>>
|
||||
local
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><label for="user-username">Username</label></td>
|
||||
<td><input name="user[username]" id="user-username" value="<?php echo View::escape($this->user->getUsername()); ?>" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><label for="user-password">Password</label></td>
|
||||
<td><input name="user[password]" id="user-password" /></td>
|
||||
</tr>
|
||||
<tr><td><label for="user-roles">Roles</label></td>
|
||||
<td><select name="user[roles][]" id="user-roles" size="5" multiple="multiple">
|
||||
<?php
|
||||
$roles = new RoleList();
|
||||
$roles->find();
|
||||
foreach ($roles as $role) {
|
||||
$selected = in_array($role,$this->user->getRoles())
|
||||
? 'selected="selected"'
|
||||
: '';
|
||||
echo "<option $selected>$role</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="submit" class="submit">Submit</button>
|
||||
<button type="button" class="cancel" onclick="document.location.href='<?php echo BASE_URL; ?>/users';">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2007-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param UserList $this->userList
|
||||
*/
|
||||
?>
|
||||
<div class="interfaceBox">
|
||||
<h1><?php
|
||||
if (userIsAllowed('Users')) {
|
||||
echo "
|
||||
<button type=\"button\" class=\"add\" onclick=\"document.location.href='".BASE_URL."/users/addUser.php';\">
|
||||
Add User Account
|
||||
</button>
|
||||
";
|
||||
}
|
||||
?>
|
||||
User Accounts
|
||||
</h1>
|
||||
<table>
|
||||
<?php
|
||||
foreach ($this->userList as $user) {
|
||||
$editButton = '';
|
||||
$deleteButton = '';
|
||||
if (userIsAllowed('Users')) {
|
||||
$editButton = "
|
||||
<button type=\"button\" class=\"edit\" onclick=\"document.location.href='".BASE_URL."/users/updateUser.php?user_id={$user->getId()}';\">
|
||||
Edit User Account
|
||||
</button>
|
||||
";
|
||||
|
||||
$deleteButton = "
|
||||
<button type=\"button\" class=\"delete\" onclick=\"document.location.href='".BASE_URL."/users/deleteUser.php?user_id={$user->getId()}';\">
|
||||
Delete User Account
|
||||
</button>
|
||||
";
|
||||
}
|
||||
|
||||
echo "
|
||||
<tr><td>$editButton</td>
|
||||
<td>{$user->getUsername()}</td>
|
||||
<td>{$user->getFirstname()} {$user->getLastname()}</td>
|
||||
<td>{$user->getAuthenticationMethod()}</td>
|
||||
<td>
|
||||
";
|
||||
foreach ($user->getRoles() as $role) {
|
||||
echo "$role ";
|
||||
}
|
||||
echo "
|
||||
</td>
|
||||
</tr>
|
||||
";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,380 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Deed
|
||||
{
|
||||
private $id;
|
||||
private $section;
|
||||
private $lot;
|
||||
private $lastname1;
|
||||
private $firstname1;
|
||||
private $middleInitial1;
|
||||
private $lastname2;
|
||||
private $firstname2;
|
||||
private $middleInitial2;
|
||||
private $issueDate;
|
||||
private $notes;
|
||||
private $lot2;
|
||||
private $whiteoak;
|
||||
|
||||
/**
|
||||
* Populates the object with data
|
||||
*
|
||||
* Passing in an associative array of data will populate this object without
|
||||
* hitting the database.
|
||||
*
|
||||
* Passing in a scalar will load the data from the database.
|
||||
* This will load all fields in the table as properties of this class.
|
||||
* You may want to replace this with, or add your own extra, custom loading
|
||||
*
|
||||
* @param int|array $id
|
||||
*/
|
||||
public function __construct($id=null)
|
||||
{
|
||||
if ($id) {
|
||||
if (is_array($id)) {
|
||||
$result = $id;
|
||||
}
|
||||
else {
|
||||
$zend_db = Database::getConnection();
|
||||
$sql = 'select * from deeds where id=?';
|
||||
$result = $zend_db->fetchRow($sql,array($id));
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
foreach ($result as $field=>$value) {
|
||||
if ($value) {
|
||||
if ($field == 'issueDate') {
|
||||
$value = (false === strpos($value,'0000')) ? new Date($value) : null;
|
||||
}
|
||||
$this->$field = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception('deeds/unknownDeed');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is where the code goes to generate a new, empty instance.
|
||||
// Set any default values for properties that need it here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if anything's wrong
|
||||
* @throws Exception $e
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
// Check for required fields here. Throw an exception if anything is missing.
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this record back to the database
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$data = array();
|
||||
$data['section'] = $this->section ? $this->section : null;
|
||||
$data['lot'] = $this->lot ? $this->lot : null;
|
||||
$data['lastname1'] = $this->lastname1 ? $this->lastname1 : null;
|
||||
$data['firstname1'] = $this->firstname1 ? $this->firstname1 : null;
|
||||
$data['middleInitial1'] = $this->middleInitial1 ? $this->middleInitial1 : null;
|
||||
$data['lastname2'] = $this->lastname2 ? $this->lastname2 : null;
|
||||
$data['firstname2'] = $this->firstname2 ? $this->firstname2 : null;
|
||||
$data['middleInitial2'] = $this->middleInitial2 ? $this->middleInitial2 : null;
|
||||
$data['issueDate'] = $this->issueDate ? $this->issueDate->format('Y-m-d') : null;
|
||||
$data['notes'] = $this->notes ? $this->notes : null;
|
||||
$data['lot2'] = $this->lot2 ? $this->lot2 : null;
|
||||
$data['whiteoak'] = $this->whiteoak ? $this->whiteoak : null;
|
||||
|
||||
if ($this->id) {
|
||||
$this->update($data);
|
||||
}
|
||||
else {
|
||||
$this->insert($data);
|
||||
}
|
||||
}
|
||||
|
||||
private function update($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->update('deeds',$data,"id='{$this->id}'");
|
||||
}
|
||||
|
||||
private function insert($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->insert('deeds',$data);
|
||||
$this->id = $zend_db->lastInsertId('deeds','id');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Getters
|
||||
//----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSection()
|
||||
{
|
||||
return $this->section;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLot()
|
||||
{
|
||||
return $this->lot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastname1()
|
||||
{
|
||||
return $this->lastname1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstname1()
|
||||
{
|
||||
return $this->firstname1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return char
|
||||
*/
|
||||
public function getMiddleInitial1()
|
||||
{
|
||||
return $this->middleInitial1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastname2()
|
||||
{
|
||||
return $this->lastname2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstname2()
|
||||
{
|
||||
return $this->firstname2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return char
|
||||
*/
|
||||
public function getMiddleInitial2()
|
||||
{
|
||||
return $this->middleInitial2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date/time in the desired format
|
||||
*
|
||||
* Format is specified using PHP's date() syntax
|
||||
* http://www.php.net/manual/en/function.date.php
|
||||
* If no format is given, the Date object is returned
|
||||
*
|
||||
* @param string $format
|
||||
* @return string|DateTime
|
||||
*/
|
||||
public function getIssueDate($format=null)
|
||||
{
|
||||
if ($format && $this->issueDate) {
|
||||
return $this->issueDate->format($format);
|
||||
}
|
||||
else {
|
||||
return $this->issueDate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return text
|
||||
*/
|
||||
public function getNotes()
|
||||
{
|
||||
return $this->notes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return char
|
||||
*/
|
||||
public function getLot2()
|
||||
{
|
||||
return $this->lot2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return char
|
||||
*/
|
||||
public function getWhiteoak()
|
||||
{
|
||||
return $this->whiteoak;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Setters
|
||||
//----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setSection($string)
|
||||
{
|
||||
$this->section = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLot($string)
|
||||
{
|
||||
$this->lot = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLastname1($string)
|
||||
{
|
||||
$this->lastname1 = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setFirstname1($string)
|
||||
{
|
||||
$this->firstname1 = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char $char
|
||||
*/
|
||||
public function setMiddleInitial1($char)
|
||||
{
|
||||
$this->middleInitial1 = $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLastname2($string)
|
||||
{
|
||||
$this->lastname2 = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setFirstname2($string)
|
||||
{
|
||||
$this->firstname2 = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char $char
|
||||
*/
|
||||
public function setMiddleInitial2($char)
|
||||
{
|
||||
$this->middleInitial2 = $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the date
|
||||
*
|
||||
* Date arrays should match arrays produced by getdate()
|
||||
*
|
||||
* Date string formats should be in something strtotime() understands
|
||||
* http://www.php.net/manual/en/function.strtotime.php
|
||||
*
|
||||
* @param int|string|array $date
|
||||
*/
|
||||
public function setIssueDate($date)
|
||||
{
|
||||
if ($date) {
|
||||
$this->issueDate = new Date($date);
|
||||
}
|
||||
else {
|
||||
$this->issueDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param text $text
|
||||
*/
|
||||
public function setNotes($text)
|
||||
{
|
||||
$this->notes = $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char $char
|
||||
*/
|
||||
public function setLot2($char)
|
||||
{
|
||||
$this->lot2 = $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char $char
|
||||
*/
|
||||
public function setWhiteoak($char)
|
||||
{
|
||||
$this->whiteoak = $char;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Custom Functions
|
||||
// We recommend adding all your custom code down here at the bottom
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* Returns the full name of the owner
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOwner($number=1)
|
||||
{
|
||||
$first = "firstname$number";
|
||||
$middle = "middleInitial$number";
|
||||
$last = "lastname$number";
|
||||
|
||||
$name = array();
|
||||
if ($this->$first) {
|
||||
$name[] = $this->$first;
|
||||
}
|
||||
if ($this->$middle) {
|
||||
$name[] = $this->$middle;
|
||||
}
|
||||
if ($this->$last) {
|
||||
$name[] = $this->$last;
|
||||
}
|
||||
|
||||
return implode(' ',$name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* A collection class for Deed objects
|
||||
*
|
||||
* This class creates a zend_db select statement.
|
||||
* ZendDbResultIterator handles iterating and paginating those results.
|
||||
* As the results are iterated over, ZendDbResultIterator will pass each desired
|
||||
* row back to this class's loadResult() which will be responsible for hydrating
|
||||
* each Deed object
|
||||
*
|
||||
* Beyond the basic $fields handled, you will need to write your own handling
|
||||
* of whatever extra $fields you need
|
||||
*/
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class DeedList extends ZendDbResultIterator
|
||||
{
|
||||
/**
|
||||
* Creates a basic select statement for the collection.
|
||||
*
|
||||
* Populates the collection if you pass in $fields
|
||||
* Setting itemsPerPage turns on pagination mode
|
||||
* In pagination mode, this will only load the results for one page
|
||||
*
|
||||
* @param array $fields
|
||||
* @param int $itemsPerPage Turns on Pagination
|
||||
* @param int $currentPage
|
||||
*/
|
||||
public function __construct($fields=null,$itemsPerPage=null,$currentPage=null)
|
||||
{
|
||||
parent::__construct($itemsPerPage,$currentPage);
|
||||
if (is_array($fields)) {
|
||||
$this->find($fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection
|
||||
*
|
||||
* @param array $fields
|
||||
* @param string|array $order Multi-column sort should be given as an array
|
||||
* @param int $limit
|
||||
* @param string|array $groupBy Multi-column group by should be given as an array
|
||||
*/
|
||||
public function find($fields=null,$order='id',$limit=null,$groupBy=null)
|
||||
{
|
||||
$this->select->from('deeds');
|
||||
|
||||
// Finding on fields from the deed table is handled here
|
||||
if (count($fields)) {
|
||||
foreach ($fields as $key=>$value) {
|
||||
$this->select->where("$key=?",$value);
|
||||
}
|
||||
}
|
||||
|
||||
// Finding on fields from other tables requires joining those tables.
|
||||
// You can handle fields from other tables by adding the joins here
|
||||
// If you add more joins you probably want to make sure that the
|
||||
// above foreach only handles fields from the deed table.
|
||||
|
||||
$this->select->order($order);
|
||||
if ($limit) {
|
||||
$this->select->limit($limit);
|
||||
}
|
||||
if ($groupBy) {
|
||||
$this->select->group($groupBy);
|
||||
}
|
||||
$this->populateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates all the Deed objects from a database result set
|
||||
*
|
||||
* This is a callback function, called from ZendDbResultIterator. It is
|
||||
* called once per row of the result.
|
||||
*
|
||||
* @param int $key The index of the result row to load
|
||||
* @return Deed
|
||||
*/
|
||||
protected function loadResult($key)
|
||||
{
|
||||
return new Deed($this->result[$key]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,410 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Internment
|
||||
{
|
||||
private $id;
|
||||
private $section;
|
||||
private $lot;
|
||||
private $book;
|
||||
private $pageNumber;
|
||||
private $deceasedDate;
|
||||
private $lastname;
|
||||
private $firstname;
|
||||
private $middleInitial;
|
||||
private $birthPlace;
|
||||
private $lastResidence;
|
||||
private $age;
|
||||
private $sex;
|
||||
private $whiteoak;
|
||||
private $notes;
|
||||
private $lot2;
|
||||
|
||||
/**
|
||||
* Populates the object with data
|
||||
*
|
||||
* Passing in an associative array of data will populate this object without
|
||||
* hitting the database.
|
||||
*
|
||||
* Passing in a scalar will load the data from the database.
|
||||
* This will load all fields in the table as properties of this class.
|
||||
* You may want to replace this with, or add your own extra, custom loading
|
||||
*
|
||||
* @param int|array $id
|
||||
*/
|
||||
public function __construct($id=null)
|
||||
{
|
||||
if ($id) {
|
||||
if (is_array($id)) {
|
||||
$result = $id;
|
||||
}
|
||||
else {
|
||||
$zend_db = Database::getConnection();
|
||||
$sql = 'select * from internments where id=?';
|
||||
$result = $zend_db->fetchRow($sql,array($id));
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
foreach ($result as $field=>$value) {
|
||||
if ($value) {
|
||||
if ($field == 'deceasedDate') {
|
||||
$value = (false === strpos($value,'0000')) ? new Date($value) : null;
|
||||
}
|
||||
$this->$field = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception('internments/unknownInternment');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is where the code goes to generate a new, empty instance.
|
||||
// Set any default values for properties that need it here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if anything's wrong
|
||||
* @throws Exception $e
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
// Check for required fields here. Throw an exception if anything is missing.
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this record back to the database
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$data = array();
|
||||
$data['section'] = $this->section ? $this->section : null;
|
||||
$data['lot'] = $this->lot ? $this->lot : null;
|
||||
$data['book'] = $this->book ? $this->book : null;
|
||||
$data['pageNumber'] = $this->pageNumber ? $this->pageNumber : null;
|
||||
$data['deceasedDate'] = $this->deceasedDate ? $this->deceasedDate->format('Y-m-d') : null;
|
||||
$data['lastname'] = $this->lastname ? $this->lastname : null;
|
||||
$data['firstname'] = $this->firstname ? $this->firstname : null;
|
||||
$data['middleInitial'] = $this->middleInitial ? $this->middleInitial : null;
|
||||
$data['birthPlace'] = $this->birthPlace ? $this->birthPlace : null;
|
||||
$data['lastResidence'] = $this->lastResidence ? $this->lastResidence : null;
|
||||
$data['age'] = $this->age ? $this->age : null;
|
||||
$data['sex'] = $this->sex ? $this->sex : null;
|
||||
$data['whiteoak'] = $this->whiteoak ? $this->whiteoak : null;
|
||||
$data['notes'] = $this->notes ? $this->notes : null;
|
||||
$data['lot2'] = $this->lot2 ? $this->lot2 : null;
|
||||
|
||||
if ($this->id) {
|
||||
$this->update($data);
|
||||
}
|
||||
else {
|
||||
$this->insert($data);
|
||||
}
|
||||
}
|
||||
|
||||
private function update($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->update('internments',$data,"id='{$this->id}'");
|
||||
}
|
||||
|
||||
private function insert($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->insert('internments',$data);
|
||||
$this->id = $zend_db->lastInsertId('internments','id');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Getters
|
||||
//----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSection()
|
||||
{
|
||||
return $this->section;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLot()
|
||||
{
|
||||
return $this->lot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBook()
|
||||
{
|
||||
return $this->book;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPageNumber()
|
||||
{
|
||||
return $this->pageNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date/time in the desired format
|
||||
*
|
||||
* Format is specified using PHP's date() syntax
|
||||
* http://www.php.net/manual/en/function.date.php
|
||||
* If no format is given, the Date object is returned
|
||||
*
|
||||
* @param string $format
|
||||
* @return string|DateTime
|
||||
*/
|
||||
public function getDeceasedDate($format=null)
|
||||
{
|
||||
if ($format && $this->deceasedDate) {
|
||||
return $this->deceasedDate->format($format);
|
||||
}
|
||||
else {
|
||||
return $this->deceasedDate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
return $this->lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
return $this->firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return char
|
||||
*/
|
||||
public function getMiddleInitial()
|
||||
{
|
||||
return $this->middleInitial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBirthPlace()
|
||||
{
|
||||
return $this->birthPlace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastResidence()
|
||||
{
|
||||
return $this->lastResidence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getAge()
|
||||
{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSex()
|
||||
{
|
||||
return $this->sex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return char
|
||||
*/
|
||||
public function getWhiteoak()
|
||||
{
|
||||
return $this->whiteoak;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return text
|
||||
*/
|
||||
public function getNotes()
|
||||
{
|
||||
return $this->notes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLot2()
|
||||
{
|
||||
return $this->lot2;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Setters
|
||||
//----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setSection($string)
|
||||
{
|
||||
$this->section = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLot($string)
|
||||
{
|
||||
$this->lot = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setBook($string)
|
||||
{
|
||||
$this->book = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setPageNumber($string)
|
||||
{
|
||||
$this->pageNumber = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the date
|
||||
*
|
||||
* Date arrays should match arrays produced by getdate()
|
||||
*
|
||||
* Date string formats should be in something strtotime() understands
|
||||
* http://www.php.net/manual/en/function.strtotime.php
|
||||
*
|
||||
* @param int|string|array $date
|
||||
*/
|
||||
public function setDeceasedDate($date)
|
||||
{
|
||||
if ($date) {
|
||||
$this->deceasedDate = new Date($date);
|
||||
}
|
||||
else {
|
||||
$this->deceasedDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLastname($string)
|
||||
{
|
||||
$this->lastname = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setFirstname($string)
|
||||
{
|
||||
$this->firstname = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char $char
|
||||
*/
|
||||
public function setMiddleInitial($char)
|
||||
{
|
||||
$this->middleInitial = $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setBirthPlace($string)
|
||||
{
|
||||
$this->birthPlace = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLastResidence($string)
|
||||
{
|
||||
$this->lastResidence = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $int
|
||||
*/
|
||||
public function setAge($int)
|
||||
{
|
||||
$this->age = preg_replace("/[^0-9]/","",$int);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setSex($string)
|
||||
{
|
||||
$this->sex = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char $char
|
||||
*/
|
||||
public function setWhiteoak($char)
|
||||
{
|
||||
$this->whiteoak = $char;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param text $text
|
||||
*/
|
||||
public function setNotes($text)
|
||||
{
|
||||
$this->notes = $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLot2($string)
|
||||
{
|
||||
$this->lot2 = trim($string);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Custom Functions
|
||||
// We recommend adding all your custom code down here at the bottom
|
||||
//----------------------------------------------------------------
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* A collection class for Internment objects
|
||||
*
|
||||
* This class creates a zend_db select statement.
|
||||
* ZendDbResultIterator handles iterating and paginating those results.
|
||||
* As the results are iterated over, ZendDbResultIterator will pass each desired
|
||||
* row back to this class's loadResult() which will be responsible for hydrating
|
||||
* each Internment object
|
||||
*
|
||||
* Beyond the basic $fields handled, you will need to write your own handling
|
||||
* of whatever extra $fields you need
|
||||
*/
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class InternmentList extends ZendDbResultIterator
|
||||
{
|
||||
/**
|
||||
* Creates a basic select statement for the collection.
|
||||
*
|
||||
* Populates the collection if you pass in $fields
|
||||
* Setting itemsPerPage turns on pagination mode
|
||||
* In pagination mode, this will only load the results for one page
|
||||
*
|
||||
* @param array $fields
|
||||
* @param int $itemsPerPage Turns on Pagination
|
||||
* @param int $currentPage
|
||||
*/
|
||||
public function __construct($fields=null,$itemsPerPage=null,$currentPage=null)
|
||||
{
|
||||
parent::__construct($itemsPerPage,$currentPage);
|
||||
if (is_array($fields)) {
|
||||
$this->find($fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection
|
||||
*
|
||||
* @param array $fields
|
||||
* @param string|array $order Multi-column sort should be given as an array
|
||||
* @param int $limit
|
||||
* @param string|array $groupBy Multi-column group by should be given as an array
|
||||
*/
|
||||
public function find($fields=null,$order='id',$limit=null,$groupBy=null)
|
||||
{
|
||||
$this->select->from('internments');
|
||||
|
||||
// Finding on fields from the internment table is handled here
|
||||
if (count($fields)) {
|
||||
foreach ($fields as $key=>$value) {
|
||||
$this->select->where("$key=?",$value);
|
||||
}
|
||||
}
|
||||
|
||||
// Finding on fields from other tables requires joining those tables.
|
||||
// You can handle fields from other tables by adding the joins here
|
||||
// If you add more joins you probably want to make sure that the
|
||||
// above foreach only handles fields from the internment table.
|
||||
|
||||
$this->select->order($order);
|
||||
if ($limit) {
|
||||
$this->select->limit($limit);
|
||||
}
|
||||
if ($groupBy) {
|
||||
$this->select->group($groupBy);
|
||||
}
|
||||
$this->populateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates all the Internment objects from a database result set
|
||||
*
|
||||
* This is a callback function, called from ZendDbResultIterator. It is
|
||||
* called once per row of the result.
|
||||
*
|
||||
* @param int $key The index of the result row to load
|
||||
* @return Internment
|
||||
*/
|
||||
protected function loadResult($key)
|
||||
{
|
||||
return new Internment($this->result[$key]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,226 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Person
|
||||
{
|
||||
private $id;
|
||||
private $firstname;
|
||||
private $lastname;
|
||||
private $email;
|
||||
|
||||
private $user_id;
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Populates the object with data
|
||||
*
|
||||
* Passing in an associative array of data will populate this object without
|
||||
* hitting the database.
|
||||
*
|
||||
* Passing in a scalar will load the data from the database.
|
||||
* This will load all fields in the table as properties of this class.
|
||||
* You may want to replace this with, or add your own extra, custom loading
|
||||
*
|
||||
* @param int|string|array $id (ID, email, username)
|
||||
*/
|
||||
public function __construct($id=null)
|
||||
{
|
||||
if ($id) {
|
||||
if (is_array($id)) {
|
||||
$result = $id;
|
||||
}
|
||||
else {
|
||||
$zend_db = Database::getConnection();
|
||||
if (ctype_digit($id)) {
|
||||
$sql = 'select * from people where id=?';
|
||||
}
|
||||
elseif (false !== strpos($id,'@')) {
|
||||
$sql = 'select * from people where email=?';
|
||||
}
|
||||
else {
|
||||
$sql = 'select p.* from people p left join users on p.id=person_id where username=?';
|
||||
}
|
||||
$result = $zend_db->fetchRow($sql,array($id));
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
foreach ($result as $field=>$value) {
|
||||
if ($value) {
|
||||
$this->$field = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception('people/unknownPerson');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is where the code goes to generate a new, empty instance.
|
||||
// Set any default values for properties that need it here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if anything's wrong
|
||||
* @throws Exception $e
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
// Check for required fields here. Throw an exception if anything is missing.
|
||||
if (!$this->firstname || !$this->lastname) {
|
||||
throw new Exception('missingRequiredFields');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this record back to the database
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$data = array();
|
||||
$data['firstname'] = $this->firstname;
|
||||
$data['lastname'] = $this->lastname;
|
||||
$data['email'] = $this->email ? $this->email : null;
|
||||
|
||||
if ($this->id) {
|
||||
$this->update($data);
|
||||
}
|
||||
else {
|
||||
$this->insert($data);
|
||||
}
|
||||
}
|
||||
|
||||
private function update($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->update('people',$data,"id={$this->id}");
|
||||
}
|
||||
|
||||
private function insert($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->insert('people',$data);
|
||||
$this->id = $zend_db->lastInsertId('people','id');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Getters
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
return $this->firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
return $this->lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Setters
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setFirstname($string)
|
||||
{
|
||||
$this->firstname = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLastname($string)
|
||||
{
|
||||
$this->lastname = trim($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setEmail($string)
|
||||
{
|
||||
$this->email = trim($string);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Custom Functions
|
||||
// We recommend adding all your custom code down here at the bottom
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFullname()
|
||||
{
|
||||
return "{$this->firstname} {$this->lastname}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getURL()
|
||||
{
|
||||
return BASE_URL.'/people/viewPerson.php?person_id='.$this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getUser_id()
|
||||
{
|
||||
if (!$this->user_id) {
|
||||
$zend_db = Database::getConnection();
|
||||
$this->user_id = $zend_db->fetchOne('select id from users where person_id=?',$this->id);
|
||||
}
|
||||
return $this->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function getUser() {
|
||||
if (!$this->user) {
|
||||
if ($this->getUser_id()) {
|
||||
$this->user = new User($this->getUser_id());
|
||||
}
|
||||
}
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername() {
|
||||
if ($this->getUser()) {
|
||||
return $this->getUser()->getUsername();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* A collection class for Person objects
|
||||
*
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class PersonList extends ZendDbResultIterator
|
||||
{
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct($fields=null)
|
||||
{
|
||||
parent::__construct();
|
||||
if (is_array($fields)) {
|
||||
$this->find($fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection
|
||||
*
|
||||
* @param array $fields
|
||||
* @param string|array $order Multi-column sort should be given as an array
|
||||
* @param int $limit
|
||||
* @param string|array $groupBy Multi-column group by should be given as an array
|
||||
*/
|
||||
public function find($fields=null,$order='lastname',$limit=null,$groupBy=null)
|
||||
{
|
||||
$this->select->from('people');
|
||||
|
||||
if (count($fields)) {
|
||||
foreach ($fields as $key=>$value) {
|
||||
$this->select->where("$key=?",$value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->select->order($order);
|
||||
if ($limit) {
|
||||
$this->select->limit($limit);
|
||||
}
|
||||
if ($groupBy) {
|
||||
$this->select->group($groupBy);
|
||||
}
|
||||
$this->populateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a single Person object for the row returned from ZendDbResultIterator
|
||||
*
|
||||
* @param array $key
|
||||
*/
|
||||
protected function loadResult($key)
|
||||
{
|
||||
return new Person($this->result[$key]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Role
|
||||
{
|
||||
private $id;
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Passing in an associative array of data will populate this object without
|
||||
* hitting the database.
|
||||
*
|
||||
* Passing in an int will load the data from the database for the given ID.
|
||||
*
|
||||
* This will load all fields in the table as properties of this class.
|
||||
* You may want to replace this with, or add your own extra, custom loading
|
||||
*
|
||||
* @param int|string|array $id
|
||||
*/
|
||||
public function __construct($id=null)
|
||||
{
|
||||
if ($id) {
|
||||
if (is_array($id)) {
|
||||
$result = $id;
|
||||
}
|
||||
else {
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
if (is_int($id) || ctype_digit($id)) {
|
||||
$sql = 'select * from roles where id=?';
|
||||
}
|
||||
else {
|
||||
$sql = 'select * from roles where name=?';
|
||||
}
|
||||
$result = $zend_db->fetchRow($sql,array($id));
|
||||
}
|
||||
if ($result) {
|
||||
foreach ($result as $field=>$value) {
|
||||
if ($value) {
|
||||
$this->$field = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception('roles/unknownRole');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is where the code goes to generate a new, empty instance.
|
||||
// Set any default values for properties that need it here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if theres anything wrong
|
||||
* @throws Exception
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
if (!$this->name) {
|
||||
throw new Exception('missingName');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This generates generic SQL that should work right away.
|
||||
* You can replace this $fields code with your own custom SQL
|
||||
* for each property of this class,
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$data = array();
|
||||
$data['name'] = $this->name;
|
||||
|
||||
|
||||
if ($this->id) {
|
||||
$this->update($data);
|
||||
}
|
||||
else {
|
||||
$this->insert($data);
|
||||
}
|
||||
}
|
||||
|
||||
private function update($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->update('roles',$data,"id={$this->id}");
|
||||
}
|
||||
|
||||
private function insert($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->insert('roles',$data);
|
||||
$this->id = $zend_db->lastInsertId('roles','id');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Getters
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Setters
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setName($string)
|
||||
{
|
||||
$this->name = trim($string);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Custom Functions
|
||||
// We recommend adding all your custom code down here at the bottom
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class RoleList extends ZendDbResultIterator
|
||||
{
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct($fields=null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if (is_array($fields)) {
|
||||
$this->find($fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection
|
||||
*
|
||||
* @param array $fields
|
||||
* @param string|array $order Multi-column sort should be given as an array
|
||||
* @param int $limit
|
||||
* @param string|array $groupBy Multi-column group by should be given as an array
|
||||
*/
|
||||
public function find($fields=null,$order='name',$limit=null,$groupBy=null)
|
||||
{
|
||||
$this->select->from('roles');
|
||||
|
||||
if (count($fields)) {
|
||||
foreach ($fields as $key=>$value) {
|
||||
$this->select->where("$key=?",$value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->select->order($order);
|
||||
if ($limit) {
|
||||
$this->select->limit($limit);
|
||||
}
|
||||
if ($groupBy) {
|
||||
$this->select->group($groupBy);
|
||||
}
|
||||
$this->populateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load each Role object as we iterate through the results
|
||||
*
|
||||
* @return array An array of Role objects
|
||||
*/
|
||||
protected function loadResult($key)
|
||||
{
|
||||
return new Role($this->result[$key]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,373 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class User extends SystemUser
|
||||
{
|
||||
private $id;
|
||||
private $person_id;
|
||||
private $username;
|
||||
private $password;
|
||||
private $authenticationMethod;
|
||||
|
||||
private $person;
|
||||
private $roles = array();
|
||||
private $newPassword; // the User's new password, unencrypted
|
||||
|
||||
/**
|
||||
* @param int|string $id
|
||||
*/
|
||||
public function __construct($id = null)
|
||||
{
|
||||
if ($id) {
|
||||
if (is_array($id)) {
|
||||
$result = $id;
|
||||
}
|
||||
else {
|
||||
if (ctype_digit($id)) {
|
||||
$sql = 'select * from users where id=?';
|
||||
}
|
||||
else {
|
||||
$sql = 'select * from users where username=?';
|
||||
}
|
||||
$zend_db = Database::getConnection();
|
||||
$result = $zend_db->fetchRow($sql,array($id));
|
||||
}
|
||||
if ($result) {
|
||||
foreach ($result as $field=>$value) {
|
||||
if ($value) {
|
||||
$this->$field = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception('users/unknownUser');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is where the code goes to generate a new, empty instance.
|
||||
// Set any default values for properties that need it here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if anything's wrong
|
||||
* @throws Exception $e
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
if (!$this->person_id) {
|
||||
throw new Exception('users/missingPerson_id');
|
||||
}
|
||||
if (!$this->username) {
|
||||
throw new Exception('users/missingUsername');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this record back to the database
|
||||
*
|
||||
* This generates generic SQL that should work right away.
|
||||
* You can replace this $fields code with your own custom SQL
|
||||
* for each property of this class,
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$data = array();
|
||||
$data['person_id'] = $this->person_id;
|
||||
$data['username'] = $this->username;
|
||||
// Passwords should not be updated by default. Use the savePassword() function
|
||||
$data['authenticationMethod'] = $this->authenticationMethod
|
||||
? $this->authenticationMethod
|
||||
: null;
|
||||
|
||||
// Do the database calls
|
||||
if ($this->id) {
|
||||
$this->update($data);
|
||||
}
|
||||
else {
|
||||
$this->insert($data);
|
||||
}
|
||||
|
||||
// Save the password only if it's changed
|
||||
if ($this->passwordHasChanged()) {
|
||||
$this->savePassword();
|
||||
}
|
||||
|
||||
$this->updateRoles();
|
||||
}
|
||||
|
||||
private function update($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->update('users',$data,"id={$this->id}");
|
||||
}
|
||||
|
||||
private function insert($data)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->insert('users',$data);
|
||||
$this->id = $zend_db->lastInsertId('users','id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes this object from the database
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
$zend_db->delete('user_roles',"user_id={$this->id}");
|
||||
$zend_db->delete('users',"id={$this->id}");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Getters
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPerson_id()
|
||||
{
|
||||
return $this->person_id;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthenticationMethod()
|
||||
{
|
||||
return $this->authenticationMethod;
|
||||
}
|
||||
/**
|
||||
* @return Person
|
||||
*/
|
||||
public function getPerson()
|
||||
{
|
||||
if ($this->person_id) {
|
||||
if (!$this->person) {
|
||||
$this->person = new Person($this->person_id);
|
||||
}
|
||||
return $this->person;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Setters
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @param int $int
|
||||
*/
|
||||
public function setPerson_id($int)
|
||||
{
|
||||
$this->person = new Person($int);
|
||||
$this->person_id = $int;
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setUsername($string)
|
||||
{
|
||||
$this->username = trim($string);
|
||||
}
|
||||
/**
|
||||
* Takes a user-given password and converts it to an MD5 Hash
|
||||
* @param String $string
|
||||
*/
|
||||
public function setPassword($string)
|
||||
{
|
||||
// Save the user given password, so we can update it externally, if needed
|
||||
$this->newPassword = trim($string);
|
||||
$this->password = md5(trim($string));
|
||||
}
|
||||
/**
|
||||
* Takes a pre-existing MD5 hash
|
||||
* @param MD5 $hash
|
||||
*/
|
||||
public function setPasswordHash($hash)
|
||||
{
|
||||
$this->password = trim($hash);
|
||||
}
|
||||
/**
|
||||
* @param string $authenticationMethod
|
||||
*/
|
||||
public function setAuthenticationMethod($string)
|
||||
{
|
||||
$this->authenticationMethod = $string;
|
||||
if ($this->authenticationMethod != 'local') {
|
||||
$this->password = null;
|
||||
$this->saveLocalPassword();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param Person $person
|
||||
*/
|
||||
public function setPerson($person)
|
||||
{
|
||||
$this->person_id = $person->getId();
|
||||
$this->person = $person;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Custom Functions
|
||||
// We recommend adding all your custom code down here at the bottom
|
||||
//----------------------------------------------------------------
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
return $this->getPerson()->getFirstname();
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
return $this->getPerson()->getLastname();
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->getPerson()->getEmail();
|
||||
}
|
||||
/**
|
||||
* Returns an array of Role names with the role id as the array index
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRoles()
|
||||
{
|
||||
if (!count($this->roles)) {
|
||||
if ($this->id) {
|
||||
$zend_db = Database::getConnection();
|
||||
$select = new Zend_Db_Select($zend_db);
|
||||
$select->from('user_roles','role_id')
|
||||
->joinLeft('roles','role_id=id','name')
|
||||
->where('user_id=?');
|
||||
$result = $zend_db->fetchAll($select,$this->id);
|
||||
|
||||
foreach ($result as $row) {
|
||||
$this->roles[$row['role_id']] = $row['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->roles;
|
||||
}
|
||||
/**
|
||||
* Takes an array of role names. Loads the Roles from the database
|
||||
*
|
||||
* @param array $roleNames An array of names
|
||||
*/
|
||||
public function setRoles($roleNames)
|
||||
{
|
||||
$this->roles = array();
|
||||
foreach ($roleNames as $name) {
|
||||
$role = new Role($name);
|
||||
$this->roles[$role->getId()] = $role->getName();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Takes a string or an array of strings and checks if the user has that role
|
||||
*
|
||||
* @param Array|String $roles
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasRole($roles)
|
||||
{
|
||||
if (is_array($roles)) {
|
||||
foreach ($roles as $roleName) {
|
||||
if (in_array($roleName,$this->getRoles())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return in_array($roles,$this->getRoles());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current roles back to the database
|
||||
*/
|
||||
private function updateRoles()
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
$roles = $this->getRoles();
|
||||
|
||||
$zend_db->delete('user_roles',"user_id={$this->id}");
|
||||
|
||||
foreach ($roles as $id=>$name) {
|
||||
$data = array('user_id'=>$this->id,'role_id'=>$id);
|
||||
$zend_db->insert('user_roles',$data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Since passwords can be stored externally, we only want to bother trying
|
||||
* to save them when they've actually changed
|
||||
* @return boolean
|
||||
*/
|
||||
public function passwordHasChanged()
|
||||
{
|
||||
return $this->newPassword ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function from the SystemUser class
|
||||
* The SystemUser will determine where the password should be stored.
|
||||
* If the password is stored locally, it will call this function
|
||||
*/
|
||||
protected function saveLocalPassword()
|
||||
{
|
||||
if ($this->id) {
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
// Passwords in the class should already be MD5 hashed
|
||||
$zend_db->update('users',array('password'=>$this->password),"id={$this->id}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function from the SystemUser class
|
||||
*
|
||||
* The SystemUser class will determine where the authentication
|
||||
* should occur. If the user should be authenticated locally,
|
||||
* this function will be called.
|
||||
*
|
||||
* @param string $password
|
||||
* @return boolean
|
||||
*/
|
||||
protected function authenticateDatabase($password)
|
||||
{
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
$md5 = md5($password);
|
||||
|
||||
$id = $zend_db->fetchOne('select id from users where username=? and password=?',
|
||||
array($this->username,$md5));
|
||||
return $id ? true : false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
/**
|
||||
* A collection class for User objects
|
||||
*
|
||||
* This class creates a zend_db select statement.
|
||||
* ZendDbResultIterator handles iterating and paginating those results.
|
||||
* As the results are iterated over, ZendDbResultIterator will pass each desired
|
||||
* row back to this class's loadResult() which will be responsible for hydrating
|
||||
* each User object
|
||||
*
|
||||
* Beyond the basic $fields handled, you will need to write your own handling
|
||||
* of whatever extra $fields you need
|
||||
*
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class UserList extends ZendDbResultIterator
|
||||
{
|
||||
private $columns = array('id','person_id','username','password','authenticationMethod');
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct($fields=null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if (is_array($fields)) {
|
||||
$this->find($fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection
|
||||
*
|
||||
* @param array $fields
|
||||
* @param string|array $order Multi-column sort should be given as an array
|
||||
* @param int $limit
|
||||
* @param string|array $groupBy Multi-column group by should be given as an array
|
||||
*/
|
||||
public function find($fields=null,$order='username',$limit=null,$groupBy=null)
|
||||
{
|
||||
$this->select->from(array('u'=>'users'));
|
||||
|
||||
// Finding on fields from the Users table is handled here
|
||||
if (count($fields)) {
|
||||
foreach ($fields as $key=>$value) {
|
||||
if (array_key_exists($key,$this->columns)) {
|
||||
$this->select->where("u.$key=?",$value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finding on fields from other tables requires joining those tables.
|
||||
// You can handle fields from other tables by adding the joins here
|
||||
// If you add more joins you probably want to make sure that the
|
||||
// above foreach only handles fields from the users table.
|
||||
$joins = array();
|
||||
|
||||
// Firstname, lastname, and email come from the People table
|
||||
if (isset($fields['firstname'])) {
|
||||
$joins['p'] = array('table'=>'people','condition'=>'u.id=p.user_id');
|
||||
$this->select->where('p.firstname=?',$fields['firstname']);
|
||||
}
|
||||
if (isset($fields['lastname'])) {
|
||||
$joins['p'] = array('table'=>'people','condition'=>'u.id=p.user_id');
|
||||
$this->select->where('p.lastname=?',$fields['lastname']);
|
||||
}
|
||||
if (isset($fields['email'])) {
|
||||
$joins['p'] = array('table'=>'people','condition'=>'u.id=p.user_id');
|
||||
$this->select->where('p.email=?',$fields['email']);
|
||||
}
|
||||
|
||||
// To get the Role, we have to join the user_roles and roles tables
|
||||
if (isset($fields['role'])) {
|
||||
$joins['ur'] = array('table'=>'user_roles','condition'=>'u.id=ur.user_id');
|
||||
$joins['r'] = array('table'=>'roles','condition'=>'ur.role_id=r.id');
|
||||
$this->select->where('r.name=?',$fields['role']);
|
||||
}
|
||||
|
||||
// Add all the joins we've created to the select
|
||||
foreach ($joins as $key=>$join) {
|
||||
$this->select->joinLeft(array($key=>$join['table']),$join['condition']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->select->order($order);
|
||||
if ($limit) {
|
||||
$this->select->limit($limit);
|
||||
}
|
||||
if ($groupBy) {
|
||||
$this->select->group($groupBy);
|
||||
}
|
||||
$this->populateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates all the objects from a database result set
|
||||
*
|
||||
* This is a callback function, called from ZendDbResultIterator. It is
|
||||
* called once per row of the result.
|
||||
*
|
||||
* @param int $key The index of the result row to load
|
||||
* @return User
|
||||
*/
|
||||
protected function loadResult($key)
|
||||
{
|
||||
return new User($this->result[$key]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* Replace this copyright statement with your own. All the generated code
|
||||
* will include this copyright statement
|
||||
*/
|
||||
define('COPYRIGHT',"/**
|
||||
* @copyright 2007-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/");
|
||||
/**
|
||||
* Used to keep sessions on the same webserver seperate;
|
||||
*/
|
||||
define('APPLICATION_NAME','application_name');
|
||||
|
||||
/**
|
||||
* Where on the filesystem this application is installed
|
||||
*/
|
||||
define('APPLICATION_HOME','/var/www/sites/application_name');
|
||||
|
||||
/**
|
||||
* Where on the filesystem the framework is installed.
|
||||
*/
|
||||
define('FRAMEWORK',APPLICATION_HOME.'/libraries/framework');
|
||||
|
||||
/**
|
||||
* This needs to point to the library directory inside your
|
||||
* installation of the ZendFramework
|
||||
* http://framework.zend.com
|
||||
*/
|
||||
define('ZEND',APPLICATION_HOME.'/libraries/ZendFramework/library');
|
||||
ini_set('include_path','.'.PATH_SEPARATOR.ZEND);
|
||||
require_once 'Zend/Loader/Autoloader.php';
|
||||
Zend_Loader_Autoloader::getInstance();
|
||||
|
||||
/**
|
||||
* The URL to get to this site
|
||||
* Do NOT use a trailing slash
|
||||
*/
|
||||
define('BASE_URL','http://localhost');
|
||||
|
||||
/**
|
||||
* Used when there's an error on the site. The Framework will
|
||||
* print out a nice error message, encouraging users to report any problems
|
||||
* See: FRAMEWORK/ITSFunctions.inc
|
||||
*
|
||||
* This is also the default Admin user information that gets added to the database
|
||||
*/
|
||||
define('ADMINISTRATOR_NAME','Site Admin');
|
||||
define('ADMINISTRATOR_EMAIL','admin@servername.com');
|
||||
|
||||
/**
|
||||
* Set how we want to handle errors
|
||||
* PHP_DEFAULT - do whatever's configured in php.ini
|
||||
*
|
||||
* If you do not define error handling to PHP_DEFAULT
|
||||
* the custom error handlers kick in. All of the custom error display
|
||||
* frunctions are in FRAMEWORK/globalFunctions.inc. The custom error
|
||||
* function decide what to do based on $ERROR_REPORING array values
|
||||
*
|
||||
* PRETTY_PRINT - Display a message in the browser
|
||||
* EMAIL_ADMIN - email the Administrator
|
||||
* EMAIL_USER - email the logged in user
|
||||
* SKIDDER - post errors to a Skidder server (see config below)
|
||||
*/
|
||||
define('ERROR_REPORTING','PHP_DEFAULT');
|
||||
//define('ERROR_REPORTING','CUSTOM');
|
||||
//$ERROR_REPORTING = array('PRETTY_PRINT','SKIDDER');
|
||||
/**
|
||||
* Skidder is a web service for error notifications. Error reporting supports
|
||||
* posting errors to a Skidder server. You must register for an application_id
|
||||
* on the skidder server you want to post errors to.
|
||||
*/
|
||||
//define('SKIDDER_URL','http://localhost/skidder/home.php');
|
||||
//define('SKIDDER_APPLICATION_ID',);
|
||||
|
||||
/**
|
||||
* Database Setup
|
||||
* Refer to the PDO documentation for DSN sytnax for your database type
|
||||
* http://www.php.net/manual/en/pdo.drivers.php
|
||||
*/
|
||||
define('DB_ADAPTER','Pdo_Mysql');
|
||||
define('DB_HOST','localhost');
|
||||
define('DB_NAME',APPLICATION_NAME);
|
||||
define('DB_USER',APPLICATION_NAME);
|
||||
define('DB_PASS','password');
|
||||
|
||||
/**
|
||||
* LDAP Configuration
|
||||
* This is required in order to use the LDAP authentication
|
||||
* If you do not want to use LDAP authentication, you can comment this out
|
||||
*/
|
||||
define('LDAP_DOMAIN','ldap.domain.somewhere');
|
||||
define('LDAP_DN','ou=people,o='.LDAP_DOMAIN);
|
||||
define('LDAP_USERNAME_ATTRIBUTE','uid');
|
||||
define('LDAP_ADMIN_USER','username');
|
||||
define('LDAP_ADMIN_PASS','password');
|
||||
define('LDAP_SERVER','ldap.somewhere.com');
|
||||
define('LDAP_PASSWORD_ATTRIBUTE','userpassword');
|
||||
|
||||
/**
|
||||
* Import global functions that we use for many applications we write
|
||||
*/
|
||||
include FRAMEWORK.'/globalFunctions.php';
|
||||
spl_autoload_register('autoload');
|
||||
|
||||
/**
|
||||
* Session Startup
|
||||
* Don't start a session for CLI usage.
|
||||
* We only want sessions when PHP code is executed from the webserver
|
||||
*/
|
||||
if (!defined('STDIN')) {
|
||||
ini_set('session.save_path',APPLICATION_HOME.'/data/sessions');
|
||||
session_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the Zend_Acl
|
||||
* Access control is going to handled using the Zend_Acl
|
||||
* We only need to load it, if someone is logged in
|
||||
*/
|
||||
if (isset($_SESSION['USER'])) {
|
||||
include APPLICATION_HOME.'/access_control.inc';
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
|
||||
verifyUser('Administrator');
|
||||
if (!userIsAllowed('Deeds')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL.'/deeds');
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($_POST['deed'])) {
|
||||
$deed = new Deed();
|
||||
foreach ($_POST['deed'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$deed->$set($value);
|
||||
}
|
||||
|
||||
try {
|
||||
$deed->save();
|
||||
header('Location: '.BASE_URL.'/deeds');
|
||||
exit();
|
||||
}
|
||||
catch(Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('deeds/addDeedForm.inc');
|
||||
echo $template->render();
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
|
||||
$deedList = new DeedList();
|
||||
$deedList->find();
|
||||
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('deeds/deedList.inc',array('deedList'=>$deedList));
|
||||
echo $template->render();
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
|
||||
if (!userIsAllowed('Deeds')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL.'/deeds');
|
||||
exit();
|
||||
}
|
||||
|
||||
$deed = new Deed($_REQUEST['deed_id']);
|
||||
if (isset($_POST['deed'])) {
|
||||
foreach ($_POST['deed'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$deed->$set($value);
|
||||
}
|
||||
|
||||
try {
|
||||
$deed->save();
|
||||
header('Location: '.BASE_URL.'/deeds');
|
||||
exit();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('deeds/updateDeedForm.inc',array('deed'=>$deed));
|
||||
echo $template->render();
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
$template = new Template();
|
||||
echo $template->render();
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
if (!userIsAllowed('Internments')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL.'/internments');
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($_POST['internment'])) {
|
||||
$internment = new Internment();
|
||||
foreach ($_POST['internment'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$internment->$set($value);
|
||||
}
|
||||
|
||||
try {
|
||||
$internment->save();
|
||||
header('Location: '.BASE_URL.'/internments');
|
||||
exit();
|
||||
}
|
||||
catch(Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('internments/addInternmentForm.inc');
|
||||
echo $template->render();
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
|
||||
$internmentList = new InternmentList();
|
||||
$internmentList->find();
|
||||
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('internments/internmentList.inc',
|
||||
array('internmentList'=>$internmentList));
|
||||
echo $template->render();
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
|
||||
if (!userIsAllowed('Internments')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL.'/internments');
|
||||
exit();
|
||||
}
|
||||
|
||||
$internment = new Internment($_REQUEST['internment_id']);
|
||||
if (isset($_POST['internment'])) {
|
||||
foreach ($_POST['internment'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$internment->$set($value);
|
||||
}
|
||||
|
||||
try {
|
||||
$internment->save();
|
||||
header('Location: '.BASE_URL.'/internments');
|
||||
exit();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('internments/updateInternmentForm.inc',
|
||||
array('internment'=>$internment));
|
||||
echo $template->render();
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* @copyright Copyright (C) 2006-2008 City of Bloomington, Indiana. All rights reserved.
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
var FRAMEWORK = {};
|
||||
|
||||
/* A handy function for doing pop-up confirmations when deleting something */
|
||||
FRAMEWORK.deleteConfirmation = function (url)
|
||||
{
|
||||
if (confirm("Are you really sure you want to delete this?\n\nOnce deleted it will be gone forever."))
|
||||
{
|
||||
document.location.href = url;
|
||||
return true;
|
||||
}
|
||||
else { return false; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for navigating between multiple forms that contain information
|
||||
* for one object, and are displayed as tabs. Each of the forms must have
|
||||
* a hidden field for the tab and action, each with the appropriate id.
|
||||
* Also each of the forms must use the same id in the form tag
|
||||
* @param id form The id of the form tag
|
||||
* @param string tab The name of the next tab to display
|
||||
* @param string action The function to call in the controller for the forms
|
||||
*/
|
||||
FRAMEWORK.processTabbedForm = function (form,tab,action)
|
||||
{
|
||||
if (action === 'save') { document.getElementById('continue').value = 'false'; }
|
||||
document.getElementById('tab').value = tab;
|
||||
document.getElementById('action').value = action;
|
||||
document.getElementById(form).submit();
|
||||
};
|
||||
|
||||
/* The following function creates an XMLHttpRequest object useful for doing AJAX stuff */
|
||||
FRAMEWORK.getXMLHttpRequestObject = function ()
|
||||
{
|
||||
var request;
|
||||
var browser = navigator.appName;
|
||||
|
||||
if (browser === "Microsoft Internet Explorer") { request = new ActiveXObject("Microsoft.XMLHTTP"); }
|
||||
else { request = new XMLHttpRequest(); }
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
FRAMEWORK.getFormValues = function (form)
|
||||
{
|
||||
var params = "";
|
||||
|
||||
for(var i=0; i<form.elements.length; i++)
|
||||
{
|
||||
switch(form.elements[i].type)
|
||||
{
|
||||
case "text":
|
||||
params += form.elements[i].name + "=" + escape(form.elements[i].value) + ";";
|
||||
break;
|
||||
|
||||
case "select-one":
|
||||
params += form.elements[i].name + "=" + form.elements[i].options[form.elements[i].selectedIndex].value + ";";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Remove the trailing semicolon before returning
|
||||
return params.substr(0,(params.length - 1));
|
||||
};
|
||||
|
||||
/**
|
||||
* Limits a given form field to a given number of characters
|
||||
* @param field The DOM element for the field to limit
|
||||
* @param maxNumChars The maximum number of characters you want to allow
|
||||
*/
|
||||
FRAMEWORK.limit = function (field,maxNumChars)
|
||||
{
|
||||
if (field.value.length > maxNumChars)
|
||||
{
|
||||
field.value = field.value.substring(0,maxNumChars);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Date Picker built off the YUI Calendar
|
||||
* This requires the YUI Toolkit
|
||||
* @param element The form input to put the chosen date
|
||||
*/
|
||||
FRAMEWORK.calendarInit = true;
|
||||
FRAMEWORK.popupCalendar = function (element)
|
||||
{
|
||||
if (!document.getElementById("popupDatePicker"))
|
||||
{
|
||||
var div = document.createElement("div");
|
||||
div.setAttribute("id","popupDatePicker");
|
||||
div.setAttribute("class","yui-skin-sam");
|
||||
element.form.appendChild(div);
|
||||
}
|
||||
|
||||
FRAMEWORK.dateField = element;
|
||||
|
||||
if (FRAMEWORK.calendarInit)
|
||||
{
|
||||
FRAMEWORK.calendarInit = false;
|
||||
FRAMEWORK.popupDatePicker = new YAHOO.widget.Calendar("popupDatePicker",{"close":true});
|
||||
FRAMEWORK.popupDatePicker.selectEvent.subscribe(FRAMEWORK.dateSelectionHandler,FRAMEWORK.popupDatePicker,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (element.value != "")
|
||||
{
|
||||
FRAMEWORK.popupDatePicker.select(element.value);
|
||||
dates = FRAMEWORK.popupDatePicker.getSelectedDates();
|
||||
if (dates.length > 0)
|
||||
{
|
||||
date = dates[0];
|
||||
FRAMEWORK.popupDatePicker.cfg.setProperty("pagedate",(date.getMonth()+1 + "/" + date.getFullYear()));
|
||||
}
|
||||
else { alert("Invalid date"); }
|
||||
}
|
||||
}
|
||||
|
||||
var xy = YAHOO.util.Dom.getXY(element);
|
||||
xy[0] += 20;
|
||||
xy[1] += 20;
|
||||
YAHOO.util.Dom.setXY ("popupDatePicker", xy, false);
|
||||
|
||||
|
||||
FRAMEWORK.popupDatePicker.render();
|
||||
FRAMEWORK.popupDatePicker.show();
|
||||
}
|
||||
|
||||
FRAMEWORK.dateSelectionHandler = function (type,args,obj)
|
||||
{
|
||||
FRAMEWORK.dateField.value = args[0][0][1] + "/" + args[0][0][2] + "/" + args[0][0][0];
|
||||
FRAMEWORK.popupDatePicker.hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure dates are correct. Returns false on dates like Feb 30
|
||||
* The months are zero based, so January is 0 and December is 11
|
||||
*
|
||||
* @param int month (0=Jan, 11=Dec)
|
||||
* @param int day
|
||||
* @param int year
|
||||
*/
|
||||
FRAMEWORK.validateDate = function (month,day,year)
|
||||
{
|
||||
var date = new Date(year,month,day);
|
||||
|
||||
if (year != date.getFullYear()) {
|
||||
alert('Year is not valid!');
|
||||
return false;
|
||||
}
|
||||
if (month != date.getMonth()) {
|
||||
alert('Month is not valid!');
|
||||
return false;
|
||||
}
|
||||
if(day != date.getDate()) {
|
||||
alert('Day is not valid!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2007-2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
$_SESSION['errorMessages'][] = new Exception('noJavascript');
|
||||
$template = new Template();
|
||||
echo $template->render();
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('loginForm.inc');
|
||||
echo $template->render();
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* Logs a user into the system.
|
||||
*
|
||||
* A logged in user will have a $_SESSION['USER']
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
try {
|
||||
$user = new User($_POST['username']);
|
||||
|
||||
if ($user->authenticate($_POST['password'])) {
|
||||
$user->startNewSession();
|
||||
}
|
||||
else {
|
||||
throw new Exception('wrongPassword');
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
// The user has successfully logged in. Redirect them wherever you like
|
||||
if ($_POST['return_url']) {
|
||||
header('Location: '.$_POST['return_url']);
|
||||
}
|
||||
else {
|
||||
header('Location: '.BASE_URL);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
/**
|
||||
* Logs a user out of the system
|
||||
* @copyright 2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
session_destroy();
|
||||
header('Location: '.BASE_URL);
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
if (!userIsAllowed('Users')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($_POST['person'])) {
|
||||
$person = new Person();
|
||||
foreach ($_POST['person'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$person->$set($value);
|
||||
}
|
||||
|
||||
try {
|
||||
$person->save();
|
||||
header('Location: '.BASE_URL.'/people');
|
||||
exit();
|
||||
}
|
||||
catch(Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->title = 'Add a person';
|
||||
$template->blocks[] = new Block('people/addPersonForm.inc');
|
||||
echo $template->render();
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
if (!userIsAllowed('Users')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
$personList = new PersonList();
|
||||
$personList->find();
|
||||
|
||||
$template = new Template();
|
||||
$template->title = 'People';
|
||||
$template->blocks[] = new Block('people/personList.inc',array('personList'=>$personList));
|
||||
echo $template->render();
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param Request person_id
|
||||
*/
|
||||
if (!userIsAllowed('Users')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
$person = new Person($_REQUEST['person_id']);
|
||||
|
||||
if (isset($_POST['person'])) {
|
||||
foreach ($_POST['person'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$person->$set($value);
|
||||
}
|
||||
|
||||
try {
|
||||
$person->save();
|
||||
header('Location: '.BASE_URL.'/people');
|
||||
exit();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->title = 'Update a person';
|
||||
$template->blocks[] = new Block('people/updatePersonForm.inc',array('person'=>$person));
|
||||
echo $template->render();
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param GET person_id
|
||||
*/
|
||||
$person = new Person($_GET['person_id']);
|
||||
|
||||
$template = new Template();
|
||||
$template->title = $person->getFullname();
|
||||
$template->blocks[] = new Block('people/personInfo.inc',array('person'=>$person));
|
||||
echo $template->render();
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
#panel-container { overflow:auto; }
|
||||
#panel-one { float:left; width:180px; }
|
||||
#panel-two { float:right; width:180px; }
|
||||
#content-panel { margin-left: 190px; margin-right: 190px; }
|
||||
|
||||
#footer { clear:both; }
|
|
@ -0,0 +1,5 @@
|
|||
#panel-container { overflow:auto; }
|
||||
#panel-one { float:left; width:176px; }
|
||||
#content-panel { margin-left: 178px; }
|
||||
|
||||
#footer { clear:both; }
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param GET person_id
|
||||
*/
|
||||
if (!userIsAllowed('Users')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['person_id'])) {
|
||||
try {
|
||||
$person = new Person($_REQUEST['person_id']);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['user'])) {
|
||||
|
||||
$user = new User();
|
||||
foreach ($_POST['user'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$user->$set($value);
|
||||
}
|
||||
|
||||
if (isset($person)) {
|
||||
$user->setPerson_id($person->getId());
|
||||
}
|
||||
else {
|
||||
// Load their information from LDAP
|
||||
// Delete this statement if you're not using LDAP
|
||||
if ($user->getAuthenticationMethod() == 'LDAP') {
|
||||
try {
|
||||
$ldap = new LDAPEntry($user->getUsername());
|
||||
try {
|
||||
$person = new Person($ldap->getEmail());
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$person = new Person();
|
||||
$person->setFirstname($ldap->getFirstname());
|
||||
$person->setLastname($ldap->getLastname());
|
||||
$person->setEmail($ldap->getEmail());
|
||||
$person->save();
|
||||
}
|
||||
$user->setPerson($person);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$user->save();
|
||||
header('Location: '.BASE_URL.'/users');
|
||||
exit();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->title = 'Create a user account';
|
||||
$template->blocks[] = new Block('users/addUserForm.inc');
|
||||
if (isset($person)) {
|
||||
$template->blocks[] = new Block('people/personInfo.inc',array('person'=>$person));
|
||||
}
|
||||
echo $template->render();
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param GET user_id
|
||||
*/
|
||||
if (!userIsAllowed('Users')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
$user = new User($_GET['user_id']);
|
||||
$user->delete();
|
||||
|
||||
header('Location: '.BASE_URL.'/users');
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
if (!userIsAllowed('Users')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->title = 'User accounts';
|
||||
|
||||
$userList = new UserList();
|
||||
$userList->find();
|
||||
$template->blocks[] = new Block('users/userList.inc',array('userList'=>$userList));
|
||||
|
||||
echo $template->render();
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param REQUEST user_id
|
||||
*/
|
||||
if (!userIsAllowed('Users')) {
|
||||
$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL);
|
||||
exit();
|
||||
}
|
||||
|
||||
$user = new User($_REQUEST['user_id']);
|
||||
|
||||
if (isset($_POST['user'])) {
|
||||
foreach ($_POST['user'] as $field=>$value) {
|
||||
$set = 'set'.ucfirst($field);
|
||||
$user->$set($value);
|
||||
}
|
||||
|
||||
try {
|
||||
$user->save();
|
||||
header('Location: '.BASE_URL.'/users');
|
||||
exit();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['errorMessages'][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template();
|
||||
$template->blocks[] = new Block('users/updateUserForm.inc',array('user'=>$user));
|
||||
$template->blocks[] = new BlocK('people/personInfo.inc',array('person'=>$user->getPerson()));
|
||||
echo $template->render();
|
|
@ -0,0 +1,139 @@
|
|||
---------------------------------------------------------------------
|
||||
Contents
|
||||
---------------------------------------------------------------------
|
||||
About
|
||||
|
||||
Copyright
|
||||
|
||||
Requirements
|
||||
|
||||
Installation
|
||||
|
||||
---------------------------------------------------------------------
|
||||
About
|
||||
---------------------------------------------------------------------
|
||||
This scaffolding is really just a template for our web
|
||||
applications. It provides us the basics to get a web application up
|
||||
and running very quickly. It also means our applications will be
|
||||
relatively uniform and easier to extend and maintain down the road.
|
||||
While not fully MVC, it has borrowed ideas from Rails
|
||||
and Struts. It has developed over time, and will continue to develop
|
||||
as we come across better solutions to problems run into while creating
|
||||
new applications.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
Copyright
|
||||
---------------------------------------------------------------------
|
||||
This scaffolding is written and copyrighted by the
|
||||
City of Bloomington, IN. It is being released as free software;
|
||||
you can redistribute it and/or modify it under the terms of the
|
||||
GNU Affero General Public License as published by the Free Software Foundation;
|
||||
either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This scaffolding includes code generators to create classes to
|
||||
work with your database. While the generators fall under the GPL,
|
||||
any code you generate with them belongs to you. However, we highly
|
||||
encourage you to uphold the values of Free Software and release your
|
||||
application as Free Software as well.
|
||||
|
||||
In any case, you own the copyright to any generated code and should
|
||||
edit the copyright statement in the configuration. This will be the
|
||||
copyright statement that will be included in all generated code.
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
Requirements
|
||||
---------------------------------------------------------------------
|
||||
framework:
|
||||
This scaffolding requires our framework to be on the server somewhere.
|
||||
It ships with a working version of framework installed in /libraries.
|
||||
In the configuration, you can point the application to another copy
|
||||
of the framework, if you like. If you make changes to the code in
|
||||
the /libraries/framework, you might consider sending those changes
|
||||
back to us, so we can improve this scaffolding.
|
||||
|
||||
ZendFramework:
|
||||
Database interaction for this application is done using Zend_Db. You must
|
||||
have downloaded a copy of the ZendFramework for this to work. In the
|
||||
configuration, you will point the application to wherever you've installed
|
||||
your copy of the ZendFramework. The ZendFramework is available under a
|
||||
BSD license at:
|
||||
http://framework.zend.com/
|
||||
|
||||
Apache:
|
||||
This application was written assuming you have control over your own web
|
||||
server. If you are on a hosted system, you may need to make changes to
|
||||
the code to accomodate your server.
|
||||
|
||||
All webserver instructions assume the Apache webserver. It is certainly
|
||||
possible to set this using a different web server. However, we don't have
|
||||
any experience with other webservers and cannot provide information on
|
||||
their configuration.
|
||||
|
||||
All include files have been kept out of the web directory, and a configuration
|
||||
file has been included. You will need to make sure that every .php script
|
||||
in the HTML directory includes configuration.inc. If you control your own
|
||||
webserver, you can add a <Directory> command to your httpd.conf.
|
||||
|
||||
PHP:
|
||||
PHP must be compiled with support for:
|
||||
PDO
|
||||
MySQL
|
||||
LDAP
|
||||
|
||||
Actually, you can substitute any database support for MySQL, as our
|
||||
framework uses PDO for database interaction. However, the initial SQL
|
||||
schema provided is specific to MySQL. The schema would need to be modified
|
||||
for other databases.
|
||||
|
||||
MySQL:
|
||||
MySQL should have support for InnoDB. Foreign keys are written into
|
||||
the database load scripts. While MyISAM tables will just ignore them,
|
||||
you database and your application will be that much more robust with InnoDB
|
||||
support.
|
||||
|
||||
LDAP:
|
||||
LDAP is only used for doing LDAP authentication for users.
|
||||
If you're not going to do any LDAP authentication, you can delete or
|
||||
comment out the LDAP stuff.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
Installation
|
||||
---------------------------------------------------------------------
|
||||
This scaffolding is essentially a working web application that is
|
||||
ready to be extended. It has authentication and user management
|
||||
already built.
|
||||
|
||||
The best way is to have PHP auto_prepend the configuration.inc.
|
||||
If this is the only web application on your apache server, you can just point
|
||||
your apache's web directory to the html directory inside the application and
|
||||
edit the auto_prepend in your php.ini file.
|
||||
|
||||
For us, we're running multiple applications, and have a seperate entry in
|
||||
our Apache config for each one. This does essentially the same thing.
|
||||
|
||||
Add to httpd.conf:
|
||||
|
||||
Alias /application_name "/path/to/application_name/html"
|
||||
<Directory "/path/to/application_name/html">
|
||||
Options FollowSymLinks
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
|
||||
php_value auto_prepend_file /path/to/application_name/configuration.inc
|
||||
</Directory>
|
||||
|
||||
|
||||
If you're running in a shared hosting environment, you cannot do Alias or
|
||||
Directory commands. However the html can be moved into your web directory.
|
||||
To make sure the configuration file gets loaded, create an htaccess file in
|
||||
this application's html directory with the php_value line from above.
|
||||
|
||||
If you cannot edit your httpd.conf or use htaccess files, you will need to
|
||||
add an include() command to the top of every last PHP script in the html directory.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
Configuration
|
||||
---------------------------------------------------------------------
|
||||
Edit configuration.inc with appropriate values for your installation.
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2007-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @param Zend_Paginator $this->pages
|
||||
*/
|
||||
if ($this->pages->pageCount > 1) {
|
||||
$url = new URL($_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
|
||||
$url->purgeEmptyParameters();
|
||||
|
||||
echo '<ul class="pageNavigation">';
|
||||
|
||||
// Show the Back button
|
||||
if (isset($this->pages->previous)) {
|
||||
$url->page = $this->pages->first;
|
||||
echo "<li><a href=\"$url\" class=\"first\">First</a></li>";
|
||||
|
||||
$url->page = $this->pages->previous;
|
||||
echo "<li><a href=\"$url\" class=\"previous\">Back</a></li>";
|
||||
}
|
||||
// Show the page number links
|
||||
// Show only $maxNumLinks pages at a time
|
||||
foreach ($this->pages->pagesInRange as $page) {
|
||||
$url->page = $page;
|
||||
$class = ($page == $this->pages->current) ? 'class="current"' : '';
|
||||
echo "<li><a href=\"$url\" $class>$page</a></li>";
|
||||
}
|
||||
|
||||
// Show the Next button
|
||||
if (isset($this->pages->next)) {
|
||||
$url->page = $this->pages->next;
|
||||
echo "<li><a href=\"$url\" class=\"next\">Next</a></li>";
|
||||
|
||||
$url->page = $this->pages->last;
|
||||
echo "<li><a href=\"$url\" class=\"last\">Last</a></li>";
|
||||
}
|
||||
|
||||
echo '</ul>';
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
/**
|
||||
* Represents a block of main content in a template
|
||||
*
|
||||
* Blocks are partial view scripts.
|
||||
* They are contained in APPLICATION/blocks
|
||||
* They are organized by $outputFormat
|
||||
* APPLICATION_HOME/blocks/html/...
|
||||
* APPLICATION_HOME/blocks/xml/...
|
||||
* APPLICATION_HOME/blocks/json/..
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Block extends View
|
||||
{
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* Establishes the block script to use for rendering
|
||||
*
|
||||
* Blocks are files contained in the base path of:
|
||||
* APPLICATION_HOME/blocks/$outpuform
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $vars An associative array of variables to set
|
||||
*/
|
||||
public function __construct($file,array $vars=null)
|
||||
{
|
||||
$this->file = $file;
|
||||
if (count($vars)) {
|
||||
foreach ($vars as $name=>$value) {
|
||||
$this->vars[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes the block script and returns the output as a string
|
||||
*
|
||||
* @param string $outputFormat
|
||||
* @return string
|
||||
*/
|
||||
public function render($outputFormat='html')
|
||||
{
|
||||
$block = "/blocks/$outputFormat/{$this->file}";
|
||||
|
||||
if (file_exists(APPLICATION_HOME.$block)) {
|
||||
ob_start();
|
||||
include APPLICATION_HOME.$block;
|
||||
return ob_get_clean();
|
||||
}
|
||||
elseif (file_exists(FRAMEWORK.$block)) {
|
||||
ob_start();
|
||||
include FRAMEWORK.$block;
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
throw new Exception('unknownBlock');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/**
|
||||
* Singleton for the Database connection
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
private static $connection;
|
||||
|
||||
/**
|
||||
* @param boolean $reconnect If true, drops the connection and reconnects
|
||||
* @return resource
|
||||
*/
|
||||
public static function getConnection($reconnect=false)
|
||||
{
|
||||
if ($reconnect) {
|
||||
self::$connection=null;
|
||||
}
|
||||
if (!self::$connection) {
|
||||
try {
|
||||
$parameters = array('host'=>DB_HOST,
|
||||
'username'=>DB_USER,
|
||||
'password'=>DB_PASS,
|
||||
'dbname'=>DB_NAME,
|
||||
'options'=>array(Zend_Db::AUTO_QUOTE_IDENTIFIERS=>false));
|
||||
self::$connection = Zend_Db::factory(DB_ADAPTER,$parameters);
|
||||
self::$connection->getConnection();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
die($e->getMessage());
|
||||
}
|
||||
}
|
||||
return self::$connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of database that's being used (mysql, oracle, etc.)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getType()
|
||||
{
|
||||
switch (strtolower(DB_ADAPTER)) {
|
||||
case 'pdo_mysql':
|
||||
case 'mysqli':
|
||||
return 'mysql';
|
||||
break;
|
||||
|
||||
case 'pdo_oci':
|
||||
case 'oci8':
|
||||
return 'oracle';
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Date extends DateTime
|
||||
{
|
||||
/**
|
||||
* Handles array dates passed in the constructor.
|
||||
*
|
||||
* Wrapper for DateTime constructor. If arrays are passed, they will be
|
||||
* handled here. Anything else will be passed to the DateTime constructor.
|
||||
* Arrays should be in the form of PHP's getdate() array
|
||||
*
|
||||
* @param array $date
|
||||
*/
|
||||
public function __construct($date=null)
|
||||
{
|
||||
if (is_array($date)) {
|
||||
if ($date['year'] && $date['mon'] && $date['mday']) {
|
||||
$dateString = "$date[year]-$date[mon]-$date[mday]";
|
||||
|
||||
if (isset($date['hours']) || isset($date['minutes']) || isset($date['seconds'])) {
|
||||
$time = (isset($date['hours']) && $date['hours']) ? "$date[hours]:" : '00:';
|
||||
$time.= (isset($date['minutes']) && $date['minutes']) ? "$date[minutes]:" : '00:';
|
||||
$time.= (isset($date['seconds']) && $date['seconds']) ? $date['seconds'] : '00';
|
||||
|
||||
$dateString.= " $time";
|
||||
}
|
||||
$date = $dateString;
|
||||
}
|
||||
}
|
||||
if (is_int($date)) {
|
||||
$date = date('Y-m-d',$date);
|
||||
}
|
||||
if (!$date instanceof DateTime) {
|
||||
parent::__construct($date);
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->format('n/j/Y');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
|
||||
interface ExternalAuthentication
|
||||
{
|
||||
public static function authenticate($username,$password);
|
||||
public static function savePassword($username,$password);
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
<?php
|
||||
/**
|
||||
* Pluralize and singularize English words.
|
||||
*
|
||||
* Orinally written by the CakePHP Project
|
||||
* CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
|
||||
* Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @filesource
|
||||
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @version $Revision: 6311 $
|
||||
* @modifiedby $LastChangedBy: phpnut $
|
||||
* @lastmodified $Date: 2008-01-02 00:33:52 -0600 (Wed, 02 Jan 2008) $
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*
|
||||
* Modified to work in City of Bloomington's Framework
|
||||
* Relicensed under GPL
|
||||
* Redistributions must retain all copyright notices
|
||||
* @copyright 2006-2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
*/
|
||||
class Inflector
|
||||
{
|
||||
/**
|
||||
* Return $word in plural form.
|
||||
*
|
||||
* @param string $word Word in singular
|
||||
* @return string Word in plural
|
||||
*/
|
||||
public static function pluralize($word) {
|
||||
$corePluralRules = array('/(s)tatus$/i' => '\1\2tatuses',
|
||||
'/(quiz)$/i' => '\1zes',
|
||||
'/^(ox)$/i' => '\1\2en',
|
||||
'/([m|l])ouse$/i' => '\1ice',
|
||||
'/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
|
||||
'/(x|ch|ss|sh)$/i' => '\1es',
|
||||
'/([^aeiouy]|qu)y$/i' => '\1ies',
|
||||
'/(hive)$/i' => '\1s',
|
||||
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
|
||||
'/sis$/i' => 'ses',
|
||||
'/([ti])um$/i' => '\1a',
|
||||
'/(p)erson$/i' => '\1eople',
|
||||
'/(m)an$/i' => '\1en',
|
||||
'/(c)hild$/i' => '\1hildren',
|
||||
'/(buffal|tomat)o$/i' => '\1\2oes',
|
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
|
||||
'/us$/' => 'uses',
|
||||
'/(alias)$/i' => '\1es',
|
||||
'/(ax|cri|test)is$/i' => '\1es',
|
||||
'/s$/' => 's',
|
||||
'/$/' => 's',);
|
||||
|
||||
$coreUninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'Amoyese',
|
||||
'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
|
||||
'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
|
||||
'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
|
||||
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
|
||||
'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
|
||||
'nexus', 'Niasese', 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
|
||||
'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
|
||||
'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
|
||||
'whiting', 'wildebeest', 'Yengeese',);
|
||||
|
||||
$coreIrregularPlural = array('atlas' => 'atlases',
|
||||
'beef' => 'beefs',
|
||||
'brother' => 'brothers',
|
||||
'child' => 'children',
|
||||
'corpus' => 'corpuses',
|
||||
'cow' => 'cows',
|
||||
'ganglion' => 'ganglions',
|
||||
'genie' => 'genies',
|
||||
'genus' => 'genera',
|
||||
'graffito' => 'graffiti',
|
||||
'hoof' => 'hoofs',
|
||||
'loaf' => 'loaves',
|
||||
'man' => 'men',
|
||||
'money' => 'monies',
|
||||
'mongoose' => 'mongooses',
|
||||
'move' => 'moves',
|
||||
'mythos' => 'mythoi',
|
||||
'numen' => 'numina',
|
||||
'occiput' => 'occiputs',
|
||||
'octopus' => 'octopuses',
|
||||
'opus' => 'opuses',
|
||||
'ox' => 'oxen',
|
||||
'penis' => 'penises',
|
||||
'person' => 'people',
|
||||
'sex' => 'sexes',
|
||||
'soliloquy' => 'soliloquies',
|
||||
'testis' => 'testes',
|
||||
'trilby' => 'trilbys',
|
||||
'turf' => 'turfs',);
|
||||
|
||||
$pluralRules = $corePluralRules;
|
||||
$uninflected = $coreUninflectedPlural;
|
||||
$irregular = $coreIrregularPlural;
|
||||
|
||||
if (file_exists(FRAMEWORK.'/includes/inflections.inc')) {
|
||||
include(FRAMEWORK.'/includes/inflections.inc');
|
||||
$pluralRules = array_merge($pluralRules, $corePluralRules);
|
||||
$uninflected = array_merge($uninflectedPlural, $coreUninflectedPlural);
|
||||
$irregular = array_merge($irregularPlural, $coreIrregularPlural);
|
||||
}
|
||||
$regexUninflected = self::enclose(join( '|', $uninflected));
|
||||
$regexIrregular = self::enclose(join( '|', array_keys($irregular)));
|
||||
|
||||
if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
|
||||
return $word;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
|
||||
return $regs[1] . $irregular[strtolower($regs[2])];
|
||||
}
|
||||
|
||||
foreach ($pluralRules as $rule => $replacement) {
|
||||
if (preg_match($rule, $word)) {
|
||||
$replace = preg_replace($rule, $replacement, $word);
|
||||
return $replace;
|
||||
}
|
||||
}
|
||||
return $word;
|
||||
}
|
||||
/**
|
||||
* Return $word in singular form.
|
||||
*
|
||||
* @param string $word Word in plural
|
||||
* @return string Word in singular
|
||||
*/
|
||||
public static function singularize($word) {
|
||||
$coreSingularRules = array('/(s)tatuses$/i' => '\1\2tatus',
|
||||
'/^(.*)(menu)s$/i' => '\1\2',
|
||||
'/(quiz)zes$/i' => '\\1',
|
||||
'/(matr)ices$/i' => '\1ix',
|
||||
'/(vert|ind)ices$/i' => '\1ex',
|
||||
'/^(ox)en/i' => '\1',
|
||||
'/(alias)(es)*$/i' => '\1',
|
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
|
||||
'/(cris|ax|test)es$/i' => '\1is',
|
||||
'/(shoe)s$/i' => '\1',
|
||||
'/(o)es$/i' => '\1',
|
||||
'/ouses$/' => 'ouse',
|
||||
'/uses$/' => 'us',
|
||||
'/([m|l])ice$/i' => '\1ouse',
|
||||
'/(x|ch|ss|sh)es$/i' => '\1',
|
||||
'/(m)ovies$/i' => '\1\2ovie',
|
||||
'/(s)eries$/i' => '\1\2eries',
|
||||
'/([^aeiouy]|qu)ies$/i' => '\1y',
|
||||
'/([lr])ves$/i' => '\1f',
|
||||
'/(tive)s$/i' => '\1',
|
||||
'/(hive)s$/i' => '\1',
|
||||
'/(drive)s$/i' => '\1',
|
||||
'/([^f])ves$/i' => '\1fe',
|
||||
'/(^analy)ses$/i' => '\1sis',
|
||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
|
||||
'/([ti])a$/i' => '\1um',
|
||||
'/(p)eople$/i' => '\1\2erson',
|
||||
'/(m)en$/i' => '\1an',
|
||||
'/(c)hildren$/i' => '\1\2hild',
|
||||
'/(n)ews$/i' => '\1\2ews',
|
||||
'/^(.*us)$/' => '\\1',
|
||||
'/s$/i' => '');
|
||||
|
||||
$coreUninflectedSingular = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss', 'Amoyese',
|
||||
'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
|
||||
'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
|
||||
'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
|
||||
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
|
||||
'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
|
||||
'nexus', 'Niasese', 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
|
||||
'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
|
||||
'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
|
||||
'whiting', 'wildebeest', 'Yengeese',);
|
||||
|
||||
$coreIrregularSingular = array('atlases' => 'atlas',
|
||||
'beefs' => 'beef',
|
||||
'brothers' => 'brother',
|
||||
'children' => 'child',
|
||||
'corpuses' => 'corpus',
|
||||
'cows' => 'cow',
|
||||
'ganglions' => 'ganglion',
|
||||
'genies' => 'genie',
|
||||
'genera' => 'genus',
|
||||
'graffiti' => 'graffito',
|
||||
'hoofs' => 'hoof',
|
||||
'loaves' => 'loaf',
|
||||
'men' => 'man',
|
||||
'monies' => 'money',
|
||||
'mongooses' => 'mongoose',
|
||||
'moves' => 'move',
|
||||
'mythoi' => 'mythos',
|
||||
'numina' => 'numen',
|
||||
'occiputs' => 'occiput',
|
||||
'octopuses' => 'octopus',
|
||||
'opuses' => 'opus',
|
||||
'oxen' => 'ox',
|
||||
'penises' => 'penis',
|
||||
'people' => 'person',
|
||||
'sexes' => 'sex',
|
||||
'soliloquies' => 'soliloquy',
|
||||
'testes' => 'testis',
|
||||
'trilbys' => 'trilby',
|
||||
'turfs' => 'turf',);
|
||||
|
||||
$singularRules = $coreSingularRules;
|
||||
$uninflected = $coreUninflectedSingular;
|
||||
$irregular = $coreIrregularSingular;
|
||||
|
||||
if (file_exists(FRAMEWORK.'/includes/inflections.inc')) {
|
||||
include(FRAMEWORK.'/includes/inflections.inc');
|
||||
$singularRules = array_merge($singularRules, $coreSingularRules);
|
||||
$uninflected = array_merge($uninflectedSingular, $coreUninflectedSingular);
|
||||
$irregular = array_merge($irregularSingular, $coreIrregularSingular);
|
||||
}
|
||||
$regexUninflected = self::enclose(join( '|', $uninflected));
|
||||
$regexIrregular = self::enclose(join( '|', array_keys($irregular)));
|
||||
|
||||
if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
|
||||
return $word;
|
||||
}
|
||||
|
||||
if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
|
||||
return $regs[1] . $irregular[strtolower($regs[2])];
|
||||
}
|
||||
|
||||
foreach ($singularRules as $rule => $replacement) {
|
||||
if (preg_match($rule, $word)) {
|
||||
$replace = preg_replace($rule, $replacement, $word);
|
||||
return $replace;
|
||||
}
|
||||
}
|
||||
return $word;
|
||||
}
|
||||
/**
|
||||
* Returns given $lower_case_and_underscored_word as a camelCased word.
|
||||
*
|
||||
* @param string $lower_case_and_underscored_word Word to camelize
|
||||
* @return string Camelized word. likeThis.
|
||||
*/
|
||||
public static function camelize($lowerCaseAndUnderscoredWord) {
|
||||
$replace = str_replace(" ", "", ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord)));
|
||||
return $replace;
|
||||
}
|
||||
/**
|
||||
* Returns an underscore-syntaxed ($like_this_dear_reader) version of the $camel_cased_word.
|
||||
*
|
||||
* @param string $camel_cased_word Camel-cased word to be "underscorized"
|
||||
* @return string Underscore-syntaxed version of the $camel_cased_word
|
||||
*/
|
||||
public static function underscore($camelCasedWord) {
|
||||
$replace = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
|
||||
return $replace;
|
||||
}
|
||||
/**
|
||||
* Returns a human-readable string from $lower_case_and_underscored_word,
|
||||
* by replacing underscores with a space, and by upper-casing the initial characters.
|
||||
*
|
||||
* @param string $lower_case_and_underscored_word String to be made more readable
|
||||
* @return string Human-readable string
|
||||
*/
|
||||
public static function humanize($lowerCaseAndUnderscoredWord) {
|
||||
$replace = ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord));
|
||||
return $replace;
|
||||
}
|
||||
/**
|
||||
* Returns corresponding table name for given $class_name. ("posts" for the model class "Post").
|
||||
*
|
||||
* @param string $class_name Name of class to get database table name for
|
||||
* @return string Name of the database table for given class
|
||||
*/
|
||||
public static function tableize($className) {
|
||||
$replace = self::pluralize(self::underscore($className));
|
||||
return $replace;
|
||||
}
|
||||
/**
|
||||
* Returns Cake model class name ("Post" for the database table "posts".) for given database table.
|
||||
*
|
||||
* @param string $tableName Name of database table to get class name for
|
||||
* @return string
|
||||
*/
|
||||
public static function classify($tableName) {
|
||||
$replace = self::camelize(self::singularize($tableName));
|
||||
return $replace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns camelBacked version of a string.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function variable($string) {
|
||||
$string = self::camelize(self::underscore($string));
|
||||
$replace = strtolower(substr($string, 0, 1));
|
||||
$variable = preg_replace('/\\w/', $replace, $string, 1);
|
||||
return $variable;
|
||||
}
|
||||
/**
|
||||
* Returns a string with all spaces converted to $replacement and non word characters removed.
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $replacement
|
||||
* @return string
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function slug($string, $replacement = '_') {
|
||||
$string = preg_replace(array('/[^\w\s]/', '/\\s+/') , array(' ', $replacement), $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enclose a string for preg matching.
|
||||
*
|
||||
* @param string $string String to enclose
|
||||
* @return string Enclosed string
|
||||
*/
|
||||
public static function enclose($string) {
|
||||
return '(?:' . $string . ')';
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2008 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class LDAP implements ExternalAuthentication
|
||||
{
|
||||
/**
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function authenticate($username,$password)
|
||||
{
|
||||
$connection = ldap_connect(LDAP_SERVER) or die("Couldn't connect to LDAP");
|
||||
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_bind($connection);
|
||||
|
||||
$result = ldap_search($connection,LDAP_DN,LDAP_USERNAME_ATTRIBUTE."=$username");
|
||||
if (ldap_count_entries($connection,$result)) {
|
||||
$entries = ldap_get_entries($connection, $result);
|
||||
|
||||
if (preg_match("/^\{crypt\}(.+)/i",$entries[0][LDAP_PASSWORD_ATTRIBUTE][0],$matches)) {
|
||||
$ldapPassword = $matches[1];
|
||||
$salt = substr($ldapPassword,0,2);
|
||||
|
||||
$encryptedPassword = crypt($password,$salt);
|
||||
if ($encryptedPassword === $ldapPassword) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
throw new Exception('wrongPassword');
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception("passwordIsCorrupted");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception("unknownUser");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a user's password to the LDAP server
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
*/
|
||||
public static function savePassword($username,$password)
|
||||
{
|
||||
$connection = ldap_connect(LDAP_SERVER);
|
||||
ldap_set_option($connection,LDAP_OPT_PROTOCOL_VERSION,3);
|
||||
ldap_bind($connection,
|
||||
LDAP_USERNAME_ATTRIBUTE."=".LDAP_ADMIN_USER.",o=".LDAP_DOMAIN,
|
||||
LDAP_ADMIN_PASS) or die(ldap_error($connection));
|
||||
|
||||
$result = ldap_search($connection,LDAP_DN,LDAP_USERNAME_ATTRIBUTE."=$username");
|
||||
$entries = ldap_get_entries($connection, $result);
|
||||
|
||||
$dn = LDAP_USERNAME_ATTRIBUTE."=$username,ou=people,o=".LDAP_DOMAIN;
|
||||
if ($this->getPassword()) {
|
||||
$salt = substr(md5(time()),0,2);
|
||||
$encryptedPassword = "{CRYPT}".crypt($password,$salt);
|
||||
|
||||
$password = array(LDAP_PASSWORD_ATTRIBUTE=>$encryptedPassword);
|
||||
|
||||
if (isset($entries[0][LDAP_PASSWORD_ATTRIBUTE])) {
|
||||
// Modify
|
||||
ldap_mod_replace($connection,$dn,$password)
|
||||
or die(print_r($password).ldap_error($connection));
|
||||
}
|
||||
else {
|
||||
// Add
|
||||
ldap_mod_add($connection,$dn,$password)
|
||||
or die(print_r($password).ldap_error($connection));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Delete
|
||||
$password = array();
|
||||
ldap_mod_del($connection,$dn,$password)
|
||||
or die(print_r($password).ldap_error($connection));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,526 @@
|
|||
<?php
|
||||
/**
|
||||
* A class for working with entries in LDAP.
|
||||
*
|
||||
* This class is written specifically for the City of Bloomington's
|
||||
* LDAP layout. If you are going to be doing LDAP authentication
|
||||
* with your own LDAP server, you will probably need to customize
|
||||
* the fields used in this class.
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class LDAPEntry
|
||||
{
|
||||
private static $connection;
|
||||
|
||||
private $ou;
|
||||
|
||||
private $uid;
|
||||
private $userPassword;
|
||||
|
||||
private $givenName;
|
||||
private $sn;
|
||||
private $cn;
|
||||
private $displayName;
|
||||
|
||||
private $businessCategory;
|
||||
private $departmentNumber;
|
||||
private $physicalDeliveryOfficeName;
|
||||
private $title;
|
||||
|
||||
private $mail;
|
||||
private $telephoneNumber;
|
||||
private $preferredTelephoneNumber;
|
||||
private $webTelephoneNumber;
|
||||
private $facsimileTelephoneNumber;
|
||||
private $homePhone;
|
||||
private $mobile;
|
||||
private $dialupAccess;
|
||||
|
||||
private $jpegPhoto;
|
||||
|
||||
private $sambaLMPassword;
|
||||
private $sambaNTPassword;
|
||||
private $sambaSID;
|
||||
|
||||
private $objectClasses = array();
|
||||
|
||||
// Used to keep track of changes we make to this entry. This is because LDAP
|
||||
// requires us to send seperate modify, add, and delete commands.
|
||||
private $modifiedAttributes = array();
|
||||
private $addedAttributes = array();
|
||||
private $deletedAttributes = array();
|
||||
|
||||
|
||||
/**
|
||||
* Loads an entry from the LDAP server for the given user
|
||||
* @param string $username
|
||||
*/
|
||||
public function __construct($username=null)
|
||||
{
|
||||
$this->openConnection();
|
||||
|
||||
if ($username) {
|
||||
$result = ldap_search(LDAPEntry::$connection,LDAP_DN,
|
||||
LDAP_USERNAME_ATTRIBUTE."=$username");
|
||||
if (ldap_count_entries(LDAPEntry::$connection,$result)) {
|
||||
$entries = ldap_get_entries(LDAPEntry::$connection, $result);
|
||||
$this->uid = $username;
|
||||
if (isset($entries[0]['ou'])) {
|
||||
$this->ou = $entries[0]['ou'][0];
|
||||
}
|
||||
if (isset($entries[0]['givenname'])) {
|
||||
$this->givenName = $entries[0]['givenname'][0];
|
||||
}
|
||||
if (isset($entries[0]['sn'])) {
|
||||
$this->sn = $entries[0]['sn'][0];
|
||||
}
|
||||
if (isset($entries[0]['cn'])) {
|
||||
$this->cn = $entries[0]['cn'][0];
|
||||
}
|
||||
if (isset($entries[0]['displayname'])) {
|
||||
$this->displayName = $entries[0]['displayname'][0];
|
||||
}
|
||||
if (isset($entries[0]['businesscategory'])) {
|
||||
$this->businessCategory = $entries[0]['businesscategory'][0];
|
||||
}
|
||||
if (isset($entries[0]['departmentnumber'])) {
|
||||
$this->departmentNumber = $entries[0]['departmentnumber'][0];
|
||||
}
|
||||
if (isset($entries[0]['physicaldeliveryofficename'])) {
|
||||
$this->physicalDeliveryOfficeName = $entries[0]['physicaldeliveryofficename'][0];
|
||||
}
|
||||
if (isset($entries[0]['title'])) {
|
||||
$this->title = $entries[0]['title'][0];
|
||||
}
|
||||
if (isset($entries[0]['mail'])) {
|
||||
$this->mail = $entries[0]['mail'][0];
|
||||
}
|
||||
if (isset($entries[0]['telephonenumber'])) {
|
||||
$this->telephoneNumber = $entries[0]['telephonenumber'][0];
|
||||
}
|
||||
if (isset($entries[0]['preferredtelephonenumber'])) {
|
||||
$this->preferredTelephoneNumber = $entries[0]['preferredtelephonenumber'][0];
|
||||
}
|
||||
if (isset($entries[0]['webtelephonenumber'])) {
|
||||
$this->webTelephoneNumber = $entries[0]['webtelephonenumber'][0];
|
||||
}
|
||||
if (isset($entries[0]['facsimiletelephonenumber'])) {
|
||||
$this->facsimileTelephoneNumber = $entries[0]['facsimiletelephonenumber'][0];
|
||||
}
|
||||
if (isset($entries[0]['homephone'])) {
|
||||
$this->homePhone = $entries[0]['homephone'][0];
|
||||
}
|
||||
if (isset($entries[0]['mobile'])) {
|
||||
$this->mobile = $entries[0]['mobile'][0];
|
||||
}
|
||||
if (isset($entries[0]['dialupaccess'])) {
|
||||
$this->dialupAccess = $entries[0]['dialupaccess'][0];
|
||||
}
|
||||
if (isset($entries[0]['objectclass'])) {
|
||||
$this->objectClasses = $entries[0]['objectclass'];
|
||||
}
|
||||
if (isset($entries[0]['jpegphoto'])) {
|
||||
$photo = ldap_get_values_len(LDAPEntry::$connection,
|
||||
ldap_first_entry(LDAPEntry::$connection,$result),
|
||||
'jpegphoto');
|
||||
$this->jpegPhoto = $photo[0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception("ldap/unknownUser");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the connection to the LDAP server
|
||||
*/
|
||||
private function openConnection()
|
||||
{
|
||||
if (!LDAPEntry::$connection) {
|
||||
if (LDAPEntry::$connection = ldap_connect(LDAP_SERVER)) {
|
||||
ldap_set_option(LDAPEntry::$connection,LDAP_OPT_PROTOCOL_VERSION,3);
|
||||
if (LDAP_ADMIN_USER) {
|
||||
if (!ldap_bind(LDAPEntry::$connection,
|
||||
LDAP_USERNAME_ATTRIBUTE."=".LDAP_ADMIN_USER.",o=".LDAP_DOMAIN,
|
||||
LDAP_ADMIN_PASS)) {
|
||||
throw new Exception(ldap_error(LDAPEntry::$connection));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!ldap_bind(LDAPEntry::$connection)) {
|
||||
throw new Exception(ldap_error(LDAPEntry::$connection));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception(ldap_error(LDAPEntry::$connection));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any changed information back to the LDAP server
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$dn = "uid={$this->uid},ou=people,o=".LDAP_DOMAIN;
|
||||
if (count($this->modifiedAttributes)) {
|
||||
ldap_mod_replace(LDAPEntry::$connection,$dn,$this->modifiedAttributes)
|
||||
or die(print_r($this->modifiedAttributes).ldap_error(LDAPEntry::$connection));
|
||||
}
|
||||
if (count($this->addedAttributes)) {
|
||||
ldap_mod_add(LDAPEntry::$connection,$dn,$this->addedAttributes)
|
||||
or die(print_r($this->addedAttributes).ldap_error(LDAPEntry::$connection));
|
||||
}
|
||||
if (count($this->deletedAttributes)) {
|
||||
ldap_mod_del(LDAPEntry::$connection,$dn,$this->deletedAttributes)
|
||||
or die(print_r($this->deletedAttributes).ldap_error(LDAPEntry::$connection));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes any problematic characters
|
||||
* @param string $str
|
||||
*/
|
||||
private function sanitize($str)
|
||||
{
|
||||
$tmp = trim($str);
|
||||
$tmp = str_replace('\\', '\\\\', $tmp);
|
||||
$tmp = str_replace('(', '\(', $tmp);
|
||||
$tmp = str_replace(')', '\)', $tmp);
|
||||
$tmp = str_replace('*', '\*', $tmp);
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps track of what properties have been changed
|
||||
*
|
||||
* All setters should call this function. Otherwise, we won't
|
||||
* know what's been changed in order to do the appropriate calls in LDAP
|
||||
* @param string $property
|
||||
* @param string $value
|
||||
*/
|
||||
private function changeProperty($property,$value)
|
||||
{
|
||||
if ($value) {
|
||||
if ($value != $this->{$property}) {
|
||||
if ($this->{$property}) {
|
||||
$this->modifiedAttributes[$property] = $value;
|
||||
}
|
||||
else {
|
||||
$this->addedAttributes[$property] = $value;
|
||||
}
|
||||
$this->{$property} = $value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($this->{$property}) {
|
||||
$this->{$property} = '';
|
||||
$this->deletedAttributes[$property] = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOU()
|
||||
{
|
||||
return $this->ou;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUID()
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFirstname()
|
||||
{
|
||||
return $this->givenName;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLastname()
|
||||
{
|
||||
return $this->sn;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCommonName()
|
||||
{
|
||||
return $this->cn;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->displayName;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBusinessCategory()
|
||||
{
|
||||
return $this->businessCategory;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDepartment()
|
||||
{
|
||||
return $this->departmentNumber;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOffice()
|
||||
{
|
||||
return $this->physicalDeliveryOfficeName;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail()
|
||||
{
|
||||
return $this->mail;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPhone()
|
||||
{
|
||||
return $this->telephoneNumber;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPreferredPhone()
|
||||
{
|
||||
return $this->preferredTelephoneNumber;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getWebPhone()
|
||||
{
|
||||
return $this->webTelephoneNumber;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFax()
|
||||
{
|
||||
return $this->facsimileTelephoneNumber;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHomePhone()
|
||||
{
|
||||
return $this->homePhone;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCellPhone()
|
||||
{
|
||||
return $this->mobile;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDialup()
|
||||
{
|
||||
return $this->dialupAccess;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSambaLMPassword()
|
||||
{
|
||||
return $this->sambaLMPassword;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSambaNTPassword()
|
||||
{
|
||||
return $this->sambaNTPassword;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSambaSID()
|
||||
{
|
||||
return $this->sambaSID;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getObjectClasses()
|
||||
{
|
||||
return $this->objectClasses;
|
||||
}
|
||||
/**
|
||||
* @return raw
|
||||
*/
|
||||
public function getPhoto()
|
||||
{
|
||||
return $this->jpegPhoto;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setUsername($string)
|
||||
{
|
||||
$this->changeProperty("uid",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setFirstname($string)
|
||||
{
|
||||
$this->changeProperty("givenName",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setLastname($string)
|
||||
{
|
||||
$this->changeProperty("sn",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setCommonName($string)
|
||||
{
|
||||
$this->changeProperty("cn",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setDisplayName($string)
|
||||
{
|
||||
$this->changeProperty("displayName",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setBusinessCategory($string)
|
||||
{
|
||||
$this->changeProperty("businessCategory",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setDepartment($string)
|
||||
{
|
||||
$this->changeProperty("departmentNumber",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setOffice($string)
|
||||
{
|
||||
$this->changeProperty("physicalDeliveryOfficeName",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setTitle($string)
|
||||
{
|
||||
$this->changeProperty("title",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setEmail($string)
|
||||
{
|
||||
$this->changeProperty("mail",$this->sanitize($string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setPhone($string)
|
||||
{
|
||||
$this->changeProperty("telephoneNumber",preg_replace('/[^0-9ext\-\s]/','',$string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setPreferredPhone($string)
|
||||
{
|
||||
$this->changeProperty('preferredTelephoneNumber',
|
||||
preg_replace('/[^0-9ext\-\s]/','',$string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setWebPhone($string)
|
||||
{
|
||||
$this->changeProperty('webTelephoneNumber',
|
||||
preg_replace('/[^0-9ext\-\s]/','',$string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setFax($string)
|
||||
{
|
||||
$this->changeProperty('facsimileTelephoneNumber',
|
||||
preg_replace('/[^0-9ext\-\s]/','',$string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setHomePhone($string)
|
||||
{
|
||||
$this->changeProperty('homePhone',preg_replace('/[^0-9ext\-\s]/','',$string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setCellPhone($string)
|
||||
{
|
||||
$this->changeProperty('mobile',preg_replace('/[^0-9ext\-\s]/','',$string));
|
||||
}
|
||||
/**
|
||||
* @param string $string
|
||||
*/
|
||||
public function setDialup($string)
|
||||
{
|
||||
$this->changeProperty('dialupAccess',preg_replace('/[^0-9ext\-\s]/','',$string));
|
||||
}
|
||||
/**
|
||||
* @param string $filePath
|
||||
*/
|
||||
public function setPhoto($filePath)
|
||||
{
|
||||
$this->changeProperty("jpegPhoto",file_get_contents($filePath));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
/**
|
||||
* Takes an array and splits it up into pages (an array of arrays)
|
||||
*
|
||||
* @copyright 2008-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Paginator implements ArrayAccess,SeekableIterator,Countable
|
||||
{
|
||||
private $pageSize;
|
||||
private $pages = array();
|
||||
private $key = 0;
|
||||
|
||||
/**
|
||||
* @param array $list
|
||||
* @param int $pageSize
|
||||
*/
|
||||
public function __construct($list,$pageSize)
|
||||
{
|
||||
$this->pageSize = $pageSize;
|
||||
$totalPageCount = count($list) / $this->pageSize;
|
||||
for ($i=0; $i<$totalPageCount; $i++) {
|
||||
$this->pages[] = $i * $this->pageSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements per page
|
||||
* @return int
|
||||
*/
|
||||
public function getPageSize()
|
||||
{
|
||||
return $this->pageSize;
|
||||
}
|
||||
/**
|
||||
* Returns the vary last index number for this paginator
|
||||
* @return int
|
||||
*/
|
||||
public function getLastIndex()
|
||||
{
|
||||
return count($this->pages)-1;
|
||||
}
|
||||
|
||||
// Array Access section
|
||||
/**
|
||||
* @param int $offset
|
||||
* @return boolean
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return array_key_exists($offset,$this->pages);
|
||||
}
|
||||
/**
|
||||
* Returns the array of elements for a given page
|
||||
* @param int $offset
|
||||
* @return array
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->pages[$offset];
|
||||
}
|
||||
/**
|
||||
* Unimplemented stub required for SPLIterator interface
|
||||
* Once created, paginators are read-only
|
||||
*/
|
||||
public function offsetSet($offset,$value)
|
||||
{
|
||||
// Read-only for now
|
||||
}
|
||||
/**
|
||||
* Unimplemented stub required for SPLIterator interface
|
||||
* Once created, paginators are read-only
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
// Read only for now
|
||||
}
|
||||
|
||||
|
||||
// Iterator Interface stuff
|
||||
/**
|
||||
* Reset the iterator to the start
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->key = 0;
|
||||
}
|
||||
/**
|
||||
* Move the pointer to the next element
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->key++;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return array_key_exists($this->key,$this->pages);
|
||||
}
|
||||
/**
|
||||
* Return the array of element for the current page
|
||||
* @return array
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->pages[$this->key];
|
||||
}
|
||||
/**
|
||||
* Go to a specific page
|
||||
* @param int $index
|
||||
*/
|
||||
public function seek($index)
|
||||
{
|
||||
if (isset($this->pages[$index])) {
|
||||
$this->key = $index;
|
||||
}
|
||||
else {
|
||||
throw new OutOfBoundsException('Invalid seek position');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return Iterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Countable interface section
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->pages);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
/**
|
||||
* Handles authentication and password handling for all city LDAP people.
|
||||
*
|
||||
* Applications should extend this class for their own users. That way,
|
||||
* a city employee will have the same username and password on all applications.
|
||||
* Applications should use these public functions for their own users.
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
abstract class SystemUser
|
||||
{
|
||||
abstract public function getId();
|
||||
abstract public function getUsername();
|
||||
abstract public function getAuthenticationMethod();
|
||||
abstract public function getRoles();
|
||||
|
||||
abstract public function hasRole($roles);
|
||||
|
||||
abstract public function setAuthenticationMethod($method);
|
||||
abstract public function setRoles($roles);
|
||||
abstract public function setUsername($username);
|
||||
|
||||
/**
|
||||
* Passwords are set in clear text. The only times you would want to set a password
|
||||
* is when you're adding a new password or changing a person's password.
|
||||
* Either way, it's up to the individual save routines to handle encrypting the new password
|
||||
* before storing it. Passwords should not be loaded in the constructor - they're
|
||||
* supposed to be encrypted, so what's the point?
|
||||
*/
|
||||
abstract public function setPassword($password);
|
||||
|
||||
/**
|
||||
* Used to hand authentication off to the application
|
||||
*/
|
||||
abstract protected function authenticateDatabase($password);
|
||||
|
||||
/**
|
||||
* Used to hand password saving off to the application
|
||||
*/
|
||||
abstract protected function saveLocalPassword();
|
||||
|
||||
/**
|
||||
* Determines which authentication scheme to use for the user and calls the appropriate method
|
||||
*
|
||||
* @param string $password
|
||||
* @return boolean
|
||||
*/
|
||||
public function authenticate($password)
|
||||
{
|
||||
switch($this->getAuthenticationMethod()) {
|
||||
case "local":
|
||||
return $this->authenticateDatabase($password);
|
||||
break;
|
||||
|
||||
default:
|
||||
$type = $this->getAuthenticationMethod();
|
||||
return call_user_func(array($type,'authenticate'),$this->getUsername(),$password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes a new Session and loads the default information for the user
|
||||
*/
|
||||
public function startNewSession()
|
||||
{
|
||||
session_destroy();
|
||||
session_start();
|
||||
|
||||
$_SESSION['USER'] = $this;
|
||||
$_SESSION['IP_ADDRESS'] = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which authentication method is being used, and sends the password to the
|
||||
* appropriate method
|
||||
*/
|
||||
public function savePassword()
|
||||
{
|
||||
switch($this->getAuthenticationMethod()) {
|
||||
case "local":
|
||||
$this->saveLocalPassword();
|
||||
break;
|
||||
|
||||
default:
|
||||
$type = $this->getAuthenticationMethod();
|
||||
call_user_func(array($type,'savePassword'),$this->getUsername(),$password);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
/**
|
||||
* Defines the overall page layout
|
||||
*
|
||||
* The template collects all the blocks from the controller
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class Template extends View
|
||||
{
|
||||
private $filename;
|
||||
public $outputFormat = 'html';
|
||||
public $blocks = array();
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param string $outputFormat
|
||||
* @param array $vars
|
||||
*/
|
||||
public function __construct($filename='default',$outputFormat='html',array $vars=null)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
$this->outputFormat = preg_replace('/[^a-zA-Z]/','',$outputFormat);
|
||||
|
||||
// Make sure the output format exists
|
||||
if (!is_file(APPLICATION_HOME."/templates/{$this->outputFormat}/{$this->filename}.inc")) {
|
||||
$this->filename = 'default';
|
||||
$this->outputFormat = 'html';
|
||||
}
|
||||
|
||||
if (count($vars)) {
|
||||
foreach ($vars as $name=>$value) {
|
||||
$this->vars[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the rendered content of the template
|
||||
*
|
||||
* Template files must include a call to $this->includeBlocks(),
|
||||
* when they're ready for content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
ob_start();
|
||||
include APPLICATION_HOME."/templates/{$this->outputFormat}/{$this->filename}.inc";
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for template files
|
||||
*
|
||||
* Renders blocks for the main content area, unless $panel is given. If $panel is given
|
||||
* it will render any blocks that the controllers have assigned to that panel.
|
||||
*
|
||||
* Template files make calls to this function to render all the blocks that the controller
|
||||
* has loaded for this Template. Controllers will populate the blocks array with content.
|
||||
* If a template file can render content in a panel that is not the main content panel,
|
||||
* the template file will need to include the panel's name in the includeBlocks() call.
|
||||
*
|
||||
* $this->blocks is a multi-dimensional array. The top level elements, non-array elements
|
||||
* are for the default, main content area. Other panels will be arrays in $this->blocks with
|
||||
* the panel name as the key.
|
||||
*
|
||||
* Panels are nothing but a name on a div, the $panel string can be whatever the template
|
||||
* author thinks makes sense. Controllers are expected to know what the template authors
|
||||
* have written.
|
||||
*
|
||||
* $this->blocks[] = "main content block one";
|
||||
* $this->blocks[] = "main content block two";
|
||||
* $this->blocks['panel-one'][] = "left sidebar block one";
|
||||
* $this->blocks['panel-one'][] = "left sidebar block two";
|
||||
* $this->blocks['panel-two'][] = "right sidebar block one";
|
||||
*
|
||||
* @param string $panel
|
||||
* @return string
|
||||
*/
|
||||
private function includeBlocks($panel=null)
|
||||
{
|
||||
ob_start();
|
||||
if ($panel) {
|
||||
// Render any blocks for the given panel
|
||||
if (isset($this->blocks[$panel]) && is_array($this->blocks[$panel])) {
|
||||
foreach ($this->blocks[$panel] as $block) {
|
||||
echo $block->render($this->outputFormat);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// Render only the blocks for the main content area
|
||||
foreach ($this->blocks as $block) {
|
||||
if (!is_array($block)) {
|
||||
echo $block->render($this->outputFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
/**
|
||||
* Helper class for URL handling. Parses URLs and allows adding parameters from variables.
|
||||
*
|
||||
* $url = new URL('/path/to/webpage.php?initialParameter=whatever');
|
||||
* $url->parameters['somevar'] = $somevar;
|
||||
* $url->somevar = $somevar;
|
||||
* echo $url->getURL();
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana.
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
class URL
|
||||
{
|
||||
private $scheme;
|
||||
private $host;
|
||||
private $path;
|
||||
private $anchor;
|
||||
|
||||
public $parameters = array();
|
||||
|
||||
public function __construct($script)
|
||||
{
|
||||
$script = urldecode($script);
|
||||
|
||||
// If scheme wasn't provided add one to the start of the string
|
||||
if (!preg_match('|://|',$script)) {
|
||||
$scheme = $_SERVER['SERVER_PORT']==443 ? 'https://' : 'http://';
|
||||
$script = $scheme.$script;
|
||||
}
|
||||
|
||||
$url = parse_url($script);
|
||||
$this->scheme = $url['scheme'];
|
||||
$this->host = $url['host'];
|
||||
$this->path = $url['path'];
|
||||
if (isset($url['fragment'])) {
|
||||
$this->anchor = $url['fragment'];
|
||||
}
|
||||
if (isset($url['query'])) {
|
||||
parse_str($url['query'],$this->parameters);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns just the base portion of the url
|
||||
* @return string
|
||||
*/
|
||||
public function getScript() {
|
||||
return $this->scheme.'://'.$this->host.$this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full, properly formatted and escaped URL
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->getURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full, properly formatted and escaped URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getURL()
|
||||
{
|
||||
$url = $this->getScript();
|
||||
|
||||
if (count($this->parameters)) {
|
||||
$url.= '?'.http_build_query($this->parameters,'');
|
||||
}
|
||||
|
||||
if ($this->anchor) {
|
||||
$url.= '#'.$this->anchor;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns just the protocol (http://, https://) portion
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme() {
|
||||
if (!$this->scheme) {
|
||||
$this->scheme = 'http://';
|
||||
}
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the protocol for the URL (http, https)
|
||||
* @param string $protocol
|
||||
*/
|
||||
public function setScheme($string)
|
||||
{
|
||||
if (!preg_match('|://|',$string)) {
|
||||
$string .= '://';
|
||||
}
|
||||
$this->scheme = $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans out any query parameters that had empty values
|
||||
*/
|
||||
public function purgeEmptyParameters()
|
||||
{
|
||||
$this->parameters = $this->array_filter_recursive($this->parameters);
|
||||
}
|
||||
|
||||
private function array_filter_recursive(array $input)
|
||||
{
|
||||
foreach ($input as &$value) {
|
||||
if (is_array($value)) {
|
||||
$value = $this->array_filter_recursive($value);
|
||||
}
|
||||
}
|
||||
return array_filter($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
if (isset($this->parameters[$key])) {
|
||||
return $this->parameters[$key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function __set($key,$value)
|
||||
{
|
||||
$this->parameters[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return isset($this->parameters[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
unset($this->parameters[$key]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
abstract class View
|
||||
{
|
||||
protected $vars = array();
|
||||
|
||||
abstract public function render();
|
||||
|
||||
/**
|
||||
* Magic Method for setting object properties
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set($key,$value) {
|
||||
$this->vars[$key] = $value;
|
||||
}
|
||||
/**
|
||||
* Magic method for getting object properties
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
if (isset($this->vars[$key])) {
|
||||
return $this->vars[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset($key) {
|
||||
return array_key_exists($key,$this->vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans strings for output
|
||||
*
|
||||
* There are more bad characters than htmlspecialchars deals with. We just want
|
||||
* to add in some other characters to clean. While here, we might as well
|
||||
* have it trim out the whitespace too.
|
||||
*
|
||||
* @param array|string $string
|
||||
* @param CONSTANT $quotes Optional, the desired constant to use for the htmlspecidalchars call
|
||||
* @return string
|
||||
*/
|
||||
public static function escape($input,$quotes=ENT_QUOTES)
|
||||
{
|
||||
if (is_array($input)) {
|
||||
foreach ($input as $key=>$value) {
|
||||
$input[$key] = self::escape($value,$quotes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$input = htmlspecialchars(trim($input),$quotes);
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first $n words of the given string
|
||||
*
|
||||
* @param string $string Source string
|
||||
* @param int $numWords Number of words
|
||||
* @return string
|
||||
*/
|
||||
public static function limitWords($string,$numWords)
|
||||
{
|
||||
$output = '';
|
||||
$words = preg_split('/\s+/',$string);
|
||||
$c = 0;
|
||||
foreach ($words as $word) {
|
||||
$output.= "$word ";
|
||||
$c++;
|
||||
if ($c >= $numWords) {
|
||||
$output.= '...';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*
|
||||
*/
|
||||
abstract class ZendDbResultIterator implements ArrayAccess,SeekableIterator,Countable
|
||||
{
|
||||
protected $zend_db;
|
||||
protected $select;
|
||||
protected $result = array();
|
||||
|
||||
protected $paginator = null;
|
||||
protected $itemsPerPage = null;
|
||||
protected $currentPage = 1;
|
||||
|
||||
private $valid = false;
|
||||
private $cacheEnabled = true;
|
||||
private $cache = array();
|
||||
private $key;
|
||||
|
||||
|
||||
abstract public function find($fields=null,$order='',$limit=null,$groupBy=null);
|
||||
abstract protected function loadResult($key);
|
||||
|
||||
/**
|
||||
* Creates an empty collection
|
||||
*
|
||||
* Setting itemsPerPage turns on pagination mode
|
||||
* In pagination mode, this will only load the results for one page
|
||||
*/
|
||||
public function __construct($itemsPerPage=null,$currentPage=null)
|
||||
{
|
||||
$this->zend_db = Database::getConnection();
|
||||
$this->select = new Zend_Db_Select($this->zend_db);
|
||||
|
||||
if ($itemsPerPage) {
|
||||
$this->itemsPerPage = (integer)$itemsPerPage;
|
||||
|
||||
if ($currentPage && $currentPage > 1) {
|
||||
$this->currentPage = $currentPage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the query and stores the results
|
||||
*
|
||||
* In pagination mode, this will only load the results for one page
|
||||
*/
|
||||
protected function populateList()
|
||||
{
|
||||
$this->result = array();
|
||||
if (!$this->itemsPerPage) {
|
||||
$this->result = $this->zend_db->fetchAll($this->select);
|
||||
}
|
||||
else {
|
||||
// Only load the results for one page
|
||||
$this->paginator = new Zend_Paginator(new Zend_Paginator_Adapter_DbSelect($this->select));
|
||||
$this->paginator->setItemCountPerPage($this->itemsPerPage);
|
||||
$this->paginator->setCurrentPageNumber($this->currentPage);
|
||||
foreach ($this->paginator as $row) {
|
||||
$this->result[] = $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSQL()
|
||||
{
|
||||
return $this->select->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Zend_Paginator
|
||||
*/
|
||||
public function getPaginator()
|
||||
{
|
||||
return $this->paginator;
|
||||
}
|
||||
|
||||
// Array Access section
|
||||
/**
|
||||
* @param int $offset
|
||||
* @return boolean
|
||||
*/
|
||||
public function offsetExists($offset) {
|
||||
return array_key_exists($offset,$this->result);
|
||||
}
|
||||
/**
|
||||
* Unimplemented stub requried for interface compliance
|
||||
* @ignore
|
||||
*/
|
||||
public function offsetSet($offset,$value) { } // Read-only for now
|
||||
/**
|
||||
* Unimplemented stub requried for interface compliance
|
||||
* @ignore
|
||||
*/
|
||||
public function offsetUnset($offset) { } // Read-only for now
|
||||
/**
|
||||
* @param int $offset
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->offsetExists($offset)) {
|
||||
return $this->loadResult($offset);
|
||||
}
|
||||
else {
|
||||
throw new OutOfBoundsException('Invalid seek position');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SPLIterator Section
|
||||
/**
|
||||
* Reset the pionter to the first element
|
||||
*/
|
||||
public function rewind() {
|
||||
$this->key = 0;
|
||||
}
|
||||
/**
|
||||
* Advance to the next element
|
||||
*/
|
||||
public function next() {
|
||||
$this->key++;
|
||||
}
|
||||
/**
|
||||
* Return the index of the current element
|
||||
* @return int
|
||||
*/
|
||||
public function key() {
|
||||
return $this->key;
|
||||
}
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid() {
|
||||
return array_key_exists($this->key,$this->result);
|
||||
}
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->loadResult($this->key);
|
||||
}
|
||||
/**
|
||||
* @param int $index
|
||||
*/
|
||||
public function seek($index)
|
||||
{
|
||||
if (isset($this->result[$index])) {
|
||||
$this->key = $index;
|
||||
}
|
||||
else {
|
||||
throw new OutOfBoundsException('Invalid seek position');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Countable Section
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2007-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
if (isset($_SESSION['errorMessages'])) {
|
||||
$errorBlock = new Block('errorMessages.inc',array('errorMessages'=>$_SESSION['errorMessages']));
|
||||
echo $errorBlock->render($this->outputFormat);
|
||||
unset($_SESSION['errorMessages']);
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
/**
|
||||
* Global, shared functions for all PHP web applications
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana.
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
* @package GlobalFunctions
|
||||
*/
|
||||
/**
|
||||
* Load classes on the fly as needed
|
||||
* @param string $class
|
||||
*/
|
||||
function autoload($class)
|
||||
{
|
||||
if (file_exists(APPLICATION_HOME."/classes/$class.php")) {
|
||||
require_once(APPLICATION_HOME."/classes/$class.php");
|
||||
}
|
||||
elseif (file_exists(FRAMEWORK."/classes/$class.php")) {
|
||||
require_once(FRAMEWORK."/classes/$class.php");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide nicely formatted error messages when PHP bombs out.
|
||||
*/
|
||||
function customErrorHandler ($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
global $ERROR_REPORTING;
|
||||
|
||||
if (isset($ERROR_REPORTING)) {
|
||||
if (in_array('PRETTY_PRINT',$ERROR_REPORTING)) {
|
||||
echo "
|
||||
<div id=\"errorMessages\">
|
||||
<p><em>from ".ADMINISTRATOR_NAME.":</em>
|
||||
There is an error in the code on this page that is through no fault of your own.
|
||||
Errors of this sort need to be fixed immediately, though.
|
||||
Please help us out by copying and pasting the following error message into an email and sending it to me at
|
||||
<a href=\"mailto:".ADMINISTRATOR_EMAIL."\">".ADMINISTRATOR_EMAIL."</a>.
|
||||
</p>
|
||||
<p><strong>Code Error:</strong> Error on line $errline of file $errfile:</p>
|
||||
<p>$errstr</p>
|
||||
</div>
|
||||
";
|
||||
}
|
||||
if (in_array('EMAIL_ADMIN',$ERROR_REPORTING)) {
|
||||
$subject = APPLICATION_NAME.' Error';
|
||||
$message = "\t$_SERVER[REQUEST_URI]\n\nError on line $errline of file $errfile:\n$errstr\n\n";
|
||||
$message.= print_r(debug_backtrace(),true);
|
||||
mail(ADMINISTRATOR_EMAIL,$subject,$message,"From: apache@$_SERVER[SERVER_NAME]");
|
||||
}
|
||||
|
||||
if (in_array('EMAIL_USER',$ERROR_REPORTING)
|
||||
&& isset($_SESSION['USER'])
|
||||
&& $_SESSION['USER']->getEmail()) {
|
||||
$subject = APPLICATION_NAME.' Error';
|
||||
$message = "\t$_SERVER[REQUEST_URI]\n\nError on line $errline of file $errfile:\n$errstr\n\n";
|
||||
$message.= print_r(debug_backtrace(),true);
|
||||
mail($_SESSION['USER']->getEmail(),
|
||||
$subject,
|
||||
$message,
|
||||
"From: apache@$_SERVER[SERVER_NAME]");
|
||||
}
|
||||
if (in_array('SKIDDER',$ERROR_REPORTING)) {
|
||||
$message = "Error on line $errline of file $errfile:\n$errstr\n";
|
||||
$message.= print_r(debug_backtrace(),true);
|
||||
|
||||
$skidder = curl_init(SKIDDER_URL);
|
||||
curl_setopt($skidder,CURLOPT_POST,true);
|
||||
curl_setopt($skidder,CURLOPT_HEADER,true);
|
||||
curl_setopt($skidder,CURLOPT_RETURNTRANSFER,true);
|
||||
curl_setopt($skidder,
|
||||
CURLOPT_POSTFIELDS,
|
||||
array('application_id'=>SKIDDER_APPLICATION_ID,
|
||||
'script'=>$_SERVER['REQUEST_URI'],
|
||||
'type'=>$errstr,
|
||||
'message'=>$message));
|
||||
curl_exec($skidder);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ERROR_REPORTING != 'PHP_DEFAULT') {
|
||||
set_error_handler('customErrorHandler');
|
||||
}
|
||||
|
||||
/**
|
||||
* Object oriented exceptions are handled differently from other PHP errors.
|
||||
*/
|
||||
function customExceptionHandler($exception)
|
||||
{
|
||||
global $ERROR_REPORTING;
|
||||
|
||||
if (isset($ERROR_REPORTING)) {
|
||||
if (in_array('PRETTY_PRINT',$ERROR_REPORTING)) {
|
||||
echo "
|
||||
<div id=\"errorMessages\">
|
||||
<p><em>from ".ADMINISTRATOR_NAME.":</em>
|
||||
There is an error in the code on this page that is through no fault of your own.
|
||||
Errors of this sort need to be fixed immediately, though.
|
||||
Please help me out by copying and pasting the following error message into an email and sending it to me at
|
||||
<a href=\"mailto:".ADMINISTRATOR_EMAIL."\">".ADMINISTRATOR_EMAIL."</a>.
|
||||
</p>
|
||||
<p><strong>Uncaught exception:</strong>
|
||||
Exception on line {$exception->getLine()} of file {$exception->getFile()}:
|
||||
</p>
|
||||
<p>{$exception->getMessage()}</p>
|
||||
</div>
|
||||
";
|
||||
}
|
||||
if (in_array('EMAIL_ADMIN',$ERROR_REPORTING)) {
|
||||
$subject = APPLICATION_NAME.' Exception';
|
||||
$message = "\t$_SERVER[REQUEST_URI]\n\nException on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n\n";
|
||||
$message.= print_r(debug_backtrace(),true);
|
||||
mail(ADMINISTRATOR_EMAIL,$subject,$message,"From: apache@$_SERVER[SERVER_NAME]");
|
||||
}
|
||||
if (in_array('EMAIL_USER',$ERROR_REPORTING)
|
||||
&& isset($_SESSION['USER'])
|
||||
&& $_SESSION['USER']->getEmail()) {
|
||||
$subject = APPLICATION_NAME.' Exception';
|
||||
$message = "\t$_SERVER[REQUEST_URI]\n\nException on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n\n";
|
||||
$message.= print_r(debug_backtrace(),true);
|
||||
mail($_SESSION['USER']->getEmail(),
|
||||
$subject,
|
||||
$message,
|
||||
"From: apache@$_SERVER[SERVER_NAME]");
|
||||
}
|
||||
if (in_array('SKIDDER',$ERROR_REPORTING)) {
|
||||
$message = "Error on line {$exception->getLine()} of file {$exception->getFile()}:\n{$exception->getMessage()}\n";
|
||||
$message.= print_r(debug_backtrace(),true);
|
||||
|
||||
$skidder = curl_init(SKIDDER_URL);
|
||||
curl_setopt($skidder,CURLOPT_POST,true);
|
||||
curl_setopt($skidder,CURLOPT_HEADER,true);
|
||||
curl_setopt($skidder,CURLOPT_RETURNTRANSFER,true);
|
||||
curl_setopt($skidder,
|
||||
CURLOPT_POSTFIELDS,
|
||||
array('application_id'=>SKIDDER_APPLICATION_ID,
|
||||
'script'=>$_SERVER['REQUEST_URI'],
|
||||
'type'=>'Uncaught Exception',
|
||||
'message'=>$message));
|
||||
curl_exec($skidder);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ERROR_REPORTING != 'PHP_DEFAULT') {
|
||||
set_exception_handler('customExceptionHandler');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user is logged in and is supposed to have acces to the resource
|
||||
*
|
||||
* This is implemented by checking against a Zend_Acl object
|
||||
* The Zend_Acl should be created in configuration.inc
|
||||
* @param Zend_Acl_Resource|string $resource
|
||||
* @return boolean
|
||||
*/
|
||||
function userIsAllowed($resource)
|
||||
{
|
||||
global $ZEND_ACL;
|
||||
if (isset($_SESSION['USER'])) {
|
||||
foreach ($_SESSION['USER']->getRoles() as $role) {
|
||||
if ($ZEND_ACL->isAllowed($role,$resource)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
/* SVN FILE: $Id: inflections.php 3028 2006-06-08 02:18:18Z phpnut $ */
|
||||
/**
|
||||
* Custom Inflected Words.
|
||||
*
|
||||
* This file is used to hold words that are not matched in the normail Inflector::pluralize() and
|
||||
* Inflector::singularize()
|
||||
*
|
||||
* Orinally written by the CakePHP Project
|
||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||
* Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*
|
||||
* Modified to work in City of Bloomington's Framework
|
||||
* Relicensed under GPL
|
||||
* Redistributions must retain all copyright notices
|
||||
* @copyright 2006 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
*/
|
||||
/**
|
||||
* This is a key => value array of regex used to match words.
|
||||
* If key matches then the value is returned.
|
||||
*
|
||||
* $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
|
||||
*/
|
||||
$pluralRules = array();
|
||||
/**
|
||||
* This is a key only array of plural words that should not be inflected.
|
||||
* Notice the last comma
|
||||
*
|
||||
* $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
|
||||
*/
|
||||
$uninflectedPlural = array();
|
||||
/**
|
||||
* This is a key => value array of plural irregular words.
|
||||
* If key matches then the value is returned.
|
||||
*
|
||||
* $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
|
||||
*/
|
||||
$irregularPlural = array();
|
||||
/**
|
||||
* This is a key => value array of regex used to match words.
|
||||
* If key matches then the value is returned.
|
||||
*
|
||||
* $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
|
||||
*/
|
||||
$singularRules = array();
|
||||
/**
|
||||
* This is a key only array of singular words that should not be inflected.
|
||||
* You should not have to change this value below if you do change it use same format
|
||||
* as the $uninflectedPlural above.
|
||||
*/
|
||||
$uninflectedSingular = $uninflectedPlural;
|
||||
/**
|
||||
* This is a key => value array of singular irregular words.
|
||||
* Most of the time this will be a reverse of the above $irregularPlural array
|
||||
* You should not have to change this value below if you do change it use same format
|
||||
*
|
||||
* $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
|
||||
*/
|
||||
$irregularSingular = array_flip($irregularPlural);
|
||||
?>
|
|
@ -0,0 +1,330 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
include '../configuration.inc';
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
foreach ($zend_db->listTables() as $tableName) {
|
||||
$fields = array();
|
||||
$primary_keys = array();
|
||||
foreach ($zend_db->describeTable($tableName) as $row) {
|
||||
$type = preg_replace("/[^a-z]/","",strtolower($row['DATA_TYPE']));
|
||||
|
||||
// Translate database datatypes into PHP datatypes
|
||||
if (preg_match('/int/',$type)) {
|
||||
$type = 'int';
|
||||
}
|
||||
if (preg_match('/enum/',$type) || preg_match('/varchar/',$type)) {
|
||||
$type = 'string';
|
||||
}
|
||||
|
||||
$fields[] = array('field'=>$row['COLUMN_NAME'],'type'=>$type);
|
||||
|
||||
if ($row['PRIMARY']) {
|
||||
$primary_keys[] = $row['COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
// Only generate code for tables that have a single-column primary key
|
||||
// Code for other tables will need to be created by hand
|
||||
if (count($primary_keys) != 1) {
|
||||
continue;
|
||||
}
|
||||
$key = $primary_keys[0];
|
||||
|
||||
$tableName = strtolower($tableName);
|
||||
$className = Inflector::classify($tableName);
|
||||
$variableName = Inflector::singularize($tableName);
|
||||
$acl_resource = ucfirst($tableName);
|
||||
|
||||
/**
|
||||
* Generate the list block
|
||||
*/
|
||||
$getId = "get".ucwords($key);
|
||||
$HTML = "<div class=\"interfaceBox\">
|
||||
<h1>
|
||||
<?php
|
||||
if (userIsAllowed('$acl_resource')) {
|
||||
echo \"
|
||||
<button type=\\\"button\\\" class=\\\"add\\\" onclick=\\\"document.location.href='\".BASE_URL.\"/$tableName/add$className.php';\\\">
|
||||
Add
|
||||
</button>
|
||||
\";
|
||||
}
|
||||
?>
|
||||
{$className}s
|
||||
</h1>
|
||||
<ul><?php
|
||||
foreach (\$this->{$variableName}List as \${$variableName}) {
|
||||
\$editButton = '';
|
||||
if (userIsAllowed('$acl_resource')) {
|
||||
\$url = new URL(BASE_URL.'/$tableName/update$className.php');
|
||||
\$url->$key = \${$variableName}->{$getId}();
|
||||
\$editButton = \"
|
||||
<button type=\\\"button\\\" class=\\\"edit\\\" onclick=\\\"document.location.href='\$url';\\\">
|
||||
Edit
|
||||
</button>
|
||||
\";
|
||||
}
|
||||
echo \"<li>\$editButton \$$variableName</li>\";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>";
|
||||
|
||||
$contents = "<?php\n";
|
||||
$contents.= COPYRIGHT;
|
||||
$contents.="
|
||||
?>
|
||||
$HTML";
|
||||
|
||||
$dir = APPLICATION_HOME."/scripts/stubs/blocks/$tableName";
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir,0770,true);
|
||||
}
|
||||
file_put_contents("$dir/{$variableName}List.inc",$contents);
|
||||
|
||||
|
||||
/**
|
||||
* Generate the addForm
|
||||
*/
|
||||
$HTML = "<h1>Add $className</h1>
|
||||
<form method=\"post\" action=\"<?php echo \$_SERVER['SCRIPT_NAME']; ?>\">
|
||||
<fieldset><legend>$className Info</legend>
|
||||
<table>
|
||||
";
|
||||
foreach ($fields as $field) {
|
||||
if ($field['field'] != $key) {
|
||||
$fieldFunctionName = ucwords($field['field']);
|
||||
switch ($field['type']) {
|
||||
case 'date':
|
||||
$HTML.="
|
||||
<tr><td><label for=\"{$variableName}-$field[field]-mon\">$field[field]</label></td>
|
||||
<td><select name=\"{$variableName}[$field[field]][mon]\" id=\"{$variableName}-$field[field]-mon\">
|
||||
<option></option>
|
||||
<?php
|
||||
\$now = getdate();
|
||||
for (\$i=1; \$i<=12; \$i++) {
|
||||
\$selected = (\$i==\$now['mon']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name=\"{$variableName}[$field[field]][mday]\">
|
||||
<option></option>
|
||||
<?php
|
||||
for (\$i=1; \$i<=31; \$i++) {
|
||||
\$selected = (\$i==\$now['mday']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input name=\"{$variableName}[$field[field]][year]\" id=\"{$variableName}-$field[field]-year\" size=\"4\" maxlength=\"4\" value=\"<?php echo \$now['year']; ?>\" />
|
||||
</td>
|
||||
</tr>";
|
||||
break;
|
||||
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$HTML.="
|
||||
<tr><td><label for=\"{$variableName}-$field[field]-mon\">$field[field]</label></td>
|
||||
<td><select name=\"{$variableName}[$field[field]][mon]\" id=\"{$variableName}-$field[field]-mon\">
|
||||
<option></option>
|
||||
<?php
|
||||
\$now = getdate();
|
||||
for (\$i=1; \$i<=12; \$i++) {
|
||||
\$selected = (\$i==\$now['mon']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name=\"{$variableName}[$field[field]][mday]\">
|
||||
<option></option>
|
||||
<?php
|
||||
for (\$i=1; \$i<=31; \$i++) {
|
||||
\$selected = (\$i==\$now['mday']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input name=\"{$variableName}[$field[field]][year]\" id=\"{$variableName}-$field[field]-year\" size=\"4\" maxlength=\"4\" value=\"<?php echo \$now['year']; ?>\" />
|
||||
<select name=\"{$variableName}[$field[field]][hours]\" id=\"{$variableName}-$field[field]-hours\">
|
||||
<?php
|
||||
for (\$i=0; \$i<=23; \$i++) {
|
||||
\$selected = (\$i==\$now['hours']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name=\"{$variableName}[$field[field]][minutes]\" id=\"{$variableName}-$field[field]-minutes\">
|
||||
<?php
|
||||
for (\$i=0; \$i<=59; \$i+=15) {
|
||||
\$selected = (\$i==\$now['minutes']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>";
|
||||
break;
|
||||
|
||||
case 'text':
|
||||
$HTML.= "
|
||||
<tr><td><label for=\"{$variableName}-$field[field]\">$field[field]</label></td>
|
||||
<td><textarea name=\"{$variableName}[$field[field]]\" id=\"{$variableName}-$field[field]\" rows=\"3\" cols=\"60\"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
";
|
||||
break;
|
||||
|
||||
default:
|
||||
$HTML.= "
|
||||
<tr><td><label for=\"{$variableName}-$field[field]\">$field[field]</label></td>
|
||||
<td><input name=\"{$variableName}[$field[field]]\" id=\"{$variableName}-$field[field]\" />
|
||||
</td>
|
||||
</tr>
|
||||
";
|
||||
}
|
||||
}
|
||||
}
|
||||
$HTML.= "
|
||||
</table>
|
||||
|
||||
<button type=\"submit\" class=\"submit\">Submit</button>
|
||||
<button type=\"button\" class=\"cancel\" onclick=\"document.location.href='<?php echo BASE_URL; ?>/{$variableName}s';\">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>";
|
||||
|
||||
$contents = "<?php\n";
|
||||
$contents.= COPYRIGHT;
|
||||
$contents.="
|
||||
?>
|
||||
$HTML";
|
||||
file_put_contents("$dir/add{$className}Form.inc",$contents);
|
||||
|
||||
/**
|
||||
* Generate the Update Form
|
||||
*/
|
||||
$HTML = "<h1>Update $className</h1>
|
||||
<form method=\"post\" action=\"<?php echo \$_SERVER['SCRIPT_NAME']; ?>\">
|
||||
<fieldset><legend>$className Info</legend>
|
||||
<input name=\"$key\" type=\"hidden\" value=\"<?php echo \$this->{$variableName}->{$getId}(); ?>\" />
|
||||
<table>
|
||||
";
|
||||
foreach ($fields as $field) {
|
||||
if ($field['field'] != $key) {
|
||||
$fieldFunctionName = ucwords($field['field']);
|
||||
switch ($field['type']) {
|
||||
case 'date':
|
||||
$HTML.="
|
||||
<tr><td><label for=\"{$variableName}-$field[field]-mon\">$field[field]</label></td>
|
||||
<td><select name=\"{$variableName}[$field[field]][mon]\" id=\"{$variableName}-$field[field]-mon\">
|
||||
<option></option>
|
||||
<?php
|
||||
\$$field[field] = \$this->{$variableName}->dateStringToArray(\$this->{$variableName}->get$fieldFunctionName());
|
||||
for (\$i=1; \$i<=12; \$i++) {
|
||||
\$selected = (\$i==\$$field[field]['mon']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name=\"{$variableName}[$field[field]][mday]\">
|
||||
<option></option>
|
||||
<?php
|
||||
for (\$i=1; \$i<=31; \$i++) {
|
||||
\$selected = (\$i==\$$field[field]['mday']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input name=\"{$variableName}[$field[field]][year]\" id=\"{$variableName}-$field[field]-year\" size=\"4\" maxlength=\"4\" value=\"<?php echo \$$field[field]['year']; ?>\" />
|
||||
</td>
|
||||
</tr>";
|
||||
break;
|
||||
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$HTML.="
|
||||
<tr><td><label for=\"{$variableName}-$field[field]-mon\">$field[field]</label></td>
|
||||
<td><select name=\"{$variableName}[$field[field]][mon]\" id=\"{$variableName}-$field[field]-mon\">
|
||||
<option></option>
|
||||
<?php
|
||||
\$$field[field] = \$this->{$variableName}->dateStringToArray(\$this->{$variableName}->get$fieldFunctionName());
|
||||
for (\$i=1; \$i<=12; \$i++) {
|
||||
\$selected = (\$i==\$$field[field]['mon']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name=\"{$variableName}[$field[field]][mday]\">
|
||||
<option></option>
|
||||
<?php
|
||||
for (\$i=1; \$i<=31; \$i++) {
|
||||
\$selected = (\$i==\$$field[field]['mday']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<input name=\"{$variableName}[$field[field]][year]\" id=\"{$variableName}-$field[field]-year\" size=\"4\" maxlength=\"4\" value=\"<?php echo \$$field[field]['year']; ?>\" />
|
||||
<select name=\"{$variableName}[$field[field]][hours]\" id=\"{$variableName}-$field[field]-hours\">
|
||||
<?php
|
||||
for (\$i=0; \$i<=23; \$i++) {
|
||||
\$selected = (\$i==\$$field[field]['hours']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<select name=\"{$variableName}[$field[field]][minutes]\" id=\"{$variableName}-$field[field]-minutes\">
|
||||
<?php
|
||||
for (\$i=0; \$i<=59; \$i+=15) {
|
||||
\$selected = (\$i==\$$field[field]['minutes']) ? 'selected=\"selected\"' : '';
|
||||
echo \"<option \$selected>\$i</option>\";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>";
|
||||
break;
|
||||
|
||||
case 'text':
|
||||
$HTML.= "
|
||||
<tr><td><label for=\"{$variableName}-$field[field]\">$field[field]</label></td>
|
||||
<td><textarea name=\"{$variableName}[$field[field]]\" id=\"{$variableName}-$field[field]\" rows=\"3\" cols=\"60\"><?php echo \$this->{$variableName}->get$fieldFunctionName(); ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
";
|
||||
break;
|
||||
|
||||
default:
|
||||
$HTML.= "
|
||||
<tr><td><label for=\"{$variableName}-$field[field]\">$field[field]</label></td>
|
||||
<td><input name=\"{$variableName}[$field[field]]\" id=\"{$variableName}-$field[field]\" value=\"<?php echo \$this->{$variableName}->get$fieldFunctionName(); ?>\" />
|
||||
</td>
|
||||
</tr>
|
||||
";
|
||||
}
|
||||
}
|
||||
}
|
||||
$HTML.= "
|
||||
</table>
|
||||
|
||||
<button type=\"submit\" class=\"submit\">Submit</button>
|
||||
<button type=\"button\" class=\"cancel\" onclick=\"document.location.href='<?php echo BASE_URL; ?>/{$variableName}s';\">
|
||||
Cancel
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>";
|
||||
$contents = "<?php\n";
|
||||
$contents.= COPYRIGHT;
|
||||
$contents.="
|
||||
?>
|
||||
$HTML";
|
||||
file_put_contents("$dir/update{$className}Form.inc",$contents);
|
||||
|
||||
echo "$className\n";
|
||||
}
|
|
@ -0,0 +1,382 @@
|
|||
<?php
|
||||
/**
|
||||
* Generates ActiveRecord class files for each of the database tables
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
include '../configuration.inc';
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
foreach ($zend_db->listTables() as $tableName) {
|
||||
$fields = array();
|
||||
$primary_keys = array();
|
||||
foreach ($zend_db->describeTable($tableName) as $row) {
|
||||
$type = preg_replace("/[^a-z]/","",strtolower($row['DATA_TYPE']));
|
||||
|
||||
// Translate database datatypes into PHP datatypes
|
||||
if (preg_match('/int/',$type)) {
|
||||
$type = 'int';
|
||||
}
|
||||
if (preg_match('/enum/',$type) || preg_match('/varchar/',$type)) {
|
||||
$type = 'string';
|
||||
}
|
||||
|
||||
$fields[] = array('field'=>$row['COLUMN_NAME'],'type'=>$type);
|
||||
|
||||
if ($row['PRIMARY']) {
|
||||
$primary_keys[] = $row['COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
// Only generate code for tables that have a single-column primary key
|
||||
// Code for other tables will need to be created by hand
|
||||
if (count($primary_keys) != 1) {
|
||||
continue;
|
||||
}
|
||||
$key = $primary_keys[0];
|
||||
|
||||
$tableName = strtolower($tableName);
|
||||
$className = Inflector::classify($tableName);
|
||||
//--------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//--------------------------------------------------------------------------
|
||||
$constructor = "
|
||||
/**
|
||||
* Populates the object with data
|
||||
*
|
||||
* Passing in an associative array of data will populate this object without
|
||||
* hitting the database.
|
||||
*
|
||||
* Passing in a scalar will load the data from the database.
|
||||
* This will load all fields in the table as properties of this class.
|
||||
* You may want to replace this with, or add your own extra, custom loading
|
||||
*
|
||||
* @param int|array \$$key
|
||||
*/
|
||||
public function __construct(\$$key=null)
|
||||
{
|
||||
if (\$$key) {
|
||||
if (is_array(\$$key)) {
|
||||
\$result = \$$key;
|
||||
}
|
||||
else {
|
||||
\$zend_db = Database::getConnection();
|
||||
\$sql = 'select * from $tableName where $key=?';
|
||||
\$result = \$zend_db->fetchRow(\$sql,array(\$$key));
|
||||
}
|
||||
|
||||
if (\$result) {
|
||||
foreach (\$result as \$field=>\$value) {
|
||||
if (\$value) {
|
||||
\$this->\$field = \$value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Exception('$tableName/unknown$className');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is where the code goes to generate a new, empty instance.
|
||||
// Set any default values for properties that need it here
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Properties
|
||||
//--------------------------------------------------------------------------
|
||||
$properties = '';
|
||||
$linkedProperties = array();
|
||||
foreach ($fields as $field) {
|
||||
$properties.= "\tprivate \$$field[field];\n";
|
||||
|
||||
if (substr($field['field'],-3) == '_id') {
|
||||
$linkedProperties[] = $field['field'];
|
||||
}
|
||||
}
|
||||
|
||||
if (count($linkedProperties)) {
|
||||
$properties.="\n\n";
|
||||
foreach ($linkedProperties as $property) {
|
||||
$field = substr($property,0,-3);
|
||||
$properties.= "\tprivate \$$field;\n";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Getters
|
||||
//--------------------------------------------------------------------------
|
||||
$getters = '';
|
||||
foreach ($fields as $field) {
|
||||
$fieldFunctionName = ucwords($field['field']);
|
||||
|
||||
switch ($field['type'])
|
||||
{
|
||||
case 'date':
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$getters.= "
|
||||
/**
|
||||
* Returns the date/time in the desired format
|
||||
*
|
||||
* Format is specified using PHP's date() syntax
|
||||
* http://www.php.net/manual/en/function.date.php
|
||||
* If no format is given, the Date object is returned
|
||||
*
|
||||
* @param string \$format
|
||||
* @return string|DateTime
|
||||
*/
|
||||
public function get$fieldFunctionName(\$format=null)
|
||||
{
|
||||
if (\$format && \$this->$field[field]) {
|
||||
return \$this->$field[field]->format(\$format);
|
||||
}
|
||||
else {
|
||||
return \$this->$field[field];
|
||||
}
|
||||
}
|
||||
";
|
||||
break;
|
||||
|
||||
default: $getters.= "
|
||||
/**
|
||||
* @return $field[type]
|
||||
*/
|
||||
public function get$fieldFunctionName()
|
||||
{
|
||||
return \$this->$field[field];
|
||||
}
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($linkedProperties as $property) {
|
||||
$field = substr($property,0,-3);
|
||||
$fieldFunctionName = ucwords($field);
|
||||
$getters.= "
|
||||
/**
|
||||
* @return $fieldFunctionName
|
||||
*/
|
||||
public function get$fieldFunctionName()
|
||||
{
|
||||
if (\$this->$property) {
|
||||
if (!\$this->$field) {
|
||||
\$this->$field = new $fieldFunctionName(\$this->$property);
|
||||
}
|
||||
return \$this->$field;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
";
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Setters
|
||||
//--------------------------------------------------------------------------
|
||||
$setters = '';
|
||||
foreach ($fields as $field) {
|
||||
if ($field['field'] != $key) {
|
||||
$fieldFunctionName = ucwords($field['field']);
|
||||
switch ($field['type']) {
|
||||
case 'int':
|
||||
if (in_array($field['field'],$linkedProperties)) {
|
||||
$property = substr($field['field'],0,-3);
|
||||
$object = ucfirst($property);
|
||||
$setters.= "
|
||||
/**
|
||||
* @param $field[type] \$$field[type]
|
||||
*/
|
||||
public function set$fieldFunctionName(\$$field[type])
|
||||
{
|
||||
\$this->$property = new $object(\$int);
|
||||
\$this->$field[field] = \$$field[type];
|
||||
}
|
||||
";
|
||||
}
|
||||
else {
|
||||
$setters.= "
|
||||
/**
|
||||
* @param $field[type] \$$field[type]
|
||||
*/
|
||||
public function set$fieldFunctionName(\$$field[type])
|
||||
{
|
||||
\$this->$field[field] = preg_replace(\"/[^0-9]/\",\"\",\$$field[type]);
|
||||
}
|
||||
";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
$setters.= "
|
||||
/**
|
||||
* @param $field[type] \$$field[type]
|
||||
*/
|
||||
public function set$fieldFunctionName(\$$field[type])
|
||||
{
|
||||
\$this->$field[field] = trim(\$$field[type]);
|
||||
}
|
||||
";
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
$setters.= "
|
||||
/**
|
||||
* Sets the date
|
||||
*
|
||||
* Date arrays should match arrays produced by getdate()
|
||||
*
|
||||
* Date string formats should be in something strtotime() understands
|
||||
* http://www.php.net/manual/en/function.strtotime.php
|
||||
*
|
||||
* @param int|string|array \$$field[type]
|
||||
*/
|
||||
public function set$fieldFunctionName(\$$field[type])
|
||||
{
|
||||
if (\$$field[type]) {
|
||||
\$this->$field[field] = new Date(\$$field[type]);
|
||||
}
|
||||
else {
|
||||
\$this->$field[field] = null;
|
||||
}
|
||||
}
|
||||
";
|
||||
break;
|
||||
|
||||
case 'float':
|
||||
$setters.= "
|
||||
/**
|
||||
* @param $field[type] \$$field[type]
|
||||
*/
|
||||
public function set$fieldFunctionName(\$$field[type])
|
||||
{
|
||||
\$this->$field[field] = preg_replace(\"/[^0-9.\-]/\",\"\",\$$field[type]);
|
||||
}
|
||||
";
|
||||
break;
|
||||
|
||||
case 'bool':
|
||||
$setters.= "
|
||||
/**
|
||||
* @param boolean \$$field[type]
|
||||
*/
|
||||
public function set$fieldFunctionName(\$$field[type])
|
||||
{
|
||||
\$this->$field[field] = \$$field[type] ? true : false;
|
||||
}
|
||||
";
|
||||
break;
|
||||
|
||||
default:
|
||||
$setters.= "
|
||||
/**
|
||||
* @param $field[type] \$$field[type]
|
||||
*/
|
||||
public function set$fieldFunctionName(\$$field[type])
|
||||
{
|
||||
\$this->$field[field] = \$$field[type];
|
||||
}
|
||||
";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($linkedProperties as $field) {
|
||||
$property = substr($field,0,-3);
|
||||
$object = ucfirst($property);
|
||||
$setters.= "
|
||||
/**
|
||||
* @param $object \$$property
|
||||
*/
|
||||
public function set$object(\$$property)
|
||||
{
|
||||
\$this->$field = \${$property}->getId();
|
||||
\$this->$property = \$$property;
|
||||
}
|
||||
";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Output the class
|
||||
//--------------------------------------------------------------------------
|
||||
$contents = "<?php\n";
|
||||
$contents.= COPYRIGHT;
|
||||
$contents.= "
|
||||
class $className
|
||||
{
|
||||
$properties
|
||||
|
||||
$constructor
|
||||
/**
|
||||
* Throws an exception if anything's wrong
|
||||
* @throws Exception \$e
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
// Check for required fields here. Throw an exception if anything is missing.
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this record back to the database
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
\$this->validate();
|
||||
|
||||
\$data = array();
|
||||
";
|
||||
foreach ($fields as $field) {
|
||||
if ($field['field'] != $key) {
|
||||
$contents.="\t\t\$data['$field[field]'] = \$this->$field[field] ? \$this->$field[field] : null;\n";
|
||||
}
|
||||
}
|
||||
$contents.= "
|
||||
if (\$this->$key) {
|
||||
\$this->update(\$data);
|
||||
}
|
||||
else {
|
||||
\$this->insert(\$data);
|
||||
}
|
||||
}
|
||||
|
||||
private function update(\$data)
|
||||
{
|
||||
\$zend_db = Database::getConnection();
|
||||
\$zend_db->update('$tableName',\$data,\"$key='{\$this->$key}'\");
|
||||
}
|
||||
|
||||
private function insert(\$data)
|
||||
{
|
||||
\$zend_db = Database::getConnection();
|
||||
\$zend_db->insert('$tableName',\$data);
|
||||
\$this->$key = \$zend_db->lastInsertId('$tableName','$key');
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Generic Getters
|
||||
//----------------------------------------------------------------
|
||||
$getters
|
||||
//----------------------------------------------------------------
|
||||
// Generic Setters
|
||||
//----------------------------------------------------------------
|
||||
$setters
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Custom Functions
|
||||
// We recommend adding all your custom code down here at the bottom
|
||||
//----------------------------------------------------------------
|
||||
}
|
||||
";
|
||||
$dir = APPLICATION_HOME.'/scripts/stubs/classes';
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir,0770,true);
|
||||
}
|
||||
file_put_contents("$dir/$className.php",$contents);
|
||||
echo "$className\n";
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
include '../configuration.inc';
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
foreach ($zend_db->listTables() as $tableName) {
|
||||
$fields = array();
|
||||
$primary_keys = array();
|
||||
foreach ($zend_db->describeTable($tableName) as $row) {
|
||||
$type = preg_replace("/[^a-z]/","",strtolower($row['DATA_TYPE']));
|
||||
|
||||
// Translate database datatypes into PHP datatypes
|
||||
if (preg_match('/int/',$type)) {
|
||||
$type = 'int';
|
||||
}
|
||||
if (preg_match('/enum/',$type) || preg_match('/varchar/',$type)) {
|
||||
$type = 'string';
|
||||
}
|
||||
|
||||
$fields[] = array('field'=>$row['COLUMN_NAME'],'type'=>$type);
|
||||
|
||||
if ($row['PRIMARY']) {
|
||||
$primary_keys[] = $row['COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
// Only generate code for tables that have a single-column primary key
|
||||
// Code for other tables will need to be created by hand
|
||||
if (count($primary_keys) != 1) {
|
||||
continue;
|
||||
}
|
||||
$key = $primary_keys[0];
|
||||
|
||||
$tableName = strtolower($tableName);
|
||||
$className = Inflector::classify($tableName);
|
||||
$variableName = Inflector::singularize($tableName);
|
||||
$acl_resource = ucfirst($tableName);
|
||||
|
||||
/**
|
||||
* Generate home.php
|
||||
*/
|
||||
$PHP = "
|
||||
\${$variableName}List = new {$className}List();
|
||||
\${$variableName}List->find();
|
||||
|
||||
\$template = new Template();
|
||||
\$template->blocks[] = new Block('{$variableName}s/{$variableName}List.inc',array('{$variableName}List'=>\${$variableName}List));
|
||||
echo \$template->render();";
|
||||
|
||||
$contents = "<?php\n";
|
||||
$contents.= COPYRIGHT."\n";
|
||||
$contents.= $PHP;
|
||||
|
||||
$dir = APPLICATION_HOME."/scripts/stubs/html/$tableName";
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir,0770,true);
|
||||
}
|
||||
file_put_contents("$dir/home.php",$contents);
|
||||
|
||||
/**
|
||||
* Generate the Add controller
|
||||
*/
|
||||
$PHP = "
|
||||
if (!userIsAllowed('$acl_resource')) {
|
||||
\$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL.'/$tableName');
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset(\$_POST['{$variableName}'])) {
|
||||
\${$variableName} = new {$className}();
|
||||
foreach (\$_POST['{$variableName}'] as \$field=>\$value) {
|
||||
\$set = 'set'.ucfirst(\$field);
|
||||
\${$variableName}->\$set(\$value);
|
||||
}
|
||||
|
||||
try {
|
||||
\${$variableName}->save();
|
||||
header('Location: '.BASE_URL.'/$tableName');
|
||||
exit();
|
||||
}
|
||||
catch(Exception \$e) {
|
||||
\$_SESSION['errorMessages'][] = \$e;
|
||||
}
|
||||
}
|
||||
|
||||
\$template = new Template();
|
||||
\$template->blocks[] = new Block('{$variableName}s/add{$className}Form.inc');
|
||||
echo \$template->render();";
|
||||
$contents = "<?php\n";
|
||||
$contents.= COPYRIGHT."\n";
|
||||
$contents.= $PHP;
|
||||
file_put_contents("$dir/add{$className}.php",$contents);
|
||||
|
||||
|
||||
/**
|
||||
* Generate the Update controller
|
||||
*/
|
||||
$PHP = "
|
||||
if (!userIsAllowed('$acl_resource')) {
|
||||
\$_SESSION['errorMessages'][] = new Exception('noAccessAllowed');
|
||||
header('Location: '.BASE_URL.'/$tableName');
|
||||
exit();
|
||||
}
|
||||
|
||||
\${$variableName} = new {$className}(\$_REQUEST['$key']);
|
||||
if (isset(\$_POST['$variableName'])) {
|
||||
foreach (\$_POST['$variableName'] as \$field=>\$value) {
|
||||
\$set = 'set'.ucfirst(\$field);
|
||||
\${$variableName}->\$set(\$value);
|
||||
}
|
||||
|
||||
try {
|
||||
\${$variableName}->save();
|
||||
header('Location: '.BASE_URL.'/$tableName');
|
||||
exit();
|
||||
}
|
||||
catch (Exception \$e) {
|
||||
\$_SESSION['errorMessages'][] = \$e;
|
||||
}
|
||||
}
|
||||
|
||||
\$template = new Template();
|
||||
\$template->blocks[] = new Block('{$variableName}s/update{$className}Form.inc',array('{$variableName}'=>\${$variableName}));
|
||||
echo \$template->render();";
|
||||
$contents = "<?php\n";
|
||||
$contents.= COPYRIGHT."\n";
|
||||
$contents.= $PHP;
|
||||
file_put_contents("$dir/update{$className}.php",$contents);
|
||||
echo "$className\n";
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
/**
|
||||
* Generates a Collection class for each the ActiveRecord objects
|
||||
*
|
||||
* @copyright 2006-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
include '../configuration.inc';
|
||||
$zend_db = Database::getConnection();
|
||||
|
||||
foreach ($zend_db->listTables() as $tableName) {
|
||||
$fields = array();
|
||||
$primary_keys = array();
|
||||
foreach ($zend_db->describeTable($tableName) as $row) {
|
||||
$type = preg_replace("/[^a-z]/","",strtolower($row['DATA_TYPE']));
|
||||
|
||||
// Translate database datatypes into PHP datatypes
|
||||
if (preg_match('/int/',$type)) {
|
||||
$type = 'int';
|
||||
}
|
||||
if (preg_match('/enum/',$type) || preg_match('/varchar/',$type)) {
|
||||
$type = 'string';
|
||||
}
|
||||
|
||||
$fields[] = array('field'=>$row['COLUMN_NAME'],'type'=>$type);
|
||||
|
||||
if ($row['PRIMARY']) {
|
||||
$primary_keys[] = $row['COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
// Only generate code for tables that have a single-column primary key
|
||||
// Code for other tables will need to be created by hand
|
||||
if (count($primary_keys) != 1) {
|
||||
continue;
|
||||
}
|
||||
$key = $primary_keys[0];
|
||||
|
||||
$tableName = strtolower($tableName);
|
||||
$className = Inflector::classify($tableName);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Output the class
|
||||
//--------------------------------------------------------------------------
|
||||
$contents = "<?php
|
||||
/**
|
||||
* A collection class for $className objects
|
||||
*
|
||||
* This class creates a zend_db select statement.
|
||||
* ZendDbResultIterator handles iterating and paginating those results.
|
||||
* As the results are iterated over, ZendDbResultIterator will pass each desired
|
||||
* row back to this class's loadResult() which will be responsible for hydrating
|
||||
* each $className object
|
||||
*
|
||||
* Beyond the basic \$fields handled, you will need to write your own handling
|
||||
* of whatever extra \$fields you need
|
||||
*/
|
||||
";
|
||||
$contents.= COPYRIGHT;
|
||||
$contents.="
|
||||
class {$className}List extends ZendDbResultIterator
|
||||
{
|
||||
/**
|
||||
* Creates a basic select statement for the collection.
|
||||
*
|
||||
* Populates the collection if you pass in \$fields
|
||||
* Setting itemsPerPage turns on pagination mode
|
||||
* In pagination mode, this will only load the results for one page
|
||||
*
|
||||
* @param array \$fields
|
||||
* @param int \$itemsPerPage Turns on Pagination
|
||||
* @param int \$currentPage
|
||||
*/
|
||||
public function __construct(\$fields=null,\$itemsPerPage=null,\$currentPage=null)
|
||||
{
|
||||
parent::__construct(\$itemsPerPage,\$currentPage);
|
||||
if (is_array(\$fields)) {
|
||||
\$this->find(\$fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the collection
|
||||
*
|
||||
* @param array \$fields
|
||||
* @param string|array \$order Multi-column sort should be given as an array
|
||||
* @param int \$limit
|
||||
* @param string|array \$groupBy Multi-column group by should be given as an array
|
||||
*/
|
||||
public function find(\$fields=null,\$order='$key',\$limit=null,\$groupBy=null)
|
||||
{
|
||||
\$this->select->from('$tableName');
|
||||
|
||||
// Finding on fields from the $tableName table is handled here
|
||||
if (count(\$fields)) {
|
||||
foreach (\$fields as \$key=>\$value) {
|
||||
\$this->select->where(\"\$key=?\",\$value);
|
||||
}
|
||||
}
|
||||
|
||||
// Finding on fields from other tables requires joining those tables.
|
||||
// You can handle fields from other tables by adding the joins here
|
||||
// If you add more joins you probably want to make sure that the
|
||||
// above foreach only handles fields from the $tableName table.
|
||||
|
||||
\$this->select->order(\$order);
|
||||
if (\$limit) {
|
||||
\$this->select->limit(\$limit);
|
||||
}
|
||||
if (\$groupBy) {
|
||||
\$this->select->group(\$groupBy);
|
||||
}
|
||||
\$this->populateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates all the $className objects from a database result set
|
||||
*
|
||||
* This is a callback function, called from ZendDbResultIterator. It is
|
||||
* called once per row of the result.
|
||||
*
|
||||
* @param int \$key The index of the result row to load
|
||||
* @return $className
|
||||
*/
|
||||
protected function loadResult(\$key)
|
||||
{
|
||||
return new $className(\$this->result[\$key]);
|
||||
}
|
||||
}
|
||||
";
|
||||
$dir = APPLICATION_HOME.'/scripts/stubs/classes';
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir,0770,true);
|
||||
}
|
||||
file_put_contents("$dir/{$className}List.php",$contents);
|
||||
echo "$className\n";
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2008-2009 City of Bloomington, Indiana
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
* @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
*/
|
||||
include '../configuration.inc';
|
||||
$dir = APPLICATION_HOME.'/scripts/stubs/tests';
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir,0770,true);
|
||||
}
|
||||
|
||||
$dir = APPLICATION_HOME.'/scripts/stubs/tests/DatabaseTests';
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir,0770,true);
|
||||
}
|
||||
|
||||
$dir = APPLICATION_HOME.'/scripts/stubs/tests/UnitTests';
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir,0770,true);
|
||||
}
|
||||
|
||||
$dir = APPLICATION_HOME.'/scripts/stubs/tests';
|
||||
|
||||
|
||||
$zend_db = Database::getConnection();
|
||||
$classes = array();
|
||||
foreach ($zend_db->listTables() as $tableName) {
|
||||
$fields = array();
|
||||
$primary_keys = array();
|
||||
foreach ($zend_db->describeTable($tableName) as $row) {
|
||||
$type = preg_replace("/[^a-z]/","",strtolower($row['DATA_TYPE']));
|
||||
|
||||
// Translate database datatypes into PHP datatypes
|
||||
if (preg_match('/int/',$type)) {
|
||||
$type = 'int';
|
||||
}
|
||||
if (preg_match('/enum/',$type) || preg_match('/varchar/',$type)) {
|
||||
$type = 'string';
|
||||
}
|
||||
|
||||
$fields[] = array('field'=>$row['COLUMN_NAME'],'type'=>$type);
|
||||
|
||||
if ($row['PRIMARY']) {
|
||||
$primary_keys[] = $row['COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
// Only generate code for tables that have a single-column primary key
|
||||
// Code for other tables will need to be created by hand
|
||||
if (count($primary_keys) != 1) {
|
||||
continue;
|
||||
}
|
||||
$key = $primary_keys[0];
|
||||
|
||||
$tableName = strtolower($tableName);
|
||||
$className = Inflector::classify($tableName);
|
||||
$classes[] = $className;
|
||||
|
||||
$variable = strtolower($className);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generate the Unit Tests
|
||||
//------------------------------------------------------------------------------
|
||||
$contents = "<?php
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
class {$className}UnitTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testValidate()
|
||||
{
|
||||
\${$variable} = new {$className}();
|
||||
try {
|
||||
\${$variable}->validate();
|
||||
\$this->fail('Missing name failed to throw exception');
|
||||
}
|
||||
catch (Exception \$e) {
|
||||
|
||||
}
|
||||
|
||||
\${$variable}->setName('Test {$className}');
|
||||
\${$variable}->validate();
|
||||
}
|
||||
}
|
||||
";
|
||||
file_put_contents("$dir/UnitTests/{$className}UnitTest.php",$contents);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generate the Database Tests
|
||||
//------------------------------------------------------------------------------
|
||||
$contents = "<?php
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
class {$className}DbTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
\$dir = dirname(__FILE__);
|
||||
exec('/usr/local/mysql/bin/mysql -u '.DB_USER.' -p'.DB_PASS.' '.DB_NAME.\" < \$dir/../testData.sql\");
|
||||
}
|
||||
|
||||
public function testSaveLoad()
|
||||
{
|
||||
\${$variable} = new {$className}();
|
||||
\${$variable}->setName('Test {$className}');
|
||||
try {
|
||||
\${$variable}->save();
|
||||
\$id = \${$variable}->getId();
|
||||
\$this->assertGreaterThan(0,\$id);
|
||||
}
|
||||
catch (Exception \$e) {
|
||||
\$this->fail(\$e->getMessage());
|
||||
}
|
||||
|
||||
\${$variable} = new {$className}(\$id);
|
||||
\$this->assertEquals(\${$variable}->getName(),'Test {$className}');
|
||||
|
||||
\${$variable}->setName('Test');
|
||||
\${$variable}->save();
|
||||
|
||||
\${$variable} = new {$className}(\$id);
|
||||
\$this->assertEquals(\${$variable}->getName(),'Test');
|
||||
}
|
||||
}
|
||||
";
|
||||
file_put_contents("$dir/DatabaseTests/{$className}DbTest.php",$contents);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generate the Database List Tests
|
||||
//------------------------------------------------------------------------------
|
||||
$contents = "<?php
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
class {$className}ListDbTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
\$dir = dirname(__FILE__);
|
||||
exec('/usr/local/mysql/bin/mysql -u '.DB_USER.' -p'.DB_PASS.' '.DB_NAME.\" < \$dir/../testData.sql\");
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure find returns all $tableName ordered correctly by default
|
||||
*/
|
||||
public function testFindOrderedByName()
|
||||
{
|
||||
\$PDO = Database::getConnection();
|
||||
\$query = \$PDO->query('select id from $tableName order by id');
|
||||
\$result = \$query->fetchAll();
|
||||
|
||||
\$list = new {$className}List();
|
||||
\$list->find();
|
||||
\$this->assertEquals(\$list->getSort(),'id');
|
||||
|
||||
foreach (\$list as \$i=>\${$variable}) {
|
||||
\$this->assertEquals(\${$variable}->getId(),\$result[\$i]['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
";
|
||||
file_put_contents("$dir/DatabaseTests/{$className}ListDbTest.php",$contents);
|
||||
|
||||
echo "$className\n";
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generate the All Tests Suite
|
||||
//------------------------------------------------------------------------------
|
||||
$contents = "<?php
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
require_once 'UnitTests.php';
|
||||
require_once 'DatabaseTests.php';
|
||||
|
||||
class AllTests extends PHPUnit_Framework_TestSuite
|
||||
{
|
||||
public static function suite()
|
||||
{
|
||||
\$suite = new AllTests('".APPLICATION_NAME."');
|
||||
\$suite->addTest(UnitTests::suite());
|
||||
\$suite->addTest(DatabaseTests::suite());
|
||||
return \$suite;
|
||||
}
|
||||
}
|
||||
";
|
||||
file_put_contents("$dir/AllTests.php",$contents);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generate the All Tests Suite
|
||||
//------------------------------------------------------------------------------
|
||||
$contents = "<?php\nrequire_once 'PHPUnit/Framework.php';\n\n";
|
||||
foreach ($classes as $className) {
|
||||
$contents.= "require_once 'DatabaseTests/{$className}DbTest.php';\n";
|
||||
$contents.= "require_once 'DatabaseTests/{$className}ListDbTest.php';\n";
|
||||
}
|
||||
$contents.= "
|
||||
class DatabaseTests extends PHPUnit_Framework_TestSuite
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
\$dir = dirname(__FILE__);
|
||||
exec('/usr/local/mysql/bin/mysql -u '.DB_USER.' -p'.DB_PASS.' '.DB_NAME.\" < \$dir/testData.sql\");
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
\$dir = dirname(__FILE__);
|
||||
exec('/usr/local/mysql/bin/mysql -u '.DB_USER.' -p'.DB_PASS.' '.DB_NAME.\" < \$dir/testData.sql\");
|
||||
}
|
||||
|
||||
public static function suite()
|
||||
{
|
||||
\$suite = new DatabaseTests('".APPLICATION_NAME." Classes');
|
||||
|
||||
";
|
||||
foreach ($classes as $className) {
|
||||
$contents.= "\t\t\$suite->addTestSuite('{$className}DbTest');\n";
|
||||
$contents.= "\t\t\$suite->addTestSuite('{$className}ListDbTest');\n";
|
||||
}
|
||||
$contents.= "
|
||||
return \$suite;
|
||||
}
|
||||
}
|
||||
";
|
||||
file_put_contents("$dir/DatabaseTests.php",$contents);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generate the Unit Tests Suite
|
||||
//------------------------------------------------------------------------------
|
||||
$contents = "<?php\nrequire_once 'PHPUnit/Framework.php';\n\n";
|
||||
foreach ($classes as $className) {
|
||||
$contents.= "require_once 'UnitTests/{$className}UnitTest.php';\n";
|
||||
}
|
||||
$contents.= "
|
||||
class UnitTests extends PHPUnit_Framework_TestSuite
|
||||
{
|
||||
public static function suite()
|
||||
{
|
||||
\$suite = new UnitTests('".APPLICATION_NAME." Classes');
|
||||
|
||||
";
|
||||
foreach ($classes as $className) {
|
||||
$contents.= "\t\t\$suite->addTestSuite('{$className}UnitTest');\n";
|
||||
}
|
||||
$contents.= "
|
||||
return \$suite;
|
||||
}
|
||||
}
|
||||
";
|
||||
file_put_contents("$dir/UnitTests.php",$contents);
|
|
@ -0,0 +1,75 @@
|
|||
-- @copyright 2009 City of Bloomington, Indiana
|
||||
-- @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.txt
|
||||
-- @author Cliff Ingham <inghamn@bloomington.in.gov>
|
||||
create table people (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
firstname varchar(128) not null,
|
||||
lastname varchar(128) not null,
|
||||
email varchar(255) not null
|
||||
) engine=InnoDB;
|
||||
|
||||
create table users (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
person_id int unsigned not null unique,
|
||||
username varchar(30) not null unique,
|
||||
password varchar(32),
|
||||
authenticationMethod varchar(40) not null default 'LDAP',
|
||||
foreign key (person_id) references people(id)
|
||||
) engine=InnoDB;
|
||||
|
||||
create table roles (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
name varchar(30) not null unique
|
||||
) engine=InnoDB;
|
||||
insert roles values(1,'Administrator');
|
||||
insert roles values(2,'Editor');
|
||||
|
||||
create table user_roles (
|
||||
user_id int unsigned not null,
|
||||
role_id int unsigned not null,
|
||||
primary key (user_id,role_id),
|
||||
foreign key(user_id) references users (id),
|
||||
foreign key(role_id) references roles (id)
|
||||
) engine=InnoDB;
|
||||
|
||||
create table cemeteries (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
name varchar(128) not null
|
||||
) engine=InnoDB;
|
||||
|
||||
create table deeds (
|
||||
id int unsigned not null primary key auto_increment,
|
||||
section varchar(5),
|
||||
lot varchar(5),
|
||||
lastname1 varchar(20),
|
||||
firstname1 varchar(20),
|
||||
middleInitial1 char(1),
|
||||
lastname2 varchar(20),
|
||||
firstname2 varchar(20),
|
||||
middleInitial2 char(1),
|
||||
issueDate date,
|
||||
notes text,
|
||||
lot2 char(5),
|
||||
cemetery_id int unsigned,
|
||||
foreign key (cemetery_id) references cemeteries(id)
|
||||
) engine=InnoDB;
|
||||
|
||||
create table internments (
|
||||
id int(11) unsigned not null primary key auto_increment,
|
||||
section varchar(5),
|
||||
lot varchar(5),
|
||||
book varchar(4),
|
||||
pageNumber varchar(5),
|
||||
deceasedDate date,
|
||||
lastname varchar(20),
|
||||
firstname varchar(20),
|
||||
middleInitial char(1),
|
||||
birthPlace varchar(20),
|
||||
lastResidence varchar(20),
|
||||
age int unsigned,
|
||||
sex enum('M','F'),
|
||||
cemetery_id int unsigned,
|
||||
notes text,
|
||||
lot2 varchar(5),
|
||||
foreign key (cemetery_id) references cemeteries(id)
|
||||
) engine=InnoDB;
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
PHP=/usr/local/bin/php
|
||||
$PHP generateBlocks.php
|
||||
$PHP generateControllers.php
|
||||
$PHP generateClasses.php
|
||||
$PHP generateLists.php
|
||||
$PHP generateTests.php
|
|
@ -0,0 +1 @@
|
|||
two-column.inc
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<?php
|
||||
$this->layout = 'full-width';
|
||||
$dir = dirname(__FILE__);
|
||||
include $dir.'/partials/header.inc';
|
||||
?>
|
||||
<body>
|
||||
<?php
|
||||
include $dir.'/partials/banner.inc';
|
||||
include $dir.'/partials/menubar.inc';
|
||||
?>
|
||||
|
||||
<div id="panel-container">
|
||||
<div id="content-panel">
|
||||
<?php
|
||||
include FRAMEWORK.'/errorMessages.php';
|
||||
|
||||
echo $this->includeBlocks();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php include $dir.'/partials/footer.inc'; ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
include $dir.'/partials/garbageCollection.inc';
|
||||
?>
|
|
@ -0,0 +1,6 @@
|
|||
<div id="banner">
|
||||
<div id="application_name"><a href="<?php echo BASE_URL; ?>/">New Application</a></div>
|
||||
<div id="location_name">
|
||||
<a href="<?php echo BASE_URL; ?>">City of Bloomington, Mark Kruzan, Mayor</a>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,10 @@
|
|||
<div id="footer">
|
||||
<p>
|
||||
<?php
|
||||
# Calculate the process time
|
||||
$endTime = microtime(1);
|
||||
$processTime = $endTime - $startTime;
|
||||
echo "<!-- Process Time: $processTime -->";
|
||||
?>
|
||||
</p>
|
||||
</div>
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
//---------------------------------------------------------------------
|
||||
// Before we quit, handle any Garbage Collection that needs to be done
|
||||
//---------------------------------------------------------------------
|
||||
// If we're on a form, clean out any old data
|
||||
if (isset($_SESSION['oldPostData'])) {
|
||||
unset($_SESSION['oldPostData']);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php $startTime = microtime(1); ?>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
|
||||
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
||||
<link rel="SHORTCUT ICON" href="/favicon.ico" />
|
||||
<style type="text/css" media="screen">
|
||||
@import url('/skins/origin/reset.css');
|
||||
@import url('<?php echo BASE_URL; ?>/skins/local/layouts/<?php echo $this->layout; ?>.css');
|
||||
@import url('/skins/origin/screen.css');
|
||||
@import url('<?php echo BASE_URL; ?>/skins/local/screen.css');
|
||||
</style>
|
||||
<script type="text/javascript" src="<?php echo BASE_URL; ?>/js/functions.js"></script>
|
||||
|
||||
<title>New Application</title>
|
||||
</head>
|
|
@ -0,0 +1,12 @@
|
|||
<div class="menuBar">
|
||||
<ul><li><a href="<?php echo BASE_URL; ?>">Home</a></li>
|
||||
<?php
|
||||
if (isset($_SESSION['USER'])) {
|
||||
echo "<li><a href=\"".BASE_URL."/login/logout.php\">Logout</a></li>";
|
||||
}
|
||||
else {
|
||||
echo "<li><a href=\"".BASE_URL."/login\">Login</a></li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
<div id="panel-one">
|
||||
<?php
|
||||
if (userIsAllowed('Users')) {
|
||||
include APPLICATION_HOME.'/templates/html/partials/panel-widgets/Users.inc';
|
||||
}
|
||||
?>
|
||||
</div>
|
|
@ -0,0 +1,2 @@
|
|||
<div id="panel-two">
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
<div>
|
||||
<h1>Admin</h1>
|
||||
<ul>
|
||||
<li><a href="<?php echo BASE_URL; ?>/people">People</a></li>
|
||||
<li><a href="<?php echo BASE_URL; ?>/users">User Accounts</a></li>
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<?php
|
||||
$this->layout = 'three-column';
|
||||
$dir = dirname(__FILE__);
|
||||
include $dir.'/partials/header.inc';
|
||||
?>
|
||||
<body>
|
||||
<?php
|
||||
include $dir.'/partials/banner.inc';
|
||||
include $dir.'/partials/menubar.inc';
|
||||
?>
|
||||
|
||||
<div id="panel-container">
|
||||
<?php
|
||||
include $dir.'/partials/panel-one.inc';
|
||||
include $dir.'/partials/panel-two.inc';
|
||||
?>
|
||||
<div id="content-panel">
|
||||
<?php
|
||||
include FRAMEWORK.'/errorMessages.php';
|
||||
|
||||
echo $this->includeBlocks();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php include $dir.'/partials/footer.inc'; ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
include $dir.'/partials/garbageCollection.inc';
|
||||
?>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<?php
|
||||
$this->layout = 'two-column';
|
||||
$dir = dirname(__FILE__);
|
||||
include $dir.'/partials/header.inc';
|
||||
?>
|
||||
<body>
|
||||
<?php
|
||||
include $dir.'/partials/banner.inc';
|
||||
include $dir.'/partials/menubar.inc';
|
||||
?>
|
||||
|
||||
<div id="panel-container">
|
||||
<?php
|
||||
include $dir.'/partials/panel-one.inc';
|
||||
?>
|
||||
<div id="content-panel">
|
||||
<?php
|
||||
include FRAMEWORK.'/errorMessages.php';
|
||||
|
||||
echo $this->includeBlocks();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php include $dir.'/partials/footer.inc'; ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
include $dir.'/partials/garbageCollection.inc';
|
||||
?>
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
require_once 'UnitTests.php';
|
||||
require_once 'DatabaseTests.php';
|
||||
|
||||
class AllTests extends PHPUnit_Framework_TestSuite
|
||||
{
|
||||
public static function suite()
|
||||
{
|
||||
$suite = new AllTests('All Tests');
|
||||
$suite->addTest(UnitTests::suite());
|
||||
$suite->addTest(DatabaseTests::suite());
|
||||
return $suite;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
PHPCS=/usr/local/PHP_CodeSniffer/scripts/phpcs
|
||||
STANDARD=COB
|
||||
|
||||
for FILE in `ls ../classes/`;
|
||||
do $PHPCS --standard=$STANDARD ../classes/$FILE;
|
||||
done;
|
||||
|
||||
for FILE in `find ../html/ -name '*.php'`;
|
||||
do $PHPCS --standard=$STANDARD $FILE;
|
||||
done
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
require_once 'PHPUnit/Framework.php';
|
||||
|
||||
require_once 'DatabaseTests/RoleListDbTest.php';
|
||||
require_once 'DatabaseTests/RoleDbTest.php';
|
||||
require_once 'DatabaseTests/UserListDbTest.php';
|
||||
require_once 'DatabaseTests/UserDbTest.php';
|
||||
|
||||
class DatabaseTests extends PHPUnit_Framework_TestSuite
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$dir = dirname(__FILE__);
|
||||
exec('/usr/local/mysql/bin/mysql -u '.DB_USER.' -p'.DB_PASS.' '.DB_NAME." < $dir/testData.sql\n");
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$dir = dirname(__FILE__);
|
||||
exec('/usr/local/mysql/bin/mysql -u '.DB_USER.' -p'.DB_PASS.' '.DB_NAME." < $dir/testData.sql\n");
|
||||
}
|
||||
|
||||
public static function suite()
|
||||
{
|
||||
$suite = new DatabaseTests('Database Tests');
|
||||
|
||||
$suite->addTestSuite('RoleListDbTest');
|
||||
$suite->addTestSuite('RoleDbTest');
|
||||
$suite->addTestSuite('UserListDbTest');
|
||||
$suite->addTestSuite('UserDbTest');
|
||||
|
||||
return $suite;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue