Initial Commit

This commit is contained in:
Lucas Bartholemy 2014-02-10 06:36:00 +01:00
parent 3af490723d
commit d3ff1c3c4a
5965 changed files with 1534101 additions and 664 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
nbproject

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "protected/modules/feedback"]
path = protected/modules/feedback
url = git@git.humhub.org:/home/git/humhub-modules-feedback.git
[submodule "protected/modules/translation"]
path = protected/modules/translation
url = git@github.com:humhub/humhub-modules-translation.git
[submodule "themes/enoa"]
path = themes/enoa
url = git@git.humhub.org:/home/git/humhub-themes-enoa.git

9
.htaccess Normal file
View File

@ -0,0 +1,9 @@
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php

661
LICENSE
View File

@ -1,661 +0,0 @@
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/>.

View File

@ -1,4 +1,14 @@
humhub
======
Welcome to HumHub
=================
HumHub is an opensource social network application written in PHP.
- <a href="http://demo.humhub.org" target="_blank">**Demo**</a>
- <a href="protected/docs/guide/administration/index.md">Installation & Admin Documentation</a>
- <a href="protected/docs/guide/developer/index.md">Developer Documentation</a>
- <a href="protected/docs/guide/theming/index.md">Theming Documentation</a>
- <a href="protected/docs/license.md">License: Dual license AGPL v3 / Proprietary</a>
HumHub - OpenSource Social Network

0
assets/empty.txt Normal file
View File

102
css/bootstrap-wysihtml5.css vendored Normal file
View File

@ -0,0 +1,102 @@
ul.wysihtml5-toolbar {
margin: 0;
padding: 0;
display: block;
}
ul.wysihtml5-toolbar::after {
clear: both;
display: table;
content: "";
}
ul.wysihtml5-toolbar > li {
float: left;
display: list-item;
list-style: none;
margin: 0 5px 10px 0;
}
ul.wysihtml5-toolbar a[data-wysihtml5-command=bold] {
font-weight: bold;
}
ul.wysihtml5-toolbar a[data-wysihtml5-command=italic] {
font-style: italic;
}
ul.wysihtml5-toolbar a[data-wysihtml5-command=underline] {
text-decoration: underline;
}
ul.wysihtml5-toolbar a.btn.wysihtml5-command-active {
background-image: none;
-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
background-color: #E6E6E6;
background-color: #D9D9D9;
outline: 0;
}
ul.wysihtml5-commands-disabled .dropdown-menu {
display: none !important;
}
ul.wysihtml5-toolbar div.wysihtml5-colors {
display:block;
width: 50px;
height: 20px;
margin-top: 2px;
margin-left: 5px;
position: absolute;
pointer-events: none;
}
ul.wysihtml5-toolbar a.wysihtml5-colors-title {
padding-left: 70px;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="black"] {
background: black !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="silver"] {
background: silver !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="gray"] {
background: gray !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="maroon"] {
background: maroon !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="red"] {
background: red !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="purple"] {
background: purple !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="green"] {
background: green !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="olive"] {
background: olive !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="navy"] {
background: navy !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="blue"] {
background: blue !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="orange"] {
background: orange !important;
}

9
css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

67
css/bootstrap3-wysiwyg5-color.css vendored Normal file
View File

@ -0,0 +1,67 @@
.wysiwyg-color-black {
color: black;
}
.wysiwyg-color-silver {
color: silver;
}
.wysiwyg-color-gray {
color: gray;
}
.wysiwyg-color-white {
color: white;
}
.wysiwyg-color-maroon {
color: maroon;
}
.wysiwyg-color-red {
color: red;
}
.wysiwyg-color-purple {
color: purple;
}
.wysiwyg-color-fuchsia {
color: fuchsia;
}
.wysiwyg-color-green {
color: green;
}
.wysiwyg-color-lime {
color: lime;
}
.wysiwyg-color-olive {
color: olive;
}
.wysiwyg-color-yellow {
color: yellow;
}
.wysiwyg-color-navy {
color: navy;
}
.wysiwyg-color-blue {
color: blue;
}
.wysiwyg-color-teal {
color: teal;
}
.wysiwyg-color-aqua {
color: aqua;
}
.wysiwyg-color-orange {
color: orange;
}

481
css/datepicker.css Normal file
View File

@ -0,0 +1,481 @@
/*!
* Datepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datepicker {
padding: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
}
.datepicker-inline {
width: 220px;
}
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
}
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-top: 0;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
}
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
border-top: 0;
position: absolute;
}
.datepicker-dropdown.datepicker-orient-left:before {
left: 6px;
}
.datepicker-dropdown.datepicker-orient-left:after {
left: 7px;
}
.datepicker-dropdown.datepicker-orient-right:before {
right: 6px;
}
.datepicker-dropdown.datepicker-orient-right:after {
right: 7px;
}
.datepicker-dropdown.datepicker-orient-top:before {
top: -7px;
}
.datepicker-dropdown.datepicker-orient-top:after {
top: -6px;
}
.datepicker-dropdown.datepicker-orient-bottom:before {
bottom: -7px;
border-bottom: 0;
border-top: 7px solid #999;
}
.datepicker-dropdown.datepicker-orient-bottom:after {
bottom: -6px;
border-bottom: 0;
border-top: 6px solid #ffffff;
}
.datepicker > div {
display: none;
}
.datepicker.days div.datepicker-days {
display: block;
}
.datepicker.months div.datepicker-months {
display: block;
}
.datepicker.years div.datepicker-years {
display: block;
}
.datepicker table {
margin: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.datepicker td,
.datepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
}
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td.today,
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(top, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #000;
}
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active {
background-color: #fbf069 \9;
}
.datepicker table tr td.today:hover:hover {
color: #000;
}
.datepicker table tr td.today.active:hover {
color: #fff;
}
.datepicker table tr td.range,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover {
background: #eeeeee;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today.disabled:hover {
background-color: #f3d17a;
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
background-image: linear-gradient(top, #f3c17a, #f3e97a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
border-color: #f3e97a #f3e97a #edde34;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today:hover:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled] {
background-color: #f3e97a;
}
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active {
background-color: #efe24b \9;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected.disabled:hover {
background-color: #9e9e9e;
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
background-image: linear-gradient(top, #b3b3b3, #808080);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
border-color: #808080 #808080 #595959;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected:hover:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled] {
background-color: #808080;
}
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active {
background-color: #666666 \9;
}
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datepicker table tr td span:hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
color: #999999;
}
.datepicker th.datepicker-switch {
width: 145px;
}
.datepicker thead tr:first-child th,
.datepicker tfoot tr th {
cursor: pointer;
}
.datepicker thead tr:first-child th:hover,
.datepicker tfoot tr th:hover {
background: #eeeeee;
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.datepicker thead tr:first-child th.cw {
cursor: default;
background-color: transparent;
}
.input-group.date .input-group-addon i,
.input-group.date .input-group-addon i {
display: block;
cursor: pointer;
width: 16px;
height: 16px;
}
.input-daterange input {
text-align: center;
}
.input-daterange input:first-child {
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
}
.input-daterange input:last-child {
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0;
}
.input-daterange .add-on {
display: inline-block;
width: auto;
min-width: 16px;
height: 18px;
padding: 4px 5px;
font-weight: normal;
line-height: 18px;
text-align: center;
text-shadow: 0 1px 0 #ffffff;
vertical-align: middle;
background-color: #eeeeee;
border: 1px solid #ccc;
margin-left: -5px;
margin-right: -5px;
}

39
css/ie.css Normal file
View File

@ -0,0 +1,39 @@
.hideInIE8 {
display: none;
}
.navbar-inner {
filter: none;
}
.box,
.discussions ul li {
border-top: none;
border-left: 1px solid #e4e6eb;
border-right: 1px solid #e4e6eb;
border-bottom: 2px solid #e4e6eb;
}
a.brand {
position: absolute;
left: 0px;
}
.container-fluid-full {
overflow: hidden;
position: relative;
height: 100%;
}
.container-fluid-full #content {
width: 85.578%;
padding: 28px;
margin: 0px 0px;
margin-left: 14.422% !important;
}
.container-fluid-full #sidebar-left {
margin-left: 0px !important;
position: absolute;
height: 100%;
}
footer {
position: relative;
}

86
css/ie9.css Normal file
View File

@ -0,0 +1,86 @@
.navbar-inner {
filter: none;
}
.dark {
right: -17px;
}
.verticalChart .singleBar .bar .value span{
color: #3b3b41;
}
hr {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIwLjI1Ii8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmOWY5ZjkiIHN0b3Atb3BhY2l0eT0iMC4yNSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.box-header {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNGY0ZjQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.btn3d:before {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2ViZWFlOCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.login-box {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y1ZjVmNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjE5JSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9Ijc3JSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderOverlay,
.progressBarOverlay {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2ViZWFlOCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.slider {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZjZmNmYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmYWZhZmEiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderVertical {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxJSIgc3RvcC1jb2xvcj0iI2ViZWFlOCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderBlue .ui-slider-range, .progressBlue .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzY3YzJlZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMyZmFiZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderGreen .ui-slider-range, .progressGreen .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2JkZWE3NCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiNmUzNzAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderDarkGreen .ui-slider-range, .progressDarkGreen .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzc4Y2Q1MSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM1YWFkMzQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderPink .ui-slider-range, .progressPink .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U4NGM4YSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlMjE2NjgiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderOrange .ui-slider-range, .progressOrange .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhNjAzZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmYTU4MzMiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderLightOrange .ui-slider-range, .progressLightOrange .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhYmIzZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNGE1MDYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderRed .ui-slider-range, .progressRed .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmNTQ1NCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZjAwMDAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.sliderYellow .ui-slider-range, .progressYellow .ui-progressbar-value {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2VhZTg3NCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlM2UyNzAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.progress {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZjZmNmYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmYWZhZmEiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.progressSlim {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZjZmNmYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmYWZhZmEiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}
.quick-button,
.quick-button-small {
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZhZmFmYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlZmVmZWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
}

459
css/style.css Normal file
View File

@ -0,0 +1,459 @@
/*
HumHub Style CSS
Author: Andreas Strobel
Website: http://www.humhub.org
Table of Bootstrap modifications:
---------------------------------------------
1) General
2) Topbar (replaces the Bootstrap Navbar)
3) Navs (Nav-Tabs & Nav-Pills)
4) Media Object
5) Panels
6) Pagination
7) Yii Components
8) HumHub Components
9) Third Party Tools
10) Responsive modifications
*/
body {
padding-top: 130px;
background-color: #f4f4f4;
}
a:hover {
text-decoration: none;
}
hr {
margin-top: 10px;
margin-bottom: 10px;
}
.col-md-1,
.col-md-2,
.col-md-3,
.col-md-4,
.col-md-5,
.col-md-6,
.col-md-7,
.col-md-8,
.col-md-9,
.col-md-10,
.col-md-11,
.col-md-12 {
position: inherit;
}
.topbar {
position: fixed;
display: block;
height: 50px;
width: 100%;
padding-left: 15px;
padding-right: 15px;
}
.topbar ul.nav {
float: left;
}
.topbar ul.nav > li {
float: left;
}
.topbar ul.nav > li > a {
padding-top: 15px;
padding-bottom: 15px;
line-height: 20px;
}
.topbar .dropdown-footer {
margin: 10px;
}
#topbar-first {
top: 0;
background-color: #101010;
z-index: 1030;
}
#topbar-first .nav > li > a:hover,
#topbar-first .nav > .open > a {
background-color: #2a2a2a;
}
#topbar-first .nav > .account {
height: 50px;
margin-left: 20px;
}
#topbar-first .nav > .account img {
margin-left: 10px;
}
#topbar-first .nav > .account .dropdown-toggle {
padding: 10px 5px 8px 5px;
line-height: 1.1em;
text-align: left;
}
#topbar-first .nav > .account .dropdown-toggle span {
font-size: 12px;
}
#topbar-first .topbar-brand {
position: relative;
z-index: 2;
}
#topbar-first .topbar-actions {
position: relative;
z-index: 3;
}
#topbar-first .notifications {
position: absolute;
left: 0;
right: 0;
text-align: center;
z-index: 1;
}
#topbar-first .notifications .btn-group {
position: relative;
text-align: left;
}
#topbar-first .notifications .btn-group > a {
padding: 5px 10px;
margin: 10px 2px;
display: inline-block;
border-radius: 2px;
text-decoration: none;
text-align: left;
}
#topbar-first .notifications .btn-group > .label {
position: absolute;
top: 4px;
right: -2px;
}
#topbar-first .notifications #dropdown-notifications {
width: 350px;
margin-left: -148px;
}
#topbar-first .notifications #dropdown-notifications li {
position: relative;
}
#topbar-first .notifications #dropdown-notifications li i.approval {
position: absolute;
left: 6px;
top: 35px;
font-size: 14px;
}
#topbar-first .notifications #dropdown-notifications li i.accepted {
color: #5cb85c;
}
#topbar-first .notifications #dropdown-notifications li i.declined {
color: #d9534f;
}
#topbar-first .notifications #dropdown-notifications li .media {
position: relative;
}
#topbar-first .notifications #dropdown-notifications li .media .img-space {
position: absolute;
top: 14px;
left: 14px;
}
#topbar-second {
top: 50px;
background-color: #f8f8f8;
z-index: 1029;
}
#topbar-second .dropdown-menu {
padding-top: 0;
padding-bottom: 0;
}
#topbar-second #space-menu-dropdown,
#topbar-second #search-menu-dropdown {
width: 400px;
}
#topbar-second #space-menu-dropdown .media-list,
#topbar-second #search-menu-dropdown .media-list {
max-height: 400px;
overflow: auto;
}
#topbar-second #space-menu-dropdown form,
#topbar-second #search-menu-dropdown form {
margin: 10px;
}
#topbar-second #space-menu-dropdown .search-reset,
#topbar-second #search-menu-dropdown .search-reset {
position: absolute;
color: #999;
margin: 10px;
top: 8px;
right: 10px;
display: none;
cursor: pointer;
}
.nav-tabs {
margin-bottom: 10px;
}
.media-list li {
padding: 10px;
border-bottom: 1px solid #eee;
position: relative;
}
.media-list li:hover,
.media-list li.selected {
background-color: #eee;
}
.panel .statistics {
margin-top: 40px;
margin-right: 20px;
}
.panel .statistics .entry {
margin-left: 20px;
}
.panel .statistics .entry .count {
font-size: 30px;
}
.panel.profile {
position: relative;
}
.panel.profile .controls {
position: absolute;
top: 10px;
right: 10px;
}
.panel.members .panel-body a img,
.panel.groups .panel-body a img,
.panel.follower .panel-body a img,
.panel.spaces .panel-body a img {
margin-bottom: 5px;
}
.pagination-container {
text-align: center;
}
.grid-view img {
width: 24px;
height: 24px;
}
.errorMessage {
color: red;
padding: 10px 0;
}
.error {
border-color: red !important;
}
.loader {
height: 60px;
background: url('../img/loader.gif') no-repeat center center;
}
.loader-small {
height: 20px;
width: 20px;
}
ul.tag_input {
list-style: none;
background-color: #ffffff;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
padding: 0 0 9px 4px;
}
ul.tag_input li img {
margin: 0 5px 0 0;
}
.tag_input_field {
outline: none;
border: none !important;
padding: 5px 4px 0px 4px !important;
width: 170px;
margin: 2px 0 0 0 !important;
}
.userInput,
.spaceInput {
background-color: #428bca;
color: #ffffff;
border-radius: 3px;
font-size: 12px !important;
padding: 2px;
float: left;
margin: 4px 4px 0 0;
}
.userInput i,
.spaceInput i {
padding: 0px 6px;
font-size: 14px;
cursor: pointer;
line-height: 8px;
}
#userpicker li > a,
#spacepicker li > a {
padding-left: 10px;
}
#userpicker li.selected,
#spacepicker li.selected {
background-color: #eee;
}
.activities {
max-height: 400px;
overflow: auto;
}
.activities li .media {
position: relative;
}
.activities li .media .img-space {
position: absolute;
top: 14px;
left: 14px;
}
.wall-entry {
position: relative;
}
.wall-entry .media {
overflow: visible;
}
.wall-entry .media .img-space {
position: absolute;
top: 60px;
left: 60px;
}
.wall-entry .well {
margin-bottom: 0;
}
.wall-entry .well .comment .show-all-link {
font-size: 12px;
}
.media:after {
content: '';
clear: both;
display: block;
}
.wall-entry .preferences {
position: absolute;
right: 1px;
top: 1px;
}
.wall-entry-controls {
font-size: 12px;
margin-top: 10px;
margin-bottom: 10px;
}
.tags {
margin: 5px 0;
}
.tags .tag {
margin-bottom: 5px;
}
.placeholder {
padding: 15px;
}
.space-member-sign {
color: #5cb85c;
position: absolute;
top: 50px;
left: 50px;
font-size: 18px;
}
.mime {
background-repeat: no-repeat;
background-position: 0 0;
}
.mime-word {
background-image: url('../img/mime/word.png');
}
.mime-excel {
background-image: url('../img/mime/excel.png');
}
.mime-powerpoint {
background-image: url('../img/mime/powerpoint.png');
}
.mime-pdf {
background-image: url('../img/mime/pdf.png');
}
.mime-zip {
background-image: url('../img/mime/zip.png');
}
.mime-image {
background-image: url('../img/mime/image.png');
}
.mime-file {
background-image: url('../img/mime/file.png');
}
.mime-photoshop {
background-image: url('../img/mime/photoshop.png');
}
.mime-illustrator {
background-image: url('../img/mime/illustrator.png');
}
.mime-flash {
background-image: url('../img/mime/flash.png');
}
.mime-audio {
background-image: url('../img/mime/audio.png');
}
.files {
padding-left: 0;
}
.highlight {
background-color: #fffbc1;
}
@media (max-width: 767px) {
.topbar {
padding-left: 0;
padding-right: 0;
}
#space-menu > .title {
display: none;
}
#space-menu-dropdown {
width: 300px !important;
}
#search-menu-dropdown {
width: 300px !important;
}
.notifications {
position: inherit !important;
float: left !important;
}
#dropdown-notifications {
width: 300px !important;
margin-left: 0 !important;
}
.profile .media > a {
float: none !important;
margin-right: 0;
}
.profile .media > a img {
margin-bottom: 10px;
}
.profile .statistics {
float: none !important;
}
/*.wall-entry {
.media > a {
float: none !important;
img {
display: inline;
}
}
.comment .media > a {
float: left !important;
img {
display: block;
}
}
.media-body {
.media-heading {
position: absolute;
top: 20px;
left: 100px;
small {
display: block;
padding-top: 5px;
}
}
.content {
margin-top: 20px;
}
}
}*/
}

620
css/style.less Normal file
View File

@ -0,0 +1,620 @@
/*
HumHub Style CSS
Author: Andreas Strobel
Website: http://www.humhub.org
Table of Bootstrap modifications:
---------------------------------------------
1) General
2) Topbar (replaces the Bootstrap Navbar)
3) Navs (Nav-Tabs & Nav-Pills)
4) Media Object
5) Panels
6) Pagination
7) Yii Components
8) HumHub Components
9) Third Party Tools
10) Responsive modifications
*/
//
// 1) General
// --------------------------------------------------
body {
padding-top: 130px;
background-color: #f4f4f4;
}
a:hover {
text-decoration: none;
}
hr {
margin-top: 10px;
margin-bottom: 10px;
}
// Cols (change position property to prevent the cutting of tooltips or menus)
.col-md-1,
.col-md-2,
.col-md-3,
.col-md-4,
.col-md-5,
.col-md-6,
.col-md-7,
.col-md-8,
.col-md-9,
.col-md-10,
.col-md-11,
.col-md-12 {
position: inherit;
}
//
// 2) Topbar
// --------------------------------------------------
.topbar {
position: fixed;
display: block;
height: 50px;
width: 100%;
padding-left: 15px;
padding-right: 15px;
ul.nav {
float: left;
}
ul.nav > li {
float: left;
}
ul.nav > li > a {
padding-top: 15px;
padding-bottom: 15px;
line-height: 20px;
}
.dropdown-footer {
margin: 10px;
}
}
#topbar-first {
top: 0;
background-color: #101010;
z-index: 1030;
.nav > li > a:hover, .nav > .open > a {
background-color: lighten(#101010, 10%);;
}
.nav > .account {
height: 50px;
margin-left: 20px;
img {
margin-left: 10px;
}
.dropdown-toggle {
padding: 10px 5px 8px 5px;
line-height: 1.1em;
text-align: left;
span {
font-size: 12px;
}
}
}
.topbar-brand {
position: relative;
z-index: 2;
}
.topbar-actions {
position: relative;
z-index: 3;
}
.notifications {
position: absolute;
left: 0;
right: 0;
text-align: center;
z-index: 1;
.btn-group {
position: relative;
text-align: left;
}
.btn-group > a {
padding: 5px 10px;
margin: 10px 2px;
display: inline-block;
border-radius: 2px;
text-decoration: none;
text-align: left;
}
.btn-group > .label {
position: absolute;
top: 4px;
right: -2px;
}
#dropdown-notifications {
width: 350px;
margin-left: -148px;
li {
position: relative;
i.approval {
position: absolute;
left: 6px;
top: 35px;
font-size: 14px;
}
i.accepted {
color: #5cb85c;
}
i.declined {
color: #d9534f;
}
}
li .media {
position: relative;
}
li .media .img-space {
position: absolute;
top: 14px;
left: 14px;
}
}
}
}
#topbar-second {
top: 50px;
background-color: #f8f8f8;
z-index: 1029;
.dropdown-menu {
padding-top: 0;
padding-bottom: 0;
}
// Space dropdown menu
#space-menu-dropdown, #search-menu-dropdown {
width: 400px;
.media-list {
max-height: 400px;
overflow: auto;
}
form {
margin: 10px;
}
.search-reset {
position: absolute;
color: #999;
margin: 10px;
top: 8px;
right: 10px;
display: none;
cursor: pointer;
}
}
}
//
// 3) Navs (Nav-Tabs & Nav-Pills)
// --------------------------------------------------
.nav-tabs {
margin-bottom: 10px;
}
//
// 4) Media-Object
// --------------------------------------------------
.media-list {
li {
padding: 10px;
border-bottom: 1px solid #eee;
position: relative;
}
li:hover, li.selected {
background-color: #eee;
}
}
//
// 5) Panels
// --------------------------------------------------
.panel {
.statistics {
margin-top: 40px;
margin-right: 20px;
.entry {
margin-left: 20px;
.count {
font-size: 30px;
}
}
}
}
.panel.profile {
position: relative;
.controls {
position: absolute;
top: 10px;
right: 10px;
}
}
.panel.members, .panel.groups, .panel.follower, .panel.spaces {
.panel-body a img {
margin-bottom: 5px;
}
}
//
// 6) Pagination
// --------------------------------------------------
.pagination-container {
text-align: center;
}
//
// 7) Yii Components
// --------------------------------------------------
.grid-view {
img {
width: 24px;
height: 24px;
}
}
// Errror handling
.errorMessage {
color: red;
padding: 10px 0;
}
.error {
border-color: red !important;
}
//
// 8) HumHub Components
// --------------------------------------------------
// Ajax loader
.loader {
height: 60px;
background: url('../img/loader.gif') no-repeat center center;
}
.loader-small {
height: 20px;
width: 20px;
}
// User- & Space picker
ul.tag_input {
list-style: none;
background-color: #ffffff;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
padding: 0 0 9px 4px;
li img {
margin: 0 5px 0 0;
}
}
.tag_input_field {
outline: none;
border: none !important;
padding: 5px 4px 0px 4px !important;
width: 170px;
margin: 2px 0 0 0 !important;
}
.userInput, .spaceInput {
background-color: #428bca;
color: #ffffff;
border-radius: 3px;
font-size: 12px !important;
padding: 2px;
float: left;
margin: 4px 4px 0 0;
}
.userInput i, .spaceInput i {
padding: 0px 6px;
font-size: 14px;
cursor: pointer;
line-height: 8px;
}
#userpicker, #spacepicker {
li > a {
padding-left: 10px;
}
li.selected {
//padding-left: 6px;
background-color: #eee;
}
}
// Activities
.activities {
max-height: 400px;
overflow: auto;
li .media {
position: relative;
}
li .media .img-space {
position: absolute;
top: 14px;
left: 14px;
}
}
// Wall-Entries
.wall-entry {
position: relative;
.media {
overflow: visible;
.img-space {
position: absolute;
top: 60px;
left: 60px;
}
}
.well {
margin-bottom: 0;
.comment {
.show-all-link {
font-size: 12px;
}
}
}
}
.media:after {
content: '';
clear: both;
display: block;
}
.wall-entry {
.preferences {
position: absolute;
right: 1px;
top: 1px;
}
}
.wall-entry-controls {
font-size: 12px;
margin-top: 10px;
margin-bottom: 10px;
}
// Tags
.tags {
margin: 5px 0;
.tag {
margin-bottom: 5px;
}
}
// Placeholder text for empty content
.placeholder {
padding: 15px;
}
// Member sign for directory list
.space-member-sign {
color: #5cb85c;
position: absolute;
top: 50px;
left: 50px;
font-size: 18px;
}
// Mime-Types
.mime {
background-repeat: no-repeat;
background-position: 0 0;
}
.mime-word {
background-image: url('../img/mime/word.png');
}
.mime-excel {
background-image: url('../img/mime/excel.png');
}
.mime-powerpoint {
background-image: url('../img/mime/powerpoint.png');
}
.mime-pdf {
background-image: url('../img/mime/pdf.png');
}
.mime-zip {
background-image: url('../img/mime/zip.png');
}
.mime-image {
background-image: url('../img/mime/image.png');
}
.mime-file {
background-image: url('../img/mime/file.png');
}
.mime-photoshop {
background-image: url('../img/mime/photoshop.png');
}
.mime-illustrator {
background-image: url('../img/mime/illustrator.png');
}
.mime-flash {
background-image: url('../img/mime/flash.png');
}
.mime-audio {
background-image: url('../img/mime/audio.png');
}
.files {
padding-left: 0;
}
//
// 9) Third Party Tools
// --------------------------------------------------
.highlight {
background-color: #fffbc1;
}
//
// 10) Responsive modifications
// --------------------------------------------------
@media (max-width: 767px) {
.topbar {
padding-left: 0;
padding-right: 0;
}
#space-menu > .title {
display: none;
}
#space-menu-dropdown {
width: 300px !important;
}
#search-menu-dropdown {
width: 300px !important;
}
.notifications {
position: inherit !important;
float: left !important;
}
#dropdown-notifications {
width: 300px !important;
margin-left: 0 !important;
}
.profile {
.media > a {
float: none !important;
margin-right: 0;
img {
margin-bottom: 10px;
}
}
.statistics {
float: none !important;
}
}
/*.wall-entry {
.media > a {
float: none !important;
img {
display: inline;
}
}
.comment .media > a {
float: left !important;
img {
display: block;
}
}
.media-body {
.media-heading {
position: absolute;
top: 20px;
left: 100px;
small {
display: block;
padding-top: 5px;
}
}
.content {
margin-top: 20px;
}
}
}*/
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
ico/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
img/loader.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
img/mime/audio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

BIN
img/mime/excel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

BIN
img/mime/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

BIN
img/mime/flash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

BIN
img/mime/illustrator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

BIN
img/mime/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

BIN
img/mime/pdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

BIN
img/mime/photoshop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

BIN
img/mime/powerpoint.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

BIN
img/mime/word.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

BIN
img/mime/zip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

39
index.php Normal file
View File

@ -0,0 +1,39 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
$yii = dirname(__FILE__) . '/protected/vendors/yii/yii.php';
$config = dirname(__FILE__) . '/protected/config/main.php';
$appClass = dirname(__FILE__) . '/protected/components/WebApplication.php';
// enable the following 3 lines when in development/testing
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', 3);
ini_set('error_reporting', E_ALL);
require_once($yii);
require_once($appClass);
$app = Yii::createApplication('WebApplication', $config);
Yii::import('application.vendors.*');
EZendAutoloader::$prefixes = array('Zend', 'Custom');
Yii::import("ext.yiiext.components.zendAutoloader.EZendAutoloader", true);
Yii::registerAutoloader(array("EZendAutoloader", "loadClass"), true);
$app->run();

132
js/app.js Normal file
View File

@ -0,0 +1,132 @@
/**
* Holds all already loaded javascript libaries
*
* @type HashTable
*/
var currentLoadedJavaScripts = new HashTable();
/**
* Looks for script tags inside the given string and checks if the files
* are already loaded.
*
* When already loaded, the scripts will ignored.
*
* @returns {undefined}
*/
function parseHtml(htmlString) {
var re = /<script type="text\/javascript" src="([\s\S]*?)"><\/script>/gm;
var match;
while (match = re.exec(htmlString)) {
js = match[1];
if (currentLoadedJavaScripts.hasItem(js)) {
// Remove Script Tag
//console.log("Ignore load of : "+js);
htmlString = htmlString.replace(match[0], "");
} else {
// Let Script Tag
//console.log("First load of: "+js);
currentLoadedJavaScripts.setItem(js, 1);
}
}
return htmlString;
}
/**
* Hashtable
*
* Javscript Class which represents a hashtable.
*
* @param {type} obj
* @returns {HashTable}
*/
function HashTable(obj)
{
this.length = 0;
this.items = {};
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
this.items[p] = obj[p];
this.length++;
}
}
this.setItem = function(key, value)
{
var previous = undefined;
if (this.hasItem(key)) {
previous = this.items[key];
}
else {
this.length++;
}
this.items[key] = value;
return previous;
}
this.getItem = function(key) {
return this.hasItem(key) ? this.items[key] : undefined;
}
this.hasItem = function(key)
{
return this.items.hasOwnProperty(key);
}
this.removeItem = function(key)
{
if (this.hasItem(key)) {
previous = this.items[key];
this.length--;
delete this.items[key];
return previous;
}
else {
return undefined;
}
}
this.keys = function()
{
var keys = [];
for (var k in this.items) {
if (this.hasItem(k)) {
keys.push(k);
}
}
return keys;
}
this.values = function()
{
var values = [];
for (var k in this.items) {
if (this.hasItem(k)) {
values.push(this.items[k]);
}
}
return values;
}
this.each = function(fn) {
for (var k in this.items) {
if (this.hasItem(k)) {
fn(k, this.items[k]);
}
}
}
this.clear = function()
{
this.items = {}
this.length = 0;
}
}

1396
js/bootstrap-datepicker.js vendored Normal file

File diff suppressed because it is too large Load Diff

9
js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

521
js/bootstrap3-wysihtml5.js vendored Normal file
View File

@ -0,0 +1,521 @@
!function($, wysi) {
"use strict";
var tpl = {
"font-styles": function(locale, options) {
var size = (options && options.size) ? ' btn-'+options.size : '';
return "<li class='dropdown'>" +
"<a class='btn dropdown-toggle btn-" + size + " btn-default' data-toggle='dropdown' href='#'>" +
"<i class='glyphicon glyphicon-font'></i>&nbsp;<span class='current-font'>" + locale.font_styles.normal + "</span>&nbsp;<b class='caret'></b>" +
"</a>" +
"<ul class='dropdown-menu'>" +
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='div' tabindex='-1'>" + locale.font_styles.normal + "</a></li>" +
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h1' tabindex='-1'>" + locale.font_styles.h1 + "</a></li>" +
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h2' tabindex='-1'>" + locale.font_styles.h2 + "</a></li>" +
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h3' tabindex='-1'>" + locale.font_styles.h3 + "</a></li>" +
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h4'>" + locale.font_styles.h4 + "</a></li>" +
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h5'>" + locale.font_styles.h5 + "</a></li>" +
"<li><a data-wysihtml5-command='formatBlock' data-wysihtml5-command-value='h6'>" + locale.font_styles.h6 + "</a></li>" +
"</ul>" +
"</li>";
},
"emphasis": function(locale, options) {
var size = (options && options.size) ? ' btn-'+options.size : '';
return "<li>" +
"<div class='btn-group'>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='bold' title='CTRL+B' tabindex='-1'>" + locale.emphasis.bold + "</a>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='italic' title='CTRL+I' tabindex='-1'>" + locale.emphasis.italic + "</a>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='underline' title='CTRL+U' tabindex='-1'>" + locale.emphasis.underline + "</a>" +
"</div>" +
"</li>";
},
"lists": function(locale, options) {
var size = (options && options.size) ? ' btn-'+options.size : '';
return "<li>" +
"<div class='btn-group'>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='insertUnorderedList' title='" + locale.lists.unordered + "' tabindex='-1'><i class='glyphicon glyphicon-list'></i></a>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='insertOrderedList' title='" + locale.lists.ordered + "' tabindex='-1'><i class='glyphicon glyphicon-th-list'></i></a>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='Outdent' title='" + locale.lists.outdent + "' tabindex='-1'><i class='glyphicon glyphicon-indent-right'></i></a>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='Indent' title='" + locale.lists.indent + "' tabindex='-1'><i class='glyphicon glyphicon-indent-left'></i></a>" +
"</div>" +
"</li>";
},
"link": function(locale, options) {
var size = (options && options.size) ? ' btn-'+options.size : '';
return "<li>" +
""+
"<div class='bootstrap-wysihtml5-insert-link-modal modal fade'>" +
"<div class='modal-dialog'>"+
"<div class='modal-content'>"+
"<div class='modal-header'>" +
"<a class='close' data-dismiss='modal'>&times;</a>" +
"<h4>" + locale.link.insert + "</h4>" +
"</div>" +
"<div class='modal-body'>" +
"<input value='http://' class='bootstrap-wysihtml5-insert-link-url form-control'>" +
"<label class='checkbox'> <input type='checkbox' class='bootstrap-wysihtml5-insert-link-target' checked>" + locale.link.target + "</label>" +
"</div>" +
"<div class='modal-footer'>" +
"<button class='btn btn-default' data-dismiss='modal'>" + locale.link.cancel + "</button>" +
"<button href='#' class='btn btn-primary' data-dismiss='modal'>" + locale.link.insert + "</button>" +
"</div>" +
"</div>" +
"</div>" +
"</div>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='createLink' title='" + locale.link.insert + "' tabindex='-1'><i class='glyphicon glyphicon-share'></i></a>" +
"</li>";
},
"image": function(locale, options) {
var size = (options && options.size) ? ' btn-'+options.size : '';
return "<li>" +
"<div class='bootstrap-wysihtml5-insert-image-modal modal fade'>" +
"<div class='modal-dialog'>"+
"<div class='modal-content'>"+
"<div class='modal-header'>" +
"<a class='close' data-dismiss='modal'>&times;</a>" +
"<h4>" + locale.image.insert + "</h4>" +
"</div>" +
"<div class='modal-body'>" +
"<input value='http://' class='bootstrap-wysihtml5-insert-image-url form-control'>" +
"</div>" +
"<div class='modal-footer'>" +
"<button class='btn btn-default' data-dismiss='modal'>" + locale.image.cancel + "</button>" +
"<button class='btn btn-primary' data-dismiss='modal'>" + locale.image.insert + "</button>" +
"</div>" +
"</div>" +
"</div>" +
"</div>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-command='insertImage' title='" + locale.image.insert + "' tabindex='-1'><i class='glyphicon glyphicon-picture'></i></a>" +
"</li>";
},
"html": function(locale, options) {
var size = (options && options.size) ? ' btn-'+options.size : '';
return "<li>" +
"<div class='btn-group'>" +
"<a class='btn btn-" + size + " btn-default' data-wysihtml5-action='change_view' title='" + locale.html.edit + "' tabindex='-1'><i class='glyphicon glyphicon-pencil'></i></a>" +
"</div>" +
"</li>";
},
"color": function(locale, options) {
var size = (options && options.size) ? ' btn-'+options.size : '';
return "<li class='dropdown'>" +
"<a class='btn dropdown-toggle btn-" + size + " btn-default' data-toggle='dropdown' href='#' tabindex='-1'>" +
"<span class='current-color'>" + locale.colours.black + "</span>&nbsp;<b class='caret'></b>" +
"</a>" +
"<ul class='dropdown-menu'>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='black'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='black'>" + locale.colours.black + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='silver'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='silver'>" + locale.colours.silver + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='gray'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='gray'>" + locale.colours.gray + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='maroon'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='maroon'>" + locale.colours.maroon + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='red'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='red'>" + locale.colours.red + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='purple'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='purple'>" + locale.colours.purple + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='green'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='green'>" + locale.colours.green + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='olive'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='olive'>" + locale.colours.olive + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='navy'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='navy'>" + locale.colours.navy + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='blue'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='blue'>" + locale.colours.blue + "</a></li>" +
"<li><div class='wysihtml5-colors' data-wysihtml5-command-value='orange'></div><a class='wysihtml5-colors-title' data-wysihtml5-command='foreColor' data-wysihtml5-command-value='orange'>" + locale.colours.orange + "</a></li>" +
"</ul>" +
"</li>";
}
};
var templates = function(key, locale, options) {
return tpl[key](locale, options);
};
var Wysihtml5 = function(el, options) {
this.el = el;
var toolbarOpts = options || defaultOptions;
for(var t in toolbarOpts.customTemplates) {
tpl[t] = toolbarOpts.customTemplates[t];
}
this.toolbar = this.createToolbar(el, toolbarOpts);
this.editor = this.createEditor(options);
window.editor = this.editor;
$('iframe.wysihtml5-sandbox').each(function(i, el){
$(el.contentWindow).off('focus.wysihtml5').on({
'focus.wysihtml5' : function(){
$('li.dropdown').removeClass('open');
}
});
});
};
Wysihtml5.prototype = {
constructor: Wysihtml5,
createEditor: function(options) {
options = options || {};
// Add the toolbar to a clone of the options object so multiple instances
// of the WYISYWG don't break because "toolbar" is already defined
options = $.extend(true, {}, options);
options.toolbar = this.toolbar[0];
var editor = new wysi.Editor(this.el[0], options);
if(options && options.events) {
for(var eventName in options.events) {
editor.on(eventName, options.events[eventName]);
}
}
return editor;
},
createToolbar: function(el, options) {
var self = this;
var toolbar = $("<ul/>", {
'class' : "wysihtml5-toolbar",
'style': "display:none"
});
var culture = options.locale || defaultOptions.locale || "en";
for(var key in defaultOptions) {
var value = false;
if(options[key] !== undefined) {
if(options[key] === true) {
value = true;
}
} else {
value = defaultOptions[key];
}
if(value === true) {
toolbar.append(templates(key, locale[culture], options));
if(key === "html") {
this.initHtml(toolbar);
}
if(key === "link") {
this.initInsertLink(toolbar);
}
if(key === "image") {
this.initInsertImage(toolbar);
}
}
}
if(options.toolbar) {
for(key in options.toolbar) {
toolbar.append(options.toolbar[key]);
}
}
toolbar.find("a[data-wysihtml5-command='formatBlock']").click(function(e) {
var target = e.target || e.srcElement;
var el = $(target);
self.toolbar.find('.current-font').text(el.html());
});
toolbar.find("a[data-wysihtml5-command='foreColor']").click(function(e) {
var target = e.target || e.srcElement;
var el = $(target);
self.toolbar.find('.current-color').text(el.html());
});
this.el.before(toolbar);
return toolbar;
},
initHtml: function(toolbar) {
var changeViewSelector = "a[data-wysihtml5-action='change_view']";
toolbar.find(changeViewSelector).click(function(e) {
toolbar.find('a.btn').not(changeViewSelector).toggleClass('disabled');
});
},
initInsertImage: function(toolbar) {
var self = this;
var insertImageModal = toolbar.find('.bootstrap-wysihtml5-insert-image-modal');
var urlInput = insertImageModal.find('.bootstrap-wysihtml5-insert-image-url');
var insertButton = insertImageModal.find('.btn-primary');
var initialValue = urlInput.val();
var caretBookmark;
var insertImage = function() {
var url = urlInput.val();
urlInput.val(initialValue);
self.editor.currentView.element.focus();
if (caretBookmark) {
self.editor.composer.selection.setBookmark(caretBookmark);
caretBookmark = null;
}
self.editor.composer.commands.exec("insertImage", url);
};
urlInput.keypress(function(e) {
if(e.which == 13) {
insertImage();
insertImageModal.modal('hide');
}
});
insertButton.click(insertImage);
insertImageModal.on('shown', function() {
urlInput.focus();
});
insertImageModal.on('hide', function() {
self.editor.currentView.element.focus();
});
toolbar.find('a[data-wysihtml5-command=insertImage]').click(function() {
var activeButton = $(this).hasClass("wysihtml5-command-active");
if (!activeButton) {
self.editor.currentView.element.focus(false);
caretBookmark = self.editor.composer.selection.getBookmark();
insertImageModal.appendTo('body').modal('show');
insertImageModal.on('click.dismiss.modal', '[data-dismiss="modal"]', function(e) {
e.stopPropagation();
});
return false;
}
else {
return true;
}
});
},
initInsertLink: function(toolbar) {
var self = this;
var insertLinkModal = toolbar.find('.bootstrap-wysihtml5-insert-link-modal');
var urlInput = insertLinkModal.find('.bootstrap-wysihtml5-insert-link-url');
var targetInput = insertLinkModal.find('.bootstrap-wysihtml5-insert-link-target');
var insertButton = insertLinkModal.find('.btn-primary');
var initialValue = urlInput.val();
var caretBookmark;
var insertLink = function() {
var url = urlInput.val();
urlInput.val(initialValue);
self.editor.currentView.element.focus();
if (caretBookmark) {
self.editor.composer.selection.setBookmark(caretBookmark);
caretBookmark = null;
}
var newWindow = targetInput.prop("checked");
self.editor.composer.commands.exec("createLink", {
'href' : url,
'target' : (newWindow ? '_blank' : '_self'),
'rel' : (newWindow ? 'nofollow' : '')
});
};
var pressedEnter = false;
urlInput.keypress(function(e) {
if(e.which == 13) {
insertLink();
insertLinkModal.modal('hide');
}
});
insertButton.click(insertLink);
insertLinkModal.on('shown', function() {
urlInput.focus();
});
insertLinkModal.on('hide', function() {
self.editor.currentView.element.focus();
});
toolbar.find('a[data-wysihtml5-command=createLink]').click(function() {
var activeButton = $(this).hasClass("wysihtml5-command-active");
if (!activeButton) {
self.editor.currentView.element.focus(false);
caretBookmark = self.editor.composer.selection.getBookmark();
insertLinkModal.appendTo('body').modal('show');
insertLinkModal.on('click.dismiss.modal', '[data-dismiss="modal"]', function(e) {
e.stopPropagation();
});
return false;
}
else {
return true;
}
});
}
};
// these define our public api
var methods = {
resetDefaults: function() {
$.fn.wysihtml5.defaultOptions = $.extend(true, {}, $.fn.wysihtml5.defaultOptionsCache);
},
bypassDefaults: function(options) {
return this.each(function () {
var $this = $(this);
$this.data('wysihtml5', new Wysihtml5($this, options));
});
},
shallowExtend: function (options) {
var settings = $.extend({}, $.fn.wysihtml5.defaultOptions, options || {}, $(this).data());
var that = this;
return methods.bypassDefaults.apply(that, [settings]);
},
deepExtend: function(options) {
var settings = $.extend(true, {}, $.fn.wysihtml5.defaultOptions, options || {});
var that = this;
return methods.bypassDefaults.apply(that, [settings]);
},
init: function(options) {
var that = this;
return methods.shallowExtend.apply(that, [options]);
}
};
$.fn.wysihtml5 = function ( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.wysihtml5' );
}
};
$.fn.wysihtml5.Constructor = Wysihtml5;
var defaultOptions = $.fn.wysihtml5.defaultOptions = {
"font-styles": true,
"color": false,
"emphasis": true,
"lists": true,
"html": false,
"link": true,
"image": true,
"size": 'sm',
events: {},
parserRules: {
classes: {
// (path_to_project/lib/css/bootstrap3-wysiwyg5-color.css)
"wysiwyg-color-silver" : 1,
"wysiwyg-color-gray" : 1,
"wysiwyg-color-white" : 1,
"wysiwyg-color-maroon" : 1,
"wysiwyg-color-red" : 1,
"wysiwyg-color-purple" : 1,
"wysiwyg-color-fuchsia" : 1,
"wysiwyg-color-green" : 1,
"wysiwyg-color-lime" : 1,
"wysiwyg-color-olive" : 1,
"wysiwyg-color-yellow" : 1,
"wysiwyg-color-navy" : 1,
"wysiwyg-color-blue" : 1,
"wysiwyg-color-teal" : 1,
"wysiwyg-color-aqua" : 1,
"wysiwyg-color-orange" : 1
},
tags: {
"b": {},
"i": {},
"br": {},
"ol": {},
"ul": {},
"li": {},
"h1": {},
"h2": {},
"h3": {},
"h4": {},
"h5": {},
"h6": {},
"blockquote": {},
"u": 1,
"img": {
"check_attributes": {
"width": "numbers",
"alt": "alt",
"src": "url",
"height": "numbers"
}
},
"a": {
check_attributes: {
'href': "url", // important to avoid XSS
'target': 'alt',
'rel': 'alt'
}
},
"span": 1,
"div": 1,
// to allow save and edit files with code tag hacks
"code": 1,
"pre": 1
}
},
stylesheets: ["./css/bootstrap3-wysiwyg5-color.css"], // (path_to_project/lib/css/bootstrap3-wysiwyg5-color.css)
locale: "en"
};
if (typeof $.fn.wysihtml5.defaultOptionsCache === 'undefined') {
$.fn.wysihtml5.defaultOptionsCache = $.extend(true, {}, $.fn.wysihtml5.defaultOptions);
}
var locale = $.fn.wysihtml5.locale = {
en: {
font_styles: {
normal: "Normal text",
h1: "Heading 1",
h2: "Heading 2",
h3: "Heading 3",
h4: "Heading 4",
h5: "Heading 5",
h6: "Heading 6"
},
emphasis: {
bold: "Bold",
italic: "Italic",
underline: "Underline"
},
lists: {
unordered: "Unordered list",
ordered: "Ordered list",
outdent: "Outdent",
indent: "Indent"
},
link: {
insert: "Insert link",
cancel: "Cancel",
target: "Open link in new window"
},
image: {
insert: "Insert image",
cancel: "Cancel"
},
html: {
edit: "Edit HTML"
},
colours: {
black: "Black",
silver: "Silver",
gray: "Grey",
maroon: "Maroon",
red: "Red",
purple: "Purple",
green: "Green",
olive: "Olive",
navy: "Navy",
blue: "Blue",
orange: "Orange"
}
}
};
}(window.jQuery, window.wysihtml5);

View File

@ -0,0 +1,315 @@
// Generated by CoffeeScript 1.6.3
/*
Lightbox for Bootstrap 3 by @ashleydw
https://github.com/ashleydw/lightbox
License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
*/
(function () {
"use strict";
var EkkoLightbox;
EkkoLightbox = function (element, options) {
var content, footer, header, video_id,
_this = this;
this.options = $.extend({
gallery_parent_selector: '*:not(.row)',
title: null,
footer: null,
remote: null,
left_arrow_class: '.glyphicon .glyphicon-chevron-left',
right_arrow_class: '.glyphicon .glyphicon-chevron-right',
directional_arrows: true,
type: null,
onShow: function () {
},
onShown: function () {
},
onHide: function () {
},
onHidden: function () {
},
id: false
}, options || {});
this.$element = $(element);
content = '';
this.modal_id = this.options.modal_id ? this.options.modal_id : 'ekkoLightbox-' + Math.floor((Math.random() * 1000) + 1);
header = '<div class="modal-header"' + (this.options.title ? '' : ' style="display:none"') + '><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button><h4 class="modal-title">' + this.options.title + '</h4></div>';
footer = '<div class="modal-footer"' + (this.options.footer ? '' : ' style="display:none"') + '>' + this.options.footer + '</div>';
//footer = '<div class="modal-footer"><button type="button" class="btn btn-primary" data-dismiss="modal">Close</button></div>';
$(document.body).append('<div id="' + this.modal_id + '" class="ekko-lightbox modal" tabindex="-1"><div class="modal-dialog" style="margin-top: 0 !important"><div class="modal-content">' + header + '<div class="modal-body"><div class="ekko-lightbox-container"><div></div></div></div>' + footer + '</div></div></div>');
this.modal = $('#' + this.modal_id);
this.modal_body = this.modal.find('.modal-body').first();
this.lightbox_container = this.modal_body.find('.ekko-lightbox-container').first();
this.lightbox_body = this.lightbox_container.find('> div:first-child').first();
this.modal_arrows = null;
this.padding = {
left: parseFloat(this.modal_body.css('padding-left'), 10),
right: parseFloat(this.modal_body.css('padding-right'), 10),
bottom: parseFloat(this.modal_body.css('padding-bottom'), 10),
top: parseFloat(this.modal_body.css('padding-top'), 10)
};
if (!this.options.remote) {
this.error('No remote target given');
} else {
this.gallery = this.$element.data('gallery');
if (this.gallery) {
if (this.options.gallery_parent_selector === 'document.body' || this.options.gallery_parent_selector === '') {
this.gallery_items = $(document.body).find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
} else {
this.gallery_items = this.$element.parents(this.options.gallery_parent_selector).first().find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
}
this.gallery_index = this.gallery_items.index(this.$element);
$(document).on('keydown.ekkoLightbox', this.navigate.bind(this));
if (this.options.directional_arrows) {
this.lightbox_container.prepend('<div class="ekko-lightbox-nav-overlay"><a href="#" class="' + this.strip_stops(this.options.left_arrow_class) + '"></a><a href="#" class="' + this.strip_stops(this.options.right_arrow_class) + '"></a></div>');
this.modal_arrows = this.lightbox_container.find('div.ekko-lightbox-nav-overlay').first();
this.lightbox_container.find('a' + this.strip_spaces(this.options.left_arrow_class)).on('click', function (event) {
event.preventDefault();
return _this.navigate_left();
});
this.lightbox_container.find('a' + this.strip_spaces(this.options.right_arrow_class)).on('click', function (event) {
event.preventDefault();
return _this.navigate_right();
});
}
}
if (this.options.type) {
if (this.options.type === 'image') {
this.preloadImage(this.options.remote, true);
} else if (this.options.type === 'youtube' && (video_id = this.getYoutubeId(this.options.remote))) {
this.showYoutubeVideo(video_id);
} else if (this.options.type === 'vimeo') {
this.showVimeoVideo(this.options.remote);
} else {
this.error("Could not detect remote target type. Force the type using data-type=\"image|youtube|vimeo\"");
}
} else {
this.detectRemoteType(this.options.remote);
}
}
this.modal.on('show.bs.modal', this.options.onShow.bind(this)).on('shown.bs.modal',function () {
if (_this.modal_arrows) {
_this.resize(_this.lightbox_body.width());
}
return _this.options.onShown.call(_this);
}).on('hide.bs.modal', this.options.onHide.bind(this)).on('hidden.bs.modal',function () {
if (_this.gallery) {
$(document).off('keydown.ekkoLightbox');
}
_this.modal.remove();
return _this.options.onHidden.call(_this);
}).modal('show', options);
return this.modal;
};
EkkoLightbox.prototype = {
strip_stops: function (str) {
return str.replace(/\./g, '');
},
strip_spaces: function (str) {
return str.replace(/\s/g, '');
},
isImage: function (str) {
return str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
},
isSwf: function (str) {
return str.match(/\.(swf)((\?|#).*)?$/i);
},
getYoutubeId: function (str) {
var match;
match = str.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
if (match && match[2].length === 11) {
return match[2];
} else {
return false;
}
},
getVimeoId: function (str) {
if (str.indexOf('vimeo') > 0) {
return str;
} else {
return false;
}
},
navigate: function (event) {
event = event || window.event;
if (event.keyCode === 39 || event.keyCode === 37) {
if (event.keyCode === 39) {
return this.navigate_right();
} else if (event.keyCode === 37) {
return this.navigate_left();
}
}
},
navigate_left: function () {
var src;
if (this.gallery_index === 0) {
this.gallery_index = this.gallery_items.length - 1;
} else {
this.gallery_index--;
}
this.$element = $(this.gallery_items.get(this.gallery_index));
this.updateTitleAndFooter();
src = this.$element.attr('data-remote') || this.$element.attr('href');
return this.detectRemoteType(src);
},
navigate_right: function () {
var next, src;
if (this.gallery_index === this.gallery_items.length - 1) {
this.gallery_index = 0;
} else {
this.gallery_index++;
}
this.$element = $(this.gallery_items.get(this.gallery_index));
src = this.$element.attr('data-remote') || this.$element.attr('href');
this.updateTitleAndFooter();
this.detectRemoteType(src);
if (this.gallery_index + 1 < this.gallery_items.length) {
next = $(this.gallery_items.get(this.gallery_index + 1), false);
src = next.attr('data-remote') || next.attr('href');
if (this.isImage(src)) {
return this.preloadImage(src, false);
}
}
},
detectRemoteType: function (src) {
var video_id;
if (this.isImage(src)) {
return this.preloadImage(src, true);
} else if (video_id = this.getYoutubeId(src)) {
return this.showYoutubeVideo(video_id);
} else if (video_id = this.getVimeoId(src)) {
return this.showVimeoVideo(video_id);
} else {
return this.error("Could not detect remote target type. Force the type using data-type=\"image|youtube|vimeo\"");
}
},
updateTitleAndFooter: function () {
var caption, footer, header, title;
header = this.modal.find('.modal-dialog .modal-content .modal-header');
footer = this.modal.find('.modal-dialog .modal-content .modal-footer');
title = this.$element.data('title') || "";
caption = this.$element.data('footer') || "";
if (title) {
header.css('display', '').find('.modal-title').html(title);
} else {
header.css('display', 'none');
}
if (caption) {
footer.css('display', '').html(caption);
} else {
footer.css('display', 'none');
}
return this;
},
showLoading: function () {
this.lightbox_body.html('<div class="modal-loading"><div class="loader"></div></div>');
return this;
},
showYoutubeVideo: function (id) {
this.resize(560);
this.lightbox_body.html('<iframe width="560" height="315" src="//www.youtube.com/embed/' + id + '?badge=0&autoplay=1" frameborder="0" allowfullscreen></iframe>');
if (this.modal_arrows) {
return this.modal_arrows.css('display', 'none');
}
},
showVimeoVideo: function (id) {
this.resize(500);
this.lightbox_body.html('<iframe width="500" height="281" src="' + id + '?autoplay=1" frameborder="0" allowfullscreen></iframe>');
if (this.modal_arrows) {
return this.modal_arrows.css('display', 'none');
}
},
error: function (message) {
this.lightbox_body.html(message);
return this;
},
preloadImage: function (src, onLoadShowImage) {
var img,
_this = this;
_this.showLoading();
img = new Image();
if ((onLoadShowImage == null) || onLoadShowImage === true) {
img.onload = function () {
var image, width;
width = _this.checkImageDimensions(img.width);
image = $('<img />');
image.attr('src', img.src);
image.css('max-width', '100%');
_this.lightbox_body.html(image);
if (_this.modal_arrows) {
_this.modal_arrows.css('display', 'block');
}
return _this.resize(width);
};
img.onerror = function () {
return _this.error('Failed to load image: ' + src);
};
}
img.src = src;
return img;
},
resize: function (width) {
var width_inc_padding;
width_inc_padding = width + this.padding.left + this.padding.right;
//this.modal.find('.modal-content').css('width', width_inc_padding);
//this.modal.find('.modal-dialog').css('width', width_inc_padding + 20);
this.modal.find('.modal-content').animate({width: width_inc_padding}, 200);
this.modal.find('.modal-dialog').animate({width: width_inc_padding + 20}, 200);
this.lightbox_container.find('a').css('padding-top', function () {
return $(this).parent().height() / 2;
});
return this;
},
checkImageDimensions: function (max_width) {
var w, width;
w = $(window);
width = max_width;
if ((max_width + (this.padding.left + this.padding.right + 20)) > w.width()) {
width = w.width() - (this.padding.left + this.padding.right + 20);
}
return width - 20;
},
close: function () {
return this.modal.modal('hide');
}
};
$.fn.ekkoLightbox = function (options) {
return this.each(function () {
var $this;
$this = $(this);
options = $.extend({
remote: $this.attr('data-remote') || $this.attr('href'),
gallery_parent_selector: $this.attr('data-parent'),
type: $this.attr('data-type')
}, options, $this.data());
new EkkoLightbox(this, options);
return this;
});
};
$(document).delegate('*[data-toggle="lightbox"]', 'click', function (event) {
var $this;
event.preventDefault();
$this = $(this);
return $this.ekkoLightbox({
remote: $this.attr('data-remote') || $this.attr('href'),
gallery_parent_selector: $this.attr('data-parent'),
onShown: function () {
if (window.console) {
return console.log('Checking our the events huh?');
}
}
}).one('hide', function () {
return $this.is(':visible') && $this.focus();
});
});
}).call(this);

301
js/html5shiv.js vendored Normal file
View File

@ -0,0 +1,301 @@
/**
* @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
;(function(window, document) {
/*jshint evil:true */
/** version */
var version = '3.7.0';
/** Preset options */
var options = window.html5 || {};
/** Used to skip problem elements */
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
/** Not all elements can be cloned in IE **/
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
/** Detect whether the browser supports default html5 styles */
var supportsHtml5Styles;
/** Name of the expando, to work with multiple documents or to re-shiv one document */
var expando = '_html5shiv';
/** The id for the the documents expando */
var expanID = 0;
/** Cached data for each document */
var expandoData = {};
/** Detect whether the browser supports unknown elements */
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '<xyz></xyz>';
//if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
// assign a false positive if unable to shiv
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
// assign a false positive if detection fails => unable to shiv
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}());
/*--------------------------------------------------------------------------*/
/**
* Creates a style sheet with the given CSS text and adds it to the document.
* @private
* @param {Document} ownerDocument The document.
* @param {String} cssText The CSS text.
* @returns {StyleSheet} The style element.
*/
function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x<style>' + cssText + '</style>';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
/**
* Returns the value of `html5.elements` as an array.
* @private
* @returns {Array} An array of shived element node names.
*/
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
/**
* Returns the data associated to the given document
* @private
* @param {Document} ownerDocument The document.
* @returns {Object} An object of data.
*/
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
/**
* returns a shived element for the given nodeName and document
* @memberOf html5
* @param {String} nodeName name of the element
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived element.
*/
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
// Avoid adding some elements to fragments in IE < 9 because
// * Attributes like `name` or `type` cannot be set/changed once an element
// is inserted into a document/fragment
// * Link elements with `src` attributes that are inaccessible, as with
// a 403 response, will cause the tab/window to crash
// * Script elements appended to fragments will execute when their `src`
// or `text` property is set
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
}
/**
* returns a shived DocumentFragment for the given document
* @memberOf html5
* @param {Document} ownerDocument The context document.
* @returns {Object} The shived DocumentFragment.
*/
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i<l;i++){
clone.createElement(elems[i]);
}
return clone;
}
/**
* Shivs the `createElement` and `createDocumentFragment` methods of the document.
* @private
* @param {Document|DocumentFragment} ownerDocument The document.
* @param {Object} data of the document.
*/
function shivMethods(ownerDocument, data) {
if (!data.cache) {
data.cache = {};
data.createElem = ownerDocument.createElement;
data.createFrag = ownerDocument.createDocumentFragment;
data.frag = data.createFrag();
}
ownerDocument.createElement = function(nodeName) {
//abort shiv
if (!html5.shivMethods) {
return data.createElem(nodeName);
}
return createElement(nodeName, ownerDocument, data);
};
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
'var n=f.cloneNode(),c=n.createElement;' +
'h.shivMethods&&(' +
// unroll the `createElement` calls
getElements().join().replace(/[\w\-]+/g, function(nodeName) {
data.createElem(nodeName);
data.frag.createElement(nodeName);
return 'c("' + nodeName + '")';
}) +
');return n}'
)(html5, data.frag);
}
/*--------------------------------------------------------------------------*/
/**
* Shivs the given document.
* @memberOf html5
* @param {Document} ownerDocument The document to shiv.
* @returns {Document} The shived document.
*/
function shivDocument(ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
}
var data = getExpandoData(ownerDocument);
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
data.hasCSS = !!addStyleSheet(ownerDocument,
// corrects block display not defined in IE6/7/8/9
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
// adds styling not present in IE6/7/8/9
'mark{background:#FF0;color:#000}' +
// hides non-rendered elements
'template{display:none}'
);
}
if (!supportsUnknownElements) {
shivMethods(ownerDocument, data);
}
return ownerDocument;
}
/*--------------------------------------------------------------------------*/
/**
* The `html5` object is exposed so that more elements can be shived and
* existing shiving can be detected on iframes.
* @type Object
* @example
*
* // options can be changed before the script is included
* html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
*/
var html5 = {
/**
* An array or space separated string of node names of the elements to shiv.
* @memberOf html5
* @type Array|String
*/
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
/**
* current version of html5shiv
*/
'version': version,
/**
* A flag to indicate that the HTML5 style sheet should be inserted.
* @memberOf html5
* @type Boolean
*/
'shivCSS': (options.shivCSS !== false),
/**
* Is equal to true if a browser supports creating unknown/HTML5 elements
* @memberOf html5
* @type boolean
*/
'supportsUnknownElements': supportsUnknownElements,
/**
* A flag to indicate that the document's `createElement` and `createDocumentFragment`
* methods should be overwritten.
* @memberOf html5
* @type Boolean
*/
'shivMethods': (options.shivMethods !== false),
/**
* A string to describe the type of `html5` object ("default" or "default print").
* @memberOf html5
* @type String
*/
'type': 'default',
// shivs the document according to the specified `html5` object options
'shivDocument': shivDocument,
//creates a shived element
createElement: createElement,
//creates a shived documentFragment
createDocumentFragment: createDocumentFragment
};
/*--------------------------------------------------------------------------*/
// expose html5
window.html5 = html5;
// shiv the document
shivDocument(document);
}(this, document));

7
js/jquery.autosize.min.js vendored Normal file
View File

@ -0,0 +1,7 @@
/*!
Autosize v1.17.8 - 2013-09-07
Automatically adjust textarea height based on user input.
(c) 2013 Jack Moore - http://www.jacklmoore.com/autosize
license: http://www.opensource.org/licenses/mit-license.php
*/
(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(window.jQuery||window.$)})(function(e){var t,o={className:"autosizejs",append:"",callback:!1,resizeDelay:10},i='<textarea tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;"/>',n=["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent"],s=e(i).data("autosize",!0)[0];s.style.lineHeight="99px","99px"===e(s).css("lineHeight")&&n.push("lineHeight"),s.style.lineHeight="",e.fn.autosize=function(i){return this.length?(i=e.extend({},o,i||{}),s.parentNode!==document.body&&e(document.body).append(s),this.each(function(){function o(){var t,o;"getComputedStyle"in window?(t=window.getComputedStyle(u),o=u.getBoundingClientRect().width,e.each(["paddingLeft","paddingRight","borderLeftWidth","borderRightWidth"],function(e,i){o-=parseInt(t[i],10)}),s.style.width=o+"px"):s.style.width=Math.max(p.width(),0)+"px"}function a(){var a={};if(t=u,s.className=i.className,d=parseInt(p.css("maxHeight"),10),e.each(n,function(e,t){a[t]=p.css(t)}),e(s).css(a),o(),window.chrome){var r=u.style.width;u.style.width="0px",u.offsetWidth,u.style.width=r}}function r(){var e,n;t!==u?a():o(),s.value=u.value+i.append,s.style.overflowY=u.style.overflowY,n=parseInt(u.style.height,10),s.scrollTop=0,s.scrollTop=9e4,e=s.scrollTop,d&&e>d?(u.style.overflowY="scroll",e=d):(u.style.overflowY="hidden",c>e&&(e=c)),e+=f,n!==e&&(u.style.height=e+"px",w&&i.callback.call(u,u))}function l(){clearTimeout(h),h=setTimeout(function(){var e=p.width();e!==g&&(g=e,r())},parseInt(i.resizeDelay,10))}var d,c,h,u=this,p=e(u),f=0,w=e.isFunction(i.callback),z={height:u.style.height,overflow:u.style.overflow,overflowY:u.style.overflowY,wordWrap:u.style.wordWrap,resize:u.style.resize},g=p.width();p.data("autosize")||(p.data("autosize",!0),("border-box"===p.css("box-sizing")||"border-box"===p.css("-moz-box-sizing")||"border-box"===p.css("-webkit-box-sizing"))&&(f=p.outerHeight()-p.height()),c=Math.max(parseInt(p.css("minHeight"),10)-f||0,p.height()),p.css({overflow:"hidden",overflowY:"hidden",wordWrap:"break-word",resize:"none"===p.css("resize")||"vertical"===p.css("resize")?"none":"horizontal"}),"onpropertychange"in u?"oninput"in u?p.on("input.autosize keyup.autosize",r):p.on("propertychange.autosize",function(){"value"===event.propertyName&&r()}):p.on("input.autosize",r),i.resizeDelay!==!1&&e(window).on("resize.autosize",l),p.on("autosize.resize",r),p.on("autosize.resizeIncludeStyle",function(){t=null,r()}),p.on("autosize.destroy",function(){t=null,clearTimeout(h),e(window).off("resize",l),p.off("autosize").off(".autosize").css(z).removeData("autosize")}),r())})):this}});

113
js/jquery.cookie.js Normal file
View File

@ -0,0 +1,113 @@
/*!
* jQuery Cookie Plugin v1.4.0
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2013 Klaus Hartl
* Released under the MIT license
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else {
// Browser globals.
factory(jQuery);
}
}(function ($) {
var pluses = /\+/g;
function encode(s) {
return config.raw ? s : encodeURIComponent(s);
}
function decode(s) {
return config.raw ? s : decodeURIComponent(s);
}
function stringifyCookieValue(value) {
return encode(config.json ? JSON.stringify(value) : String(value));
}
function parseCookieValue(s) {
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}
try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, ' '));
return config.json ? JSON.parse(s) : s;
} catch(e) {}
}
function read(s, converter) {
var value = config.raw ? s : parseCookieValue(s);
return $.isFunction(converter) ? converter(value) : value;
}
var config = $.cookie = function (key, value, options) {
// Write
if (value !== undefined && !$.isFunction(value)) {
options = $.extend({}, config.defaults, options);
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setDate(t.getDate() + days);
}
return (document.cookie = [
encode(key), '=', stringifyCookieValue(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// Read
var result = key ? undefined : {};
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling $.cookie().
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0, l = cookies.length; i < l; i++) {
var parts = cookies[i].split('=');
var name = decode(parts.shift());
var cookie = parts.join('=');
if (key && key === name) {
// If second argument (value) is a function it's a converter...
result = read(cookie, value);
break;
}
// Prevent storing a cookie that we couldn't decode.
if (!key && (cookie = read(cookie)) !== undefined) {
result[name] = cookie;
}
}
return result;
};
config.defaults = {};
$.removeCookie = function (key, options) {
if ($.cookie(key) === undefined) {
return false;
}
// Must not alter options, thus extending a fresh object...
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
return !$.cookie(key);
};
}));

17
js/jquery.highlight.min.js vendored Normal file
View File

@ -0,0 +1,17 @@
/*
highlight v4
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>
*/
jQuery.fn.highlight=function(c){function e(b,c){var d=0;if(3==b.nodeType){var a=b.data.toUpperCase().indexOf(c);if(0<=a){d=document.createElement("span");d.className="highlight";a=b.splitText(a);a.splitText(c.length);var f=a.cloneNode(!0);d.appendChild(f);a.parentNode.replaceChild(d,a);d=1}}else if(1==b.nodeType&&b.childNodes&&!/(script|style)/i.test(b.tagName))for(a=0;a<b.childNodes.length;++a)a+=e(b.childNodes[a],c);return d}return this.length&&c&&c.length?this.each(function(){e(this,c.toUpperCase())}): this};jQuery.fn.removeHighlight=function(){return this.find("span.highlight").each(function(){this.parentNode.firstChild.nodeName;with(this.parentNode)replaceChild(this.firstChild,this),normalize()}).end()};

1
js/jquery.knob.min.js vendored Normal file

File diff suppressed because one or more lines are too long

193
js/jquery.timeago.js Normal file
View File

@ -0,0 +1,193 @@
/**
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
*
* @name timeago
* @version 1.3.0
* @requires jQuery v1.2.3+
* @author Ryan McGeary
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* For usage and examples, visit:
* http://timeago.yarp.com/
*
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
$.timeago = function(timestamp) {
if (timestamp instanceof Date) {
return inWords(timestamp);
} else if (typeof timestamp === "string") {
return inWords($.timeago.parse(timestamp));
} else if (typeof timestamp === "number") {
return inWords(new Date(timestamp));
} else {
return inWords($.timeago.datetime(timestamp));
}
};
var $t = $.timeago;
$.extend($.timeago, {
settings: {
refreshMillis: 60000,
allowFuture: false,
localeTitle: false,
cutoff: 0,
strings: {
prefixAgo: null,
prefixFromNow: null,
suffixAgo: "ago",
suffixFromNow: "from now",
seconds: "less than a minute",
minute: "about a minute",
minutes: "%d minutes",
hour: "about an hour",
hours: "about %d hours",
day: "a day",
days: "%d days",
month: "about a month",
months: "%d months",
year: "about a year",
years: "%d years",
wordSeparator: " ",
numbers: []
}
},
inWords: function(distanceMillis) {
var $l = this.settings.strings;
var prefix = $l.prefixAgo;
var suffix = $l.suffixAgo;
if (this.settings.allowFuture) {
if (distanceMillis < 0) {
prefix = $l.prefixFromNow;
suffix = $l.suffixFromNow;
}
}
var seconds = Math.abs(distanceMillis) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
var years = days / 365;
function substitute(stringOrFunction, number) {
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
var value = ($l.numbers && $l.numbers[number]) || number;
return string.replace(/%d/i, value);
}
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
seconds < 90 && substitute($l.minute, 1) ||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
minutes < 90 && substitute($l.hour, 1) ||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
hours < 42 && substitute($l.day, 1) ||
days < 30 && substitute($l.days, Math.round(days)) ||
days < 45 && substitute($l.month, 1) ||
days < 365 && substitute($l.months, Math.round(days / 30)) ||
years < 1.5 && substitute($l.year, 1) ||
substitute($l.years, Math.round(years));
var separator = $l.wordSeparator || "";
if ($l.wordSeparator === undefined) { separator = " "; }
return $.trim([prefix, words, suffix].join(separator));
},
parse: function(iso8601) {
var s = $.trim(iso8601);
s = s.replace(/\.\d+/,""); // remove milliseconds
s = s.replace(/-/,"/").replace(/-/,"/");
s = s.replace(/T/," ").replace(/Z/," UTC");
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
return new Date(s);
},
datetime: function(elem) {
var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
return $t.parse(iso8601);
},
isTime: function(elem) {
// jQuery's `is()` doesn't play well with HTML5 in IE
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
}
});
// functions that can be called via $(el).timeago('action')
// init is default when no action is given
// functions are called with context of a single element
var functions = {
init: function(){
var refresh_el = $.proxy(refresh, this);
refresh_el();
var $s = $t.settings;
if ($s.refreshMillis > 0) {
setInterval(refresh_el, $s.refreshMillis);
}
},
update: function(time){
$(this).data('timeago', { datetime: $t.parse(time) });
refresh.apply(this);
},
updateFromDOM: function(){
$(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) });
refresh.apply(this);
}
};
$.fn.timeago = function(action, options) {
var fn = action ? functions[action] : functions.init;
if(!fn){
throw new Error("Unknown function name '"+ action +"' for timeago");
}
// each over objects here and call the requested function
this.each(function(){
fn.call(this, options);
});
return this;
};
function refresh() {
var data = prepareData(this);
var $s = $t.settings;
if (!isNaN(data.datetime)) {
if ( $s.cutoff == 0 || distance(data.datetime) < $s.cutoff) {
$(this).text(inWords(data.datetime));
}
}
return this;
}
function prepareData(element) {
element = $(element);
if (!element.data("timeago")) {
element.data("timeago", { datetime: $t.datetime(element) });
var text = $.trim(element.text());
if ($t.settings.localeTitle) {
element.attr("title", element.data('timeago').datetime.toLocaleString());
} else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
element.attr("title", text);
}
}
return element.data("timeago");
}
function inWords(date) {
return $t.inWords(distance(date));
}
function distance(date) {
return (new Date().getTime() - date.getTime());
}
// fix for IE6 suckage
document.createElement("abbr");
document.createElement("time");
}));

4
js/modernizr.js Normal file

File diff suppressed because one or more lines are too long

9523
js/wysihtml5-0.3.0.js Normal file

File diff suppressed because it is too large Load Diff

1
license.txt Normal file
View File

@ -0,0 +1 @@
Please see file "protected/docs/license.md" for licensing details.

1
protected/.htaccess Normal file
View File

@ -0,0 +1 @@
deny from all

View File

@ -0,0 +1,44 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HActiveRecordBehavior is attached to all active records.
*
* @package humhub.behaviors
* @since 0.5
*/
class HActiveRecordBehavior extends CActiveRecordBehavior {
/**
* On after construct event of an active record
*
* @param type $event
*/
public function afterConstruct($event) {
// Intercept this controller
Yii::app()->interceptor->intercept($this);
parent::afterConstruct($event);
}
}
?>

View File

@ -0,0 +1,187 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HContentAddonBehavior should attached to every content addon model
*
* Items like Comments, Likes with linked to a
* HContentBehavior or HContentAddonBehavior
* Model
*
* An ContentAddon needs to have following DB Fields
* - id
* - object_model
* - object_id
*
* Which should point to SIContent or SIContentAddon
*
* @package humhub.behaviors
* @since 0.5
*/
class HContentAddonBehavior extends HActiveRecordBehavior {
/**
* Cache Content Ooject and avoid multiple loading
*
* @var type
*/
private $_cacheContentObject = null;
/**
* Returns an object which this Addon belongs to
* Only Support Content -> ContentAddon -> ContentAddon
*
* This is always a object which have the behavior: HContentBehavior
*
* e.g. Post / Like
*
*/
public function getContentObject() {
// Fastlane?
if ($this->_cacheContentObject != null)
return $this->_cacheContentObject;
$target = $this->getOwner()->getUnderlyingObject();
if ($target->asa('HContentBehavior') !== null) {
$this->_cacheContentObject = $target;
return $target;
} elseif ($target->asa('HContentAddonBehavior') !== null) {
$target2 = $target->getOwner()->getUnderlyingObject();
if ($target2->asa('HContentBehavior') !== null) {
$this->_cacheContentObject = $target2;
return $target2;
}
# Maybe Multiple Nested?
}
throw new CHttpException(500, Yii::t('base', 'Invalid content object!'));
}
/**
* Checks if the given / or current user can delete this content.
* Currently only the creator can remove.
*
* @param type $userId
*/
public function canDelete($userId = "") {
if ($userId == "")
$userId = Yii::app()->user->id;
if ($this->getOwner()->created_by == $userId)
return true;
return false;
}
/**
* Deligate to the underlying content object
*
* @param type $userId
* @return type
*/
public function canRead($userId = "") {
return $this->getContentObject()->canRead($userId);
}
/**
* Checks if this content can be changed
*
* @param type $userId
* @return type
*/
public function canWrite($userId = "") {
if ($userId == "")
$userId = Yii::app()->user->id;
if ($this->getOwner()->created_by == $userId)
return true;
return false;
}
/**
* Returns textual title for this content addon
*
* @return type
*/
public function getContentTitle() {
$objectModel = get_class($this->getOwner()); // e.g. Post
return $objectModel . " (" . $this->getOwner()->id . ")";
}
/**
* Before saving, check target on content addon
*/
public function beforeSave($event) {
if ($this->getOwner()->getUnderlyingObject() == null)
throw new CHttpException(500, 'Could not load comment target!');
return true;
}
/**
* After saving
*/
public function afterSave($event) {
// Also load corresponding SIContent Object and change "updated_at & updated_by" time
$this->getContentObject()->save();
}
/**
* After delete
*/
public function afterDelete($event) {
// Also load corresponding SIContent Object and change "updated_at & updated_by" time
$this->getContentObject()->save();
}
/**
* Before deleting a SIContent try to delete all corresponding SIContentAddons.
*/
public function beforeDelete($event) {
$objectModel = get_class($this->getOwner()); // e.g. Comment
// delete all comments (sub comments?) - not implemented yet :-)
$comments = Comment::model()->findAllByAttributes(array('object_model' => $objectModel, 'object_id' => $this->getOwner()->id));
foreach ($comments as $comment) {
$comment->delete();
}
// delete all likes
$likes = Like::model()->findAllByAttributes(array('object_model' => $objectModel, 'object_id' => $this->getOwner()->id));
foreach ($likes as $like) {
$like->delete();
}
// delete all activities
$activities = Activity::model()->findAllByAttributes(array('object_model' => $objectModel, 'object_id' => $this->getOwner()->id));
foreach ($activities as $activity) {
$activity->delete();
}
}
}
?>

View File

@ -0,0 +1,57 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* The SIContentBaseBahaviour is attached to all models which act as contentbase.
*
* A ContentBase can be Space or User. Essentially a ContentBase holds a
* bunch of Content Objects.
*
* Each ContentBase should own a Wall Object.
* A Content Base needs a GUID Database Field
*
* Additionally each ContentBase has a ProfileImage.
*
* Ideas/ToDo:
* - GetUrl (Instead of Profile Url)
*
* @package humhub.behaviors
* @since 0.5
*/
class HContentBaseBehavior extends HActiveRecordBehavior {
// Auto Add Wall?
// Auto Delete Wall?
/**
* Returns the Profile Image Object for this Content Base
*
* @return ProfileImage
*/
public function getProfileImage() {
if (get_class($this->getOwner()) == 'Space') {
return new ProfileImage($this->getOwner()->guid, 'default_workspace');
}
return new ProfileImage($this->getOwner()->guid);
}
}
?>

View File

@ -0,0 +1,141 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* Behavior for Contents Objects
*
* Generally binds a Content Object to the given ActiveRecord
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.behaviors
* @since 0.5
*/
class HContentBehavior extends HActiveRecordBehavior {
private $_content = null;
/**
* Before deleting of a content object (e.g. post, activity, ...)
*
* @param type $event
*/
public function beforeDelete($event) {
parent::beforeDelete($event);
// Make sure corresponding content object is loaded
// So we can delete is afterwards
$this->getContentMeta();
}
/**
* After deleting of a content object (e.g. post, activity, ...)
*
* @param type $event
*/
public function afterDelete($event) {
parent::afterDelete($event);
// Search Stuff
if ($this->getOwner() instanceof ISearchable) {
if (!$this->getOwner()->isNewRecord)
HSearch::getInstance()->deleteModel($this->getOwner());
HSearch::getInstance()->addModel($this->getOwner());
}
$this->getContentMeta()->delete();
}
/**
* After saving of a content object (e.g. post, activity, ...)
*
* @param type $event
*/
public function afterSave($event) {
parent::afterSave($event);
if ($this->getContentMeta()->isNewRecord) {
$this->getContentMeta()->object_model = get_class($this->getOwner());
$this->getContentMeta()->object_id = $this->getOwner()->id;
// Because Content Model dont set this automatically atm
// For update reasons
// On later release remove this, and change Content Model to set this automatically
$this->getContentMeta()->created_at = $this->getOwner()->created_at;
$this->getContentMeta()->created_by = $this->getOwner()->created_by;
$this->getContentMeta()->updated_at = $this->getOwner()->updated_at;
$this->getContentMeta()->updated_by = $this->getOwner()->updated_by;
}
$this->getContentMeta()->save();
return true;
}
/**
* After finding a record
*
* @param type $event
*/
public function afterFind($event) {
parent::afterFind($event);
// Make sure corresponding content object is empty
$this->_content = null;
}
/**
* Returns corresponding Content (Meta) Object for underlying content class.
*
* ToDo: After Find Remove Existing ContentMeta Object
* @return type
*/
public function getContentMeta() {
// Content Object already instanciated
if ($this->_content != null)
return $this->_content;
// Is new record, so return empty content object
if ($this->getOwner()->isNewRecord) {
$this->_content = new Content;
// some defaults
$this->_content->sticked = 0;
$this->_content->archived = 0;
$this->_content->visibility = Content::VISIBILITY_PRIVATE;
return $this->_content;
}
$this->_content = Content::model()->findByAttributes(array('object_model' => get_class($this->getOwner()), 'object_id' => $this->getOwner()->id));
if ($this->_content == null) {
throw new CHttpException(500, Yii::t('base', 'Missing underlying content object!'));
}
return $this->_content;
}
}
?>

View File

@ -0,0 +1,98 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* A SIUnderlyingObjectBahavior adds the ability to models/active records
* to link to any other model/active record.
*
* This is archived by the database fields object_model & object_id.
*
* Required database fields:
* - object_model
* - object_id
*
* @package humhub.behaviors
* @since 0.5
*/
class HUnderlyingObjectBehavior extends HActiveRecordBehavior {
/**
* The underlying object needs to be a "instanceof" at least one
* of this values.
*
* (Its also possible to specify a CBehavior name)
*
* @var type
*/
public $mustBeInstanceOf = array();
/**
* Cache Object to avoid multiple loading
*
* @var type
*/
private $_cachedObject = null;
/**
* Cache Object is null
*/
private $_cached = false;
/*
* Returns the Underlying Object
*
* @return mixed
*/
public function getUnderlyingObject() {
if ($this->_cached)
return $this->_cachedObject;
$className = $this->getOwner()->object_model;
if ($className == "") {
$this->_cached = true;
return null;
}
$object = $className::model()->findByPk($this->getOwner()->object_id);
if (count($this->mustBeInstanceOf) == 0 || $object == null) {
$this->_cached = true;
$this->_cachedObject = $object;
return $object;
}
// Validates object
foreach ($this->mustBeInstanceOf as $instance) {
if ($object instanceof $instance || $object->asa($instance) !== null) {
$this->_cached = true;
$this->_cachedObject = $object;
return $object;
}
}
throw new CHttpException(500, 'Underlying object of invalid type! (' . $className . ')');
}
}
?>

View File

@ -0,0 +1,212 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* The E-Mailing command sends daily or hourly e-mails updates with current
* pending activities and notification.
*
* @package humhub.commands.shell.EMailing
* @since 0.5
*/
class EMailing extends HConsoleCommand {
private $mode = "hourly"; // daily
/**
* Run method for EMailing System
*
* @param type $args
*/
public function run($args) {
$this->printHeader('E-Mail Interface');
if (!isset($args[0]) || ($args[0] != "daily" && $args[0] != 'hourly')) {
print "\n Run with parameter:\n" .
"\t daily - for Daily Mailings\n" .
"\t hourly - for Hourly Mailings\n";
print "\n\n";
exit;
}
$this->mode = $args[0];
Yii::import("application.modules_core.wall.*", true);
Yii::app()->request->setBaseUrl(HSetting::Get('baseUrl'));
$users = User::model()->with('httpSessions')->findAll();
foreach ($users as $user) {
print "Processing : " . $user->email . ": ";
$user->checkWall();
$notificationContent = $this->getNotificationContent($user);
$activityContent = $this->getActivityContent($user);
// Something new?
if ($notificationContent == "" && $activityContent == "") {
print "Nothing new! \n";
continue;
}
$message = new HMailMessage();
$message->view = 'application.views.mail.EMailing';
$message->addFrom(HSetting::Get('systemEmailAddress', 'mailing'), HSetting::Get('systemEmailName', 'mailing'));
$message->addTo($user->email);
if ($this->mode == 'hourly') {
$message->subject = Yii::t('base', "Latest news");
} else {
$message->subject = Yii::t('base', "Your daily summary");
}
$message->setBody(array(
'notificationContent' => $notificationContent,
'activityContent' => $activityContent,
'user' => $user,
), 'text/html');
Yii::app()->mail->send($message);
print "Sent! \n";
}
print "\nEMailing completed.\n";
}
/**
* Returns notification content by given user.
*
* The output will generated on current mode.
*
* @param type $user
* @return string email output
*/
private function getNotificationContent($user) {
// Never receive notifications
if ($user->receive_email_notifications == User::RECEIVE_EMAIL_NEVER) {
return "";
}
// We are in hourly mode and user wants daily
if ($this->mode == 'hourly' && $user->receive_email_notifications == User::RECEIVE_EMAIL_DAILY_SUMMARY) {
return "";
}
// We are in daily mode and user dont wants daily reports
if ($this->mode == 'daily' && $user->receive_email_notifications != User::RECEIVE_EMAIL_DAILY_SUMMARY) {
return "";
}
// User wants only when offline and is online
if ($this->mode == 'hourly') {
$isOnline = (count($user->httpSessions) > 0);
if ($user->receive_email_notifications == User::RECEIVE_EMAIL_WHEN_OFFLINE && $isOnline) {
return "";
}
}
// Get not seen notifcation, order by created_at
$criteria = new CDbCriteria();
$criteria->order = 'created_at DESC';
$notifications = Notification::model()->findAllByAttributes(array('user_id' => $user->id, 'seen' => 0, 'emailed' => 0), $criteria);
// Nothin new
if (count($notifications) == 0) {
return "";
}
// Generate notification output
$output = "";
foreach ($notifications as $notification) {
$output .= $notification->getMailOut();
$notification->emailed = 1;
$notification->save();
}
return $output;
}
/**
* Return activity content by given user.
*
* This output is generated by current mode.
*
* @param type $user
* @return string
*/
private function getActivityContent($user) {
// User never wants activity content
if ($user->receive_email_activities == User::RECEIVE_EMAIL_NEVER) {
return "";
}
// We are in hourly mode and user wants receive a daily summary
if ($this->mode == 'hourly' && $user->receive_email_activities == User::RECEIVE_EMAIL_DAILY_SUMMARY) {
return "";
}
// We are in daily mode and user wants receive not daily
if ($this->mode == 'daily' && $user->receive_email_activities != User::RECEIVE_EMAIL_DAILY_SUMMARY) {
return "";
}
// User is online and want only receive when offline
if ($this->mode == 'hourly') {
$isOnline = (count($user->httpSessions) > 0);
if ($user->receive_email_activities == User::RECEIVE_EMAIL_WHEN_OFFLINE && $isOnline) {
return "";
}
}
$lastMailDate = $user->last_activity_email;
if ($lastMailDate == "" || $lastMailDate == "0000-00-00 00:00:00") {
$lastMailDate = new CDbExpression('NOW() - INTERVAL 24 HOUR');
}
// Get Stream contents
$action = new StreamAction(null, 'console');
$action->mode = 'activity';
$action->type = 'dashboard';
$action->userId = $user->id;
$action->userWallId = $user->wall_id;
$action->wallEntryLimit = 50;
$action->wallEntryDateTo = $lastMailDate;
$activities = $action->runConsole();
# Save last run
$user->last_activity_email = new CDbExpression('NOW()');
$user->save();
// Nothin new
if ($activities['counter'] == 0) {
return "";
}
// Return Output
return $activities['output'];
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* The TestMail command is used to test the e-mail subsystem.
*
* @package humhub.commands.shell.EMailing
* @since 0.5
*/
class TestMail extends HConsoleCommand {
public function run($args) {
print " E-Mail - Test Interface\n";
print "-------------------------------------------------------------------------\n\n";
if (!isset($args[0]) || ($args[0] == "")) {
print "\n Run with parameter [email]!\n" .
print "\n\n";
exit;
}
$email = $args[0];
$user = User::model()->findByPk(1);
$message = new HMailMessage();
$message->view = 'application.views.mail.EMailing';
$message->addFrom(HSetting::Get('systemEmailAddress', 'mailing'), HSetting::Get('systemEmailName', 'mailing'));
$message->addTo($email);
$message->subject = "Test Mail";
$message->setBody(array('user' => $user), 'text/html');
Yii::app()->mail->send($message);
print "Sent! \n";
print "\nEMailing completed.\n";
}
}

View File

@ -0,0 +1,95 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* IntegrityChecker command validates the current database and tries to fix
* currupted records.
*
* Also third party modules can add checking methods by intercepting the run
* event.
*
* @package humhub.commands.shell.Maintain
* @since 0.5
*/
class IntegrityChecker extends HConsoleCommand {
public $simulate = false;
/**
* Runs Integrity Checker
*
* @param type $args
*/
public function run($args) {
$this->printHeader('Integrity Checker');
if ($this->simulate) {
print "Simulation Mode!\n\n";
}
$this->doBaseTasks();
if ($this->hasEventHandler('onRun'))
$this->onRun(new CEvent($this));
print "\n\n";
print "Finished! Integrity Check done!\n\n";
}
/**
* Do general tasks used application whide
*/
protected function doBaseTasks() {
$this->showTestHeadline("Checking application base structure");
if (HSetting::Get('secret') == "" || HSetting::Get('secret') == null) {
HSetting::Set('secret', UUID::v4());
$this->showFix('Setting missing application secret!');
}
}
/**
* onRun Event is used to notify modules.
*
* @param type $event
*/
public function onRun($event) {
$this->raiseEvent('onRun', $event);
}
/**
* Shows a headline in console
* @param type $title
*/
public function showTestHeadline($title) {
print "*** " . $title . "\n";
}
/**
* Use this method to show a fix
* @param type $msg
*/
public function showFix($msg) {
print "\t" . $msg . "\n";
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* Optimize command optimizing the search index by calling underlying
* Zend Lucence Index optimizer.
*
* @package humhub.commands.shell.SearchIndexer
* @since 0.5
*/
class Optimize extends HConsoleCommand {
public function run($args) {
$this->printHeader('Search Index Optimizer');
print "- Optimizing ...\n";
HSearch::getInstance()->optimize();
print "- Search Index successfully optimized!\n";
print "\n";
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* Rebuilder command purges all search index files and rebuilds the whole index.
*
* @package humhub.commands.shell.SearchIndexer
* @since 0.5
*/
class Rebuilder extends HConsoleCommand {
public function run($args) {
$this->printHeader('Rebuild Search Index\n');
print "Deleting old index files: ";
HSearch::getInstance()->flushIndex();
print " done!\n";
print "Rebuilding index: ";
HSearch::getInstance()->rebuild();
print " done!\n";
print "\n";
}
}

View File

@ -0,0 +1,120 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* ZCronRunner command is a generic cron interface.
*
* Third party modules can intercept run events to attach methods to the cron
* subsystem.
*
* @package humhub.commands.shell.ZCron
* @since 0.5
*/
class ZCronRunner extends HConsoleCommand {
/**
* Cron Intervals
*/
const INTERVAL_DAILY = 1;
const INTERVAL_HOURLY = 2;
/**
* @var integer current interval
*/
public $interval = null;
/**
* Run method for CronRunner
*
* @param type $args
*/
public function run($args) {
$this->printHeader('Cron Interface');
if (!isset($args[0]) || ($args[0] != "daily" && $args[0] != 'hourly')) {
print "\n Run with parameter:\n" .
"\t daily - for Daily Interval\n" .
"\t hourly - for Hourly Interval \n";
print "\n\n";
exit;
}
// Set current interval to attribute
if ($args[0] == 'daily')
$this->interval = self::INTERVAL_DAILY;
elseif ($args[0] == 'hourly')
$this->interval = self::INTERVAL_HOURLY;
else
throw new CException(500, 'Invalid cron interval!');
// Do some base tasks, handle by event in future
if ($this->interval == self::INTERVAL_HOURLY) {
// Raise Event for Module specific tasks
if ($this->hasEventHandler('onHourlyRun'))
$this->onHourlyRun(new CEvent($this));
print "- Optimizing Search Index\n";
// Optimize Search Index
HSearch::getInstance()->Optimize();
print "- Invoking EMailing hourly\n\n";
// Execute Hourly Mailing Runner
Yii::import('application.commands.shell.EMailing.*');
$command = new EMailing('test', 'test');
$command->run(array('hourly'));
HSetting::Set('cronLastHourlyRun', time());
} elseif ($this->interval == self::INTERVAL_DAILY) {
// Raise Event for Module specific tasks
if ($this->hasEventHandler('onDailyRun'))
$this->onDailyRun(new CEvent($this));
// Execute Daily Mailing Runner
print "- Invoking EMailing daily\n\n";
Yii::import('application.commands.shell.EMailing.*');
$command = new EMailing('test', 'test');
$command->run(array('daily'));
HSetting::Set('cronLastDailyRun', time());
}
}
/**
* This event is raised after the cron hourly run is performed.
*
* @param CEvent $event the event parameter
*/
public function onHourlyRun($event) {
$this->raiseEvent('onHourlyRun', $event);
}
/**
* This event is raised after the cron hourly run is performed.
*
* @param CEvent $event the event parameter
*/
public function onDailyRun($event) {
$this->raiseEvent('onDailyRun', $event);
}
}

View File

@ -0,0 +1,91 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* ZDbMigration extends EDbMigration with better interactive support.
*
* @package humhub.commands
* @since 0.5
*/
class ZDbMigration extends CDbMigration {
/**
* @var EMigrateCommand
*/
private $migrateCommand;
protected $interactive = true;
/**
* @param EMigrateCommand $migrateCommand
*/
public function setCommand($migrateCommand) {
$this->migrateCommand = $migrateCommand;
$this->interactive = $migrateCommand->interactive;
}
/**
* @see CConsoleCommand::confirm()
* @param string $message
* @return bool
*/
public function confirm($message) {
if (!$this->interactive) {
return true;
}
return $this->migrateCommand->confirm($message);
}
/**
* @see CConsoleCommand::prompt()
* @param string $message
* @param mixed $defaultValue will be returned when interactive is false
* @return string
*/
public function prompt($message, $defaultValue) {
if (!$this->interactive) {
return $defaultValue;
}
return $this->migrateCommand->prompt($message);
}
/**
* Executes a SQL statement. Silently. (only show sql on exception)
* This method executes the specified SQL statement using {@link dbConnection}.
* @param string $sql the SQL statement to be executed
* @param array $params input parameters (name=>value) for the SQL execution. See {@link CDbCommand::execute} for more details.
* @param boolean $verbose
*/
public function execute($sql, $params = array(), $verbose = true) {
if ($verbose) {
parent::execute($sql, $params);
} else {
try {
echo " > execute SQL ...";
$time = microtime(true);
$this->getDbConnection()->createCommand($sql)->execute($params);
echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n";
} catch (CException $e) {
echo " failed.\n\n";
throw $e;
}
}
}
}

View File

@ -0,0 +1,149 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
Yii::import('application.vendors.yii.cli.commands.shell.*');
/**
* ZMessageCommand extends Yiis MessageCommand with better module support.
*
* - Also add module messages into module/messages dir.
*
* @package humhub.commands
* @since 0.5
*/
class ZMessageCommand extends MessageCommand {
/**
* Execute the action.
* @param array command line parameters specific for this command
*/
public function run($args) {
if (!isset($args[0]))
$this->usageError('the configuration file is not specified.');
if (!is_file($args[0]))
$this->usageError("the configuration file {$args[0]} does not exist.");
$config = require_once($args[0]);
$translator = 'Yii::t';
extract($config);
if (!isset($sourcePath, $messagePath, $languages))
$this->usageError('The configuration file must specify "sourcePath", "messagePath" and "languages".');
if (!is_dir($sourcePath))
$this->usageError("The source path $sourcePath is not a valid directory.");
if (!is_dir($messagePath))
$this->usageError("The message path $messagePath is not a valid directory.");
if (empty($languages))
$this->usageError("Languages cannot be empty.");
if (!isset($overwrite))
$overwrite = false;
if (!isset($removeOld))
$removeOld = false;
if (!isset($sort))
$sort = false;
$options = array();
if (isset($fileTypes))
$options['fileTypes'] = $fileTypes;
if (isset($exclude))
$options['exclude'] = $exclude;
$files = CFileHelper::findFiles(realpath($sourcePath), $options);
$messages = array();
foreach ($files as $file)
$messages = array_merge_recursive($messages, $this->extractMessages($file, $translator));
foreach ($messages as $category => $msgs) {
$dir = "";
if (($pos = strpos($category, '.')) !== false) {
$parts = explode(".", $category);
$className = $parts[0];
if (!$this->isModuleClassDefined($className)) {
print "Skip not enabled module: " . $className . "\n";
continue;
}
// Get base Path of Module
$class = new ReflectionClass($className);
$dir = dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'messages' . DIRECTORY_SEPARATOR;
$category = $parts[1];
} else {
$dir = $messagePath . DIRECTORY_SEPARATOR;
}
// Skip when there is no message dir
if (!is_dir($dir)) {
continue;
}
foreach ($languages as $language) {
$messageDir = $dir . DIRECTORY_SEPARATOR . $language;
if (!is_dir($messageDir))
@mkdir($messageDir);
$msgs = array_values(array_unique($msgs));
$this->generateMessageFile($msgs, $messageDir . DIRECTORY_SEPARATOR . $category . '.php', $overwrite, $removeOld, $sort);
}
}
}
protected function extractMessages($fileName, $translator) {
echo "Extracting messages from $fileName...\n";
$subject = file_get_contents($fileName);
$messages = array();
if (!is_array($translator))
$translator = array($translator);
foreach ($translator as $currentTranslator) {
$n = preg_match_all('/\b' . $currentTranslator . '\s*\(\s*(\'[\w.]*?(?<!\.)\'|"[\w.]*?(?<!\.)")\s*,\s*(\'.*?(?<!\\\\)\'|".*?(?<!\\\\)")\s*[,\)]/s', $subject, $matches, PREG_SET_ORDER);
for ($i = 0; $i < $n; ++$i) {
$category = substr($matches[$i][1], 1, -1);
$message = $matches[$i][2];
$messages[$category][] = eval("return $message;"); // use eval to eliminate quote escape
}
}
return $messages;
}
/**
* Checks if given module is registered to the yii application.
* This is needed to prevent class autoload errrors when module/class is not enabled.
*
* @param type $className
* @return boolean
*/
public function isModuleClassDefined($className) {
foreach (Yii::app()->modules as $mod) {
if (strpos($mod['class'], $className) !== false) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,94 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ZDbMigration.php');
Yii::import('application.extensions.migrate-command.EMigrateCommand');
/**
* ZMigrateCommand extends EMigrateCommand with better interactive support.
*
* @package humhub.commands
* @since 0.5
*/
class ZMigrateCommand extends EMigrateCommand {
public $migrationTable = 'migration';
public static function AutoMigrate() {
/** $commandPath = Yii::app()->getBasePath() . DIRECTORY_SEPARATOR . 'commands';
$runner->addCommands($commandPath);
$commandPath = Yii::getFrameworkPath() . DIRECTORY_SEPARATOR . 'cli' . DIRECTORY_SEPARATOR . 'commands';
$runner->addCommands($commandPath); */
$runner = new CConsoleCommandRunner();
$runner->commands = array(
'migrate' => array(
'class' => 'applications.commands.shell.ZMigrateCommand',
'interactive' => false,
),
);
$args = array('yiic', 'migrate', '--interactive=0');
ob_start();
$runner->run($args);
return htmlentities(ob_get_clean(), null, Yii::app()->charset);
}
public function init() {
print "Autodetecting Modules....\n";
$modulePaths = array();
foreach (Yii::app()->moduleManager->getRegisteredModules() as $moduleId => $moduleInfo) {
// Convert path.to.example.ExampleModule to path.to.example.migrations
$path = explode(".", $moduleInfo['class']);
array_pop($path);
$path[] = $this->migrationSubPath;
$migrationPath = implode(".", $path);
if (is_dir(Yii::getPathOfAlias($migrationPath))) {
$modulePaths[$moduleId] = $migrationPath;
}
}
$this->modulePaths = $modulePaths;
}
protected function instantiateMigration($class) {
$migration = new $class;
$migration->setDbConnection($this->getDbConnection());
if ($migration instanceof EDbMigration) {
/** @var EDbMigration $migration */
$migration->setCommand($this);
}
return $migration;
}
protected function getTemplate() {
if ($this->templateFile !== null) {
return parent::getTemplate();
} else {
return str_replace('CDbMigration', 'ZDbMigration', parent::getTemplate());
}
}
}

View File

@ -0,0 +1,170 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* Controller is the customized base controller class.
* All controller classes for this application should extend from this base class.
*
* @package humhub.components
* @since 0.5
*/
class Controller extends CController {
/**
* @var string the default layout for the controller view. Defaults to '//layouts/column1',
* meaning using a single column layout. See 'protected/views/layouts/column1.php'.
*/
public $layout = '//layouts/main';
/**
* @var string the sub layout for the controller view. Defaults to '',
*/
public $subLayout = '';
/**
* @var array context menu items. This property will be assigned to {@link CMenu::items}.
*/
public $menu = array();
/**
* @var array the breadcrumbs of the current page. The value of this property will
* be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
* for more details on how to specify this property.
*/
public $breadcrumbs = array();
public $snippets = array();
/**
* Minimum required database version (HSetting)
*
* @var type
*/
#protected $requiredDbVersion = 28;
/**
* Inits the controller class.
*
* - Force Installer when not HumHub is not installed yet.
* - Registers Event Interceptor
* - Loads Basic HSetting
* - Set Language
* - Check Database Version
*/
public function init() {
Yii::app()->interceptor->intercept($this);
// Force installer, when not installed
if (!Yii::app()->params['installed']) {
if ($this->getModule() != null && $this->getModule()->id == "installer") {
return parent::init();
}
$this->redirect(array('//installer/index'));
}
// Switch to correct user language
if (Yii::app()->user->language) {
Yii::app()->language = Yii::app()->user->language;
}
// Enable Jquery Globally
Yii::app()->clientScript->registerCoreScript('jquery');
// Tweaks for Ajax Requests
Yii::app()->user->loginRequiredAjaxResponse = "<script>window.location.href = '" . Yii::app()->user->id . "';</script>";
if (Yii::app()->request->isAjaxRequest) {
Yii::app()->clientScript->scriptMap = array(
'jquery.js' => false,
);
}
// Set a javascript variable which holds the Name and the Value of the CSRF Variable.
Yii::app()->clientScript->setJavascriptVariable('csrfName', Yii::app()->request->csrfTokenName);
Yii::app()->clientScript->setJavascriptVariable('csrfValue', Yii::app()->request->csrfToken);
Yii::app()->clientScript->setJavascriptVariable('baseUrl', Yii::app()->getBaseUrl(true));
return parent::init();
}
/**
* Create Redirect for AJAX Requests which output goes into HTML content.
* Is an alternative method to redirect, for ajax responses.
*/
public function htmlRedirect($url = "") {
echo "<script>\n";
// If current URL == New Url (absolute || relative) then only Refresh
echo "if (window.location.pathname+window.location.search+window.location.hash == '" . $url . "' || '" . $url . "' == window.location.href) { \n";
//echo "window.location.reload();\n"; // Drops warning on Posts
// Remove test.php#xy (#xy) part
$temp = explode("#", $url);
$url = $temp[0];
echo "if (window.location.search == '') {\n";
echo "window.location.href = '" . $url . "?c=" . time() . "';\n";
echo "} else { \n";
echo "window.location.href = '" . $url . "&c=" . time() . "';\n";
echo "} \n";
// When completly new url, set new window location
echo "} else { \n";
echo "window.location.href = '" . $url . "';\n";
echo "} \n";
echo "</script>\n";
Yii::app()->end();
}
/**
* Outputs a given JSON Array and ends the application
*
* @param type $json
*/
protected function renderJson($json) {
echo CJSON::encode($json);
Yii::app()->end();
return;
}
/**
* Ensures the current request is a post, when not throw an error
*/
public function forcePostRequest() {
if (!Yii::app()->request->isPostRequest) {
throw new CHttpException(500, Yii::t('base', 'Invalid request.'));
}
return true;
}
/**
* Closes a modal
*/
public function renderModalClose() {
// close modal to hide the loaded view, which is visible for some seconds, after creation
echo "<script>";
echo "$('#globalModal').modal('hide')";
echo "</script>";
//Yii::app()->end();
}
}

View File

@ -0,0 +1,116 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HActiveRecord is an extended version of the CActiveRecord.
*
* Each HActiveRecord has some extra meta database fields like:
* - created by
* - created_at
* - updated_by
* - updated_at
*
* The underlying HActiveRecord table must have these fields.
*
* @package humhub.components
* @since 0.5
*/
abstract class HActiveRecord extends CActiveRecord {
// Avoid Errors when fields not exists
public $created_at;
public $created_by;
public $updated_at;
public $updated_by;
/**
* Inits the active records and registers the event interceptor
*/
public function init() {
parent::init();
// Intercept this controller
Yii::app()->interceptor->intercept($this);
}
/**
* Prepares create_time, create_user_id, update_time and update_user_id attributes before performing validation.
*/
protected function beforeValidate() {
// Check if we got an user object
if (isset(Yii::app()->user)) {
$userId = Yii::app()->user->id;
} else {
$userId = 0;
}
if ($this->isNewRecord) {
// set the create date, last updated date and the user doing the creating
$this->created_at = $this->created_at = new CDbExpression('NOW()');
if ($this->created_by == "")
$this->created_by = $userId;
}
// Dont update in this scenario (UserSpaceMembership, only changed column is "last_visit")
if ($this->scenario != 'last_visit' && $userId != 0) {
//not a new record, so just set the last updated time and last updated user id
$this->updated_at = new CDbExpression('NOW()');
if ($this->updated_by == "")
$this->updated_by = $userId;
}
return parent::beforeValidate();
}
/**
* Returns the creator user of this active record
* (Faster than relation() because cached).
*
* @return User
*/
public function getCreator() {
return User::model()->findByPk($this->created_by);
}
/**
* Returns the updater user of this active record
* (Faster than relation() because cached).
*
* @return User
*/
public function getUpdater() {
return User::model()->findByPk($this->updated_by);
}
/**
* Returns a unique id for this record
*
* @return String Unique Id of this record
*/
public function getUniqueId() {
return get_class($this) . "_" . $this->id;
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HActiveRecordContent is the base activerecord for content objects.
*
* Each model which represents a content should derived from it.
* (e.g. Post, Question, Task, Note, ...)
*
* It automatically adds the HContentBehavior which binds a 'contentMeta'
* attribute, that always points to a Content Model Record.
* (See SiContentBavior for more details.)
*
* The Content Model is responsible for
* - Content to User/Space Binding
* - Access Controlling
* - Wall Integration
* - ...
* (See Content Model for more details.)
*
* Cleanup:
* On workspace or user deletion, this objects will automatically deleted.
*
* Note: Comments, Likes or Files are NOT Content Objects. These objects are
* ContentAddons (HActiveRecordContentAddon) which always belongs to one
* Content Object.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HActiveRecordContent extends HActiveRecord {
/**
* Extended Constructor which automatically attaches
* the HContentBehavior to the objects.
*
* @param type $scenario
*/
public function __construct($scenario = 'insert') {
parent::__construct($scenario);
$this->attachBehavior('HContentBehavior', array(
'class' => 'application.behaviors.HContentBehavior'
));
}
/**
* Returns a short textual title for this content.
* Default goes to "Classname (Id)"
*
* It should be overwritten for a more representative text.
*
* @return type
*/
public function getContentTitle() {
$objectModel = get_class($this); // e.g. Post
return $objectModel . " (" . $this->getOwner()->id . ")";
}
/**
* If the content should also displayed on a wall, overwrite this
* method and produce a wall output.
*
* e.g.
* return Yii::app()->getController()->widget('application.modules.myModule.MyContentWidget',
* array('myContent' => $this),
* true
* );
*
* @return type
*/
public function getWallOut() {
return "Default Wall Output for Class " . get_class($this->getOwner());
}
}
?>

View File

@ -0,0 +1,34 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HActiveRecordContentAddon is the base active record for content addons.
*
* Content addons are content types as example Likes, Comments or Files.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HActiveRecordContentAddon extends HActiveRecord {
}
?>

View File

@ -0,0 +1,69 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HAjaxLinkPager extends the CLinkPager with some ajax functions.
*
* @package humhub.components
* @since 0.5
*/
class HAjaxLinkPager extends CLinkPager {
/**
* @var String html dom id of target
*/
public $ajaxContentTarget = "SomeCoolDivId";
/**
* @var ind counter
*/
protected $ajaxIdCounter = 0;
/**
* Creates a page button.
*
* You may override this method to customize the page buttons.
* @param string $label the text label for the button
* @param integer $page the page number
* @param string $class the CSS class for the page button. This could be 'page', 'first', 'last', 'next' or 'previous'.
* @param boolean $hidden whether this page button is visible
* @param boolean $selected whether this page button is selected
*
* @return string the generated button
*/
protected function createPageButton($label, $page, $class, $hidden, $selected) {
$this->ajaxIdCounter++; // For Unique Ajax Link IDs
if ($hidden || $selected)
$class.=' ' . ($hidden ? self::CSS_HIDDEN_PAGE : self::CSS_SELECTED_PAGE);
$ajaxLink = HHtml::ajaxLink(
$label, $this->createPageUrl($page), array(
'success' => "function(html) { jQuery('" . $this->ajaxContentTarget . "').replaceWith(html); }",
), array(
'id' => "siPaginatorLink_" . $page . "_" . $this->ajaxIdCounter,
)
);
return '<li class="' . $class . '">' . $ajaxLink . '</li>';
}
}

View File

@ -0,0 +1,129 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HClientScript extends the CClientScript
*
* @package humhub.components
* @since 0.5
*/
class HClientScript extends CClientScript {
/**
* @var array the registered HTML code blocks (key => code)
*/
public $htmls = array();
/**
* Method to inject a javascript variable
*
* @param String $name
* @param String $value
*/
public function setJavascriptVariable($name, $value) {
$jsCode = "var " . $name . " = '" . $value . "';\n";
$this->registerScript('jsVar_' . $name, $jsCode, CClientScript::POS_BEGIN);
}
/**
* Registers a script file
*
* @param String $src
* @param String $position
*/
public function registerScriptFile($src, $position = NULL) {
# if(Yii::app()->getRequest()->getIsAjaxRequest()) {
# Yii::app()->clientScript->registerScript('loadScript_'.$src, "loadJavaScript(\"".$src."\");", CClientScript::POS_BEGIN);
# } else {
return parent::registerScriptFile($src, $position);
# }
#registerScriptFile
}
/**
* Registers a piece of html code.
* @param string $id ID that uniquely identifies this piece of HTML code
* @param string $html the html code
*
* @return CClientScript the CClientScript object itself (to support method chaining, available since version 1.1.5).
*/
public function registerHtml($id, $html) {
$this->hasScripts = true;
$this->htmls[$id] = $html;
$params = func_get_args();
$this->recordCachingAction('clientScript', 'registerScript', $params);
return $this;
}
/**
* Inserts the scripts and other html snippets at the end of the body section.
*
* @param string $output the output to be inserted with scripts.
*/
public function renderBodyEnd(&$output) {
if (!isset($this->scriptFiles[self::POS_END]) && !isset($this->scripts[self::POS_END]) && !isset($this->scripts[self::POS_READY]) && !isset($this->scripts[self::POS_LOAD]) && !count($this->htmls) == 0)
return;
$fullPage = 0;
$output = preg_replace('/(<\\/body\s*>)/is', '<###end###>$1', $output, 1, $fullPage);
$html = '';
if (isset($this->scriptFiles[self::POS_END])) {
foreach ($this->scriptFiles[self::POS_END] as $scriptFile)
$html.=CHtml::scriptFile($scriptFile) . "\n";
}
//----------------------------------------------------------------------------------------------------
// Begin Custom
foreach ($this->htmls as $id => $htmlSnippet) {
$html .= $htmlSnippet;
}
//----------------------------------------------------------------------------------------------------
$scripts = isset($this->scripts[self::POS_END]) ? $this->scripts[self::POS_END] : array();
if (isset($this->scripts[self::POS_READY])) {
if ($fullPage)
$scripts[] = "jQuery(function($) {\n" . implode("\n", $this->scripts[self::POS_READY]) . "\n});";
else
$scripts[] = implode("\n", $this->scripts[self::POS_READY]);
}
if (isset($this->scripts[self::POS_LOAD])) {
if ($fullPage)
$scripts[] = "jQuery(window).on('load',function() {\n" . implode("\n", $this->scripts[self::POS_LOAD]) . "\n});";
else
$scripts[] = implode("\n", $this->scripts[self::POS_LOAD]);
}
if (!empty($scripts))
$html.=CHtml::script(implode("\n", $scripts)) . "\n";
if ($fullPage)
$output = str_replace('<###end###>', $html, $output);
else
$output = $output . $html;
}
}
?>

View File

@ -0,0 +1,76 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HConsoleApplication is used as base console application.
*
* HConsoleApplication extends the default console application with some
* functionalities about events and theming support.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.8
*/
class HConsoleApplication extends CConsoleApplication {
/**
* Current theme name
*
* @var String
*/
public $theme;
/**
* Initializes the console application and setup some event handlers
*/
protected function init() {
parent::init();
$this->interceptor->start();
$this->interceptor->intercept($this);
$this->moduleManager->start();
if ($this->hasEventHandler('onInit'))
$this->onInit(new CEvent($this));
}
/**
* Raised after the application inits.
* @param CEvent $event the event parameter
*/
public function onInit($event) {
$this->raiseEvent('onInit', $event);
}
/**
* Adds a new command to the Console Application
*
* @param String $name
* @param String $file
*/
public function addCommand($name, $file) {
$this->getCommandRunner()->commands[$name] = $file;
}
}
?>

View File

@ -0,0 +1,50 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HConsoleApplicationBehavior is added to all console applications.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HConsoleApplicationBehavior extends CBehavior {
/**
* Adds a null view renderer.
*
* @return null
*/
public function getViewRenderer() {
return NULL;
}
/**
* Returns null theme.
*
* @return null
*/
public function getTheme() {
return NULL;
}
}
?>

View File

@ -0,0 +1,73 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HConsoleCommand extends the default CConsoleCommand.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HConsoleCommand extends CConsoleCommand {
/**
* Inits the command and prepares the base environment.
*/
public function init() {
Yii::app()->interceptor->intercept($this);
Yii::import('application.vendors.*');
require_once('adLDAP/adLDAP.php');
EZendAutoloader::$prefixes = array('Zend', 'Custom');
Yii::import("ext.yiiext.components.zendAutoloader.EZendAutoloader", true);
Yii::registerAutoloader(array("EZendAutoloader", "loadClass"), true);
ini_set('max_execution_time', 9000);
ini_set('memory_limit', '1024M');
date_default_timezone_set("Europe/Berlin");
error_reporting(E_ALL ^ E_NOTICE);
#HSetting::InstallBase();
}
/**
* Prints out the console application header
*
* @param String $title is the title of the command
*/
protected function printHeader($title) {
print "
HumHub Console Interface - Version 1
--------------------------------------------------------------------------------
$title
--------------------------------------------------------------------------------\n
\n";
}
}
?>

View File

@ -0,0 +1,49 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HHttpRequest extends the CHttpRequest.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HHttpRequest extends CHttpRequest {
public $csrfTokenName = 'CSRF_TOKEN';
/**
* Returns whether this is an AJAX (XMLHttpRequest) request.
* @return boolean whether this is an AJAX (XMLHttpRequest) request.
*/
public function getIsAjaxRequest() {
if (!parent::getIsAjaxRequest()) {
if (isset($_REQUEST['ajax'])) {
return true;
}
return false;
}
return true;
}
}
?>

View File

@ -0,0 +1,92 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HInterceptor allows modules to attach events and behaviors to all SIComponents.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HInterceptor extends CApplicationComponent {
/**
* @var Array list of events and callbacks
*/
private $events = array();
/**
* Starts interceptor service
*/
public function start() {
}
/**
* Intercepts a given object instance
*
* @param Object $obj
*/
public function intercept($obj) {
// Attach Event Handler for this class
$className = get_class($obj);
if (isset($this->events[$className])) {
foreach ($this->events[$className] as $event) {
$obj->attachEventHandler($event[0], $event[1]);
}
}
// Install also for parent classes
$parentClassName = get_parent_class($className);
while ($parentClassName !== false) {
if (isset($this->events[$parentClassName])) {
foreach ($this->events[$parentClassName] as $event) {
$obj->attachEventHandler($event[0], $event[1]);
}
}
$parentClassName = get_parent_class($parentClassName);
}
}
/**
* Attaches an event handler
*
* @param String $className
* @param String $eventName
* @param type $handler
*/
public function attachEventHandler($className, $eventName, $handler=null) {
# if ($className == 'ModuleManager') {#
# // There is already an instance
# Yii::app()->moduleManager->attachEventHandler($eventName, $handler);
# return;
#}
if (!isset($this->events[$className]))
$this->events[$className] = array();
$this->events[$className][] = array($eventName, $handler);
}
}
?>

View File

@ -0,0 +1,97 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HMailMessage is a changed version of the YiiMailMessage class.
* Its supports better theming support and allows mail views in different folders.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HMailMessage extends YiiMailMessage {
/**
* Set the body of this entity, either as a string, or array of view
* variables if a view is set, or as an instance of
* {@link Swift_OutputByteStream}.
*
* @param mixed the body of the message. If a $this->view is set and this
* is a string, this is passed to the view as $body. If $this->view is set
* and this is an array, the array values are passed to the view like in the
* controller render() method
* @param string content type optional. For html, set to 'html/text'
* @param string charset optional
*/
public function setBody($body = '', $contentType = null, $charset = null) {
if ($this->view !== null) {
if (!is_array($body))
$body = array('body' => $body);
// if Yii::app()->controller doesn't exist create a dummy
// controller to render the view (needed in the console app)
if (isset(Yii::app()->controller))
$controller = Yii::app()->controller;
else
$controller = new CController('YiiMail');
// File Path to Template
$viewPath = "";
// Name of current theme if enabled
$themeName = "";
if (Yii::app() instanceOf CConsoleApplication) {
// ConsoleApplication
Yii::setPathOfAlias('webroot', '../' . dirname($_SERVER['SCRIPT_FILENAME']));
if (Yii::app()->theme && Yii::app()->theme != "") {
$themeName = Yii::app()->theme;
}
} else {
// WebApplication
if (($theme = Yii::app()->getTheme()) !== null) {
$themeName = $theme->getName();
}
}
// When ThemeName is speified
if ($themeName != "") {
$viewThemed = str_replace('application.views.', 'webroot.themes.' . $themeName . '.views.', $this->view);
$viewThemed = preg_replace('/application\.modules(?:_core)?\.(.*?)\.views\.(.*)/i', 'webroot.themes.' . $themeName . '.views.\1.\2', $viewThemed);
if (file_exists(Yii::getPathOfAlias($viewThemed) . ".php")) {
$viewPath = Yii::getPathOfAlias($viewThemed) . ".php";
}
}
// Use orginal view name, if not set yet
if ($viewPath == "") {
$viewPath = Yii::getPathOfAlias($this->view) . ".php";
}
$body = $controller->renderInternal($viewPath, array_merge($body, array('mail' => $this)), true);
}
return $this->message->setBody($body, $contentType, $charset);
}
}
?>

View File

@ -0,0 +1,140 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HPhpMessageSource is a changed version of CPhpMessageSource class.
*
* @package humhub.components
* @since 0.5
*/
class HPhpMessageSource extends CPhpMessageSource {
const CACHE_KEY_PREFIX = 'Yii.CPhpMessageSource.';
/**
* @var integer the time in seconds that the messages can remain valid in cache.
* Defaults to 0, meaning the caching is disabled.
*/
public $cachingDuration = 0;
/**
* @var string the ID of the cache application component that is used to cache the messages.
* Defaults to 'cache' which refers to the primary cache application component.
* Set this property to false if you want to disable caching the messages.
*/
public $cacheID = 'cache';
/**
* @var string the base path for all translated messages. Defaults to null, meaning
* the "messages" subdirectory of the application directory (e.g. "protected/messages").
*/
public $basePath;
/**
* @var array the message paths for extensions that do not have a base class to use as category prefix.
* The format of the array should be:
* <pre>
* array(
* 'ExtensionName' => 'ext.ExtensionName.messages',
* )
* </pre>
* Where the key is the name of the extension and the value is the alias to the path
* of the "messages" subdirectory of the extension.
* When using Yii::t() to translate an extension message, the category name should be
* set as 'ExtensionName.categoryName'.
* Defaults to an empty array, meaning no extensions registered.
* @since 1.1.13
*/
public $extensionPaths = array();
private $_files = array();
/**
* Initializes the application component.
* This method overrides the parent implementation by preprocessing
* the user request data.
*/
public function init() {
parent::init();
if ($this->basePath === null)
$this->basePath = Yii::getPathOfAlias('application.messages');
}
/**
* Determines the message file name based on the given category and language.
* If the category name contains a dot, it will be split into the module class name and the category name.
* In this case, the message file will be assumed to be located within the 'messages' subdirectory of
* the directory containing the module class file.
* Otherwise, the message file is assumed to be under the {@link basePath}.
* @param string $category category name
* @param string $language language ID
* @return string the message file path
*/
protected function getMessageFile($category, $language) {
if (!isset($this->_files[$category][$language])) {
if (($pos = strpos($category, '.')) !== false) {
$extensionClass = substr($category, 0, $pos);
$extensionCategory = substr($category, $pos + 1);
// First check if there's an extension registered for this class.
if (isset($this->extensionPaths[$extensionClass]))
$this->_files[$category][$language] = Yii::getPathOfAlias($this->extensionPaths[$extensionClass]) . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . $extensionCategory . '.php';
else {
// No extension registered, need to find it.
try {
$class = new ReflectionClass($extensionClass);
$this->_files[$category][$language] = dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'messages' . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . $extensionCategory . '.php';
} catch (Exception $e) {
return "";
}
}
} else
$this->_files[$category][$language] = $this->basePath . DIRECTORY_SEPARATOR . $language . DIRECTORY_SEPARATOR . $category . '.php';
}
return $this->_files[$category][$language];
}
/**
* Loads the message translation for the specified language and category.
* @param string $category the message category
* @param string $language the target language
* @return array the loaded messages
*/
protected function loadMessages($category, $language) {
$messageFile = $this->getMessageFile($category, $language);
if ($this->cachingDuration > 0 && $this->cacheID !== false && ($cache = Yii::app()->getComponent($this->cacheID)) !== null) {
$key = self::CACHE_KEY_PREFIX . $messageFile;
if (($data = $cache->get($key)) !== false)
return unserialize($data);
}
if (is_file($messageFile)) {
$messages = include($messageFile);
if (!is_array($messages))
$messages = array();
if (isset($cache)) {
$dependency = new CFileCacheDependency($messageFile);
$cache->set($key, serialize($messages), $this->cachingDuration, $dependency);
}
return $messages;
} else
return array();
}
}

View File

@ -0,0 +1,69 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HTheme is an overwrite of CTheme
*
* This is caused by our view path for modules is also separeted into modules/ folders.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HTheme extends CTheme {
/**
* Finds the view file for the specified controller's view.
*
* @param CController $controller the controller
* @param string $viewName the view name
* @return string the view file path. False if the file does not exist.
*/
/*
public function getViewFile($controller, $viewName) {
$moduleViewPath = $this->getViewPath();
if (($module = $controller->getModule()) !== null) {
$moduleViewPath.='/modules/' . $module->getId();
# ^^^^^^ added modules here
}
return $controller->resolveViewFile($viewName, $this->getViewPath() . '/' . $controller->getUniqueId(), $this->getViewPath(), $moduleViewPath);
}
*/
/**
* Returns an array of all installed themes.
*
* @return Array
*/
public static function getThemes() {
$themes = array();
$themePath = Yii::getPathOfAlias('webroot') . DIRECTORY_SEPARATOR . "themes";
foreach (scandir($themePath) as $file) {
if ($file == "." || $file == ".." || !is_dir($themePath . DIRECTORY_SEPARATOR . $file)) {
continue;
}
$themes[$file] = $file;
}
return $themes;
}
}
?>

View File

@ -0,0 +1,150 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* HWidget is the base class for all widgets.
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class HWidget extends CWidget {
/**
* @var array view paths for different types of widgets
*/
private static $_viewPaths;
/**
* Returns the view path for this widget.
*
* Transform:
* /protected/modules/moduleId/widgets/views/ to /themes/mytheme/views/moduleId/widgets
* /protected/widgets/views/ to /themes/mytheme/views/widgets
*
* Instead of normal yii behavior:
* /themes/myTheme/WidgetClass/..
*
* @param type $checkTheme
* @return String
*/
public function getViewPath($checkTheme = false) {
// Fastlane
$className = get_class($this);
if (isset(self::$_viewPaths[$className]))
return self::$_viewPaths[$className];
if ($checkTheme && ($theme = Yii::app()->getTheme()) !== null) {
// /themes/myTheme/views/
$path = $theme->getViewPath() . DIRECTORY_SEPARATOR;
// + moduleId/ - if exists
$moduleId = $this->getModuleId();
if ($moduleId)
$path .= $moduleId . DIRECTORY_SEPARATOR;
$path .= 'widgets' . DIRECTORY_SEPARATOR;
if (is_dir($path))
return self::$_viewPaths[$className] = $path;
}
$class = new ReflectionClass($className);
return self::$_viewPaths[$className] = dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'views';
}
/**
* Extends CWidgets getViewFile by possibilty to get also themed version
* of a dotted view Filename
*
* @param string $viewName name of the view (without file extension)
* @return string the view file path. False if the view file does not exist
* @see CApplication::findLocalizedFile
*/
public function getViewFile($viewName) {
// a path alias e.g. application.modules.x.y.z.
if (strpos($viewName, '.')) {
if (($theme = Yii::app()->getTheme()) !== null) {
// Replace application.modules[_core].MODULEID.widgets.views
// in
// webroot.themes.CURRENTTHEME.views.MODULEID.widgets
$viewNameTheme = $viewName;
$viewNameTheme = str_replace('application.views.', 'webroot.themes.' . $theme->getName() . '.views.', $viewNameTheme);
$viewNameTheme = preg_replace('/application\.modules(?:_core)?\.(.*?)\.views\.(.*)/i', 'webroot.themes.' . $theme->getName() . '.views.\1.\2', $viewNameTheme);
#$viewNameTheme = preg_replace('/widgets\.views/', 'widgets', $viewNameTheme);
$viewFile = Yii::getPathOfAlias($viewNameTheme);
// Check if File exists
if (is_file($viewFile . '.php')) {
return Yii::app()->findLocalizedFile($viewFile . '.php');
}
}
// Fall Back to default
}
return parent::getViewFile($viewName);
}
/**
* Returns the parent moduleId if can determined.
* This requires that the module is located under /modules/ or /modules_core/.
*
* It doesn´t support nested modules.
* Always the parent moduleId is returned.
*
* @return String The Id of Module
*/
public function getModuleId() {
// Get Directory of current widget class
$reflector = new ReflectionClass(get_class($this));
$fileName = $reflector->getFileName();
// Search for .../modules_core/FINDME/... or .../modules/FINDME/...
preg_match('/\/modules(?:_core)?\/(.*?)\//', $fileName, $match);
if (isset($match[1]))
return $match[1];
return null;
}
/**
* Adds the createUrl functionality to widget by passing it to the current
* controller.
*
* @param String $action
* @param Array $params
* @param String $ampersand
* @return String url
*/
public function createUrl($action, $params = array(), $ampersand = '&') {
return $this->getController()->createUrl($this->actionPrefix . $action, $params, $ampersand);
}
}
?>

View File

@ -0,0 +1,411 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* ModuleManager allows dynamic enabling/disabling of application modules.
*
* Each module has a autostart.php which can register the module.
*
* Modules must register with a module definition, which holds all relevant
* information about it.
*
* Module Definition Array:
* id => mymodule (also folder name under /modules/...)
* title => My Module
* icon => cssClass
* description => someText (For Admin Manage Modules)
* isSpaceModule => true/FALSE (Is a workspace module)
* isCoreModule => true/FALSE (Is core module, always enabled)
* configRoute => 'mymodule/configure' (Configuration URL for SuperAdmin)
*
* @todo cache enabled modules - problem module manager started before caching
*
* @package humhub.components
* @since 0.5
*/
class ModuleManager extends CApplicationComponent {
const AUTOSTART_CACHE_FILE_NAME = "cache_autostart.php";
/**
* @var Array of all registered module definitions
*/
public $registeredModules;
/**
* @var Array of enabled module ids.
*/
public $enabledModules;
/**
* @var Array of registered content model classes.
*/
public $registeredContentModels = array();
/**
* Initializes the application component.
* This should also should check which module is enabled
*/
public function init() {
parent::init();
if (Yii::app()->params['installed'])
$this->loadEnabledModules();
// Intercept this controller
Yii::app()->interceptor->intercept($this);
}
public function start() {
$this->executeAutoloaders();
#print "start";
#die();
}
/**
* Searches and executes all module autoloaders.
*
* The module autoloaders are stored in a file "autostart.php" which can be
* placed in the root directory of the module.
*
* @todo Caching autostarts
* @todo Remove rendundant code
*/
private function executeAutoloaders() {
$cacheFileName = Yii::app()->getRuntimePath() . DIRECTORY_SEPARATOR . self::AUTOSTART_CACHE_FILE_NAME;
if (file_exists($cacheFileName)) {
require_once($cacheFileName);
return;
}
$fileNames = array();
// Looking up 3rd party modules
$modulesPaths = array(Yii::app()->getBasePath() . DIRECTORY_SEPARATOR . 'modules', Yii::app()->getBasePath() . DIRECTORY_SEPARATOR . 'modules_core');
// Execute Autoloaders in each modules paths
foreach ($modulesPaths as $modulesPath) {
// Scan Modules
$modules = scandir($modulesPath);
foreach ($modules as $module) {
if ($module == '.' || $module == '..')
continue;
$moduleDir = $modulesPath . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR;
if (is_dir($moduleDir) && is_file($moduleDir . 'autostart.php')) {
// Store Filename to Cache Content
$fileNames[] = $moduleDir . 'autostart.php';
// Execute Autoloader
require_once($moduleDir . 'autostart.php');
}
}
}
// Created a file which contains all autoloaders
$content = "";
foreach ($fileNames as $fileName) {
$content .= file_get_contents($fileName);
}
file_put_contents($cacheFileName, $content);
}
/**
* Loads all enabled modules from the database. (Cached)
*/
private function loadEnabledModules() {
$cacheId = "enabledModules";
$cacheValue = Yii::app()->cache->get($cacheId);
if ($cacheValue === false || !is_array($cacheValue)) {
$enabledModules = array();
foreach (ModuleEnabled::model()->findAll() as $em) {
$enabledModules[$em->module_id] = $em->module_id;
}
Yii::app()->cache->set($cacheId, $enabledModules, HSetting::Get('expireTime', 'cache'));
$this->enabledModules = $enabledModules;
} else {
$this->enabledModules = $cacheValue;
}
}
/**
* Flushes Module Managers cache
*/
public function flushCache() {
// Autoloader Cache File
$cacheFileName = Yii::app()->getRuntimePath() . DIRECTORY_SEPARATOR . self::AUTOSTART_CACHE_FILE_NAME;
if (file_exists($cacheFileName)) {
unlink($cacheFileName);
}
$cacheId = "enabledModules";
Yii::app()->cache->delete($cacheId);
}
/**
* Registers a module
* This is usally called in the autostart file of the module.
*
* @param Array $definition
*/
public function register($definition) {
$id = $definition['id'];
if (!isset($definition['isSpaceModule']))
$definition['isSpaceModule'] = false;
if (!isset($definition['isCoreModule']))
$definition['isCoreModule'] = false;
if (!isset($definition['configRoute']))
$definition['configRoute'] = '';
if (!isset($definition['spaceConfigRoute']))
$definition['spaceConfigRoute'] = '';
$this->registeredModules[$id] = $definition;
// Check if module is enabled
if (Yii::app()->moduleManager->isEnabled($id)) {
// Register Yii Module
if (isset($definition['class'])) {
Yii::app()->setModules(array(
$id => array(
'class' => $definition['class']
),
));
}
// Set Imports
if (isset($definition['import'])) {
Yii::app()->setImport($definition['import']);
}
// Register Event Handlers
if (isset($definition['events'])) {
foreach ($definition['events'] as $event) {
Yii::app()->interceptor->attachEventHandler(
$event['class'], $event['event'], $event['callback']
);
}
}
}
}
/**
* Checks if a module is enabled or not.
*
* @param type $moduleId
* @return boolean
*/
public function isEnabled($moduleId) {
$definition = $this->getDefinition($moduleId);
if ($definition['isCoreModule'])
return true;
// Core installed yet?
if (!Yii::app()->params['installed'])
return false;
if (in_array($moduleId, $this->enabledModules)) {
return true;
}
#$moduleEnabled = ModuleEnabled::model()->findByPk($moduleId);
#if ($moduleEnabled != null) {
# return true;
#}
return false;
}
/**
* Returns an array with all registered modules
* This contains all enabled & disabled modules.
* Key is the moduleId and value is the module definition
*
* @return type
*/
public function getRegisteredModules() {
return $this->registeredModules;
}
/**
* Returns an array with enabled modules
* Key of the array is the module id and value is the module definition.
*
* @return array
*/
public function getEnabledModules() {
$enabledModules = array();
foreach ($this->getRegisteredModules() as $moduleId => $definition) {
if ($this->isEnabled($moduleId)) {
$enabledModules[$moduleId] = $definition;
}
}
return $enabledModules;
}
/**
* Enables a module by given module id.
*
* @param String $id
*/
public function enable($id) {
$definition = $this->getDefinition($id);
if ($definition != null) {
// Core Modules doesn´t need to enabled
if (!$definition['isCoreModule']) {
$moduleEnabled = ModuleEnabled::model()->findByPk($id);
if ($moduleEnabled == null) {
$moduleEnabled = new ModuleEnabled();
$moduleEnabled->module_id = $id;
$moduleEnabled->save();
// Fire Event Disabled Event
if ($this->hasEventHandler('onEnable'))
$this->onEnable(new CEvent($this, $id));
}
}
}
$this->flushCache();
}
/**
* Disables a active module by given module id
*
* @param String $id
*/
public function disable($id) {
$definition = $this->getDefinition($id);
if ($definition != null) {
// Core Modules couldn´t disabled
if (!$definition['isCoreModule']) {
if (isset($definition['userModules']) && is_array($definition['userModules'])) {
$modulesToDisable = array_keys($definition['userModules']);
foreach (User::model()->findAll() as $user) {
foreach ($modulesToDisable as $userModuleId) {
if ($user->isModuleEnabled($userModuleId))
$user->uninstallModule($userModuleId);
}
}
}
if (isset($definition['spaceModules']) && is_array($definition['spaceModules'])) {
$modulesToDisable = array_keys($definition['spaceModules']);
foreach (Space::model()->findAll() as $space) {
foreach ($modulesToDisable as $spaceModuleId) {
if ($space->isModuleEnabled($spaceModuleId))
$space->uninstallModule($spaceModuleId);
}
}
}
// Get Enabled Module Record
$moduleEnabled = ModuleEnabled::model()->findByPk($id);
if ($moduleEnabled != null)
$moduleEnabled->delete();
// Fire Event Disabled Event
if ($this->hasEventHandler('onDisable'))
$this->onDisable(new CEvent($this, $id));
}
}
$this->flushCache();
}
/**
* This event is raised after disabling a module
*
* @param CEvent $event the event parameter
* @see disable
*/
public function onDisable($event) {
$this->raiseEvent('onDisable', $event);
}
/**
* This event is raised after enabling a module
*
* @param CEvent $event the event parameter
* @see enable
*/
public function onEnable($event) {
$this->raiseEvent('onEnable', $event);
}
/**
* Returns the definition array of a registered module
*
* @param type $id
* @return null
*/
public function getDefinition($id) {
if (isset($this->registeredModules[$id]))
return $this->registeredModules[$id];
return null;
}
/**
* Registers a new Content Model
*
* @param String $className
*/
public function registerContentModel($className) {
$this->registeredContentModels[] = $className;
}
/**
* Returns a list of all registered content models
*
* @return Array
*/
public function getContentModels() {
return $this->registeredContentModels;
}
}
?>

View File

@ -0,0 +1,77 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* WebApplication is the base WebApplication class
*
* @author Lucas Bartholemy <lucas@bartholemy.com>
* @package humhub.components
* @since 0.5
*/
class WebApplication extends CWebApplication {
/**
* Inits the webapplication
*
* Also start interceptor to add event support
*/
protected function init() {
parent::init();
$this->interceptor->start();
$this->interceptor->intercept($this);
$this->moduleManager->start();
if ($this->hasEventHandler('onInit'))
$this->onInit(new CEvent($this));
}
/**
* This event is raised after the init is executed.
* @param CEvent $event the event parameter
*/
public function onInit($event) {
$this->raiseEvent('onInit', $event);
}
/**
* Returns an array of available language codes
*
* @return Array
*/
public static function getLanguages() {
$languages = array();
$languages['en'] = 'en';
$files = scandir(Yii::app()->basePath . '/messages');
foreach ($files as $file) {
if ($file == '.' || $file == '..')
continue;
$languages[$file] = $file;
}
return $languages;
}
}
?>

View File

@ -0,0 +1,81 @@
<?php
return array(
'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
// Default Application Name
'name' => 'HumHub',
'preload' => array('log', 'input'),
'components' => array(
// Database
'db' => array(
'connectionString' => 'mysql:host=localhost;dbname=test',
'emulatePrepare' => true,
'charset' => 'utf8',
'enableProfiling' => true,
'enableParamLogging' => true,
'schemaCachingDuration' => 3600,
),
'moduleManager' => array(
'class' => 'application.components.ModuleManager',
),
'messages' => array(
'class' => 'application.components.HPhpMessageSource',
),
'input' => array(
'class' => 'application.extensions.CmsInput',
'cleanPost' => false,
'cleanGet' => false,
),
'interceptor' => array(
'class' => 'HInterceptor',
),
'session' => array(
'class' => 'application.modules_core.user.components.SIHttpSession',
'connectionID' => 'db',
'sessionName' => 'sin',
),
'request' => array(
//'enableCsrfValidation' => true,
),
// Caching (Will replaced at runtime)
'cache' => array(
'class' => 'CDummyCache'
),
),
// Modules
'modules' => array(
// All HumHub Modules will automatically loaded via
// /modules/*/autostart.php
// or
// /modules_core/*/autostart.php
),
// autoloading model and component classes
'import' => array(
'application.models.*',
'application.forms.*',
'application.components.*',
'application.behaviors.*',
'application.interfaces.*',
'application.libs.*',
'application.widgets.*',
// 3rd Party Extensions
'ext.yii-mail.YiiMailMessage',
'ext.EZendAutoloader.EZendAutoloader',
),
// application-level parameters that can be accessed
// using Yii::app()->params['paramName']
'params' => array(
// Installed Flag
'installed' => false,
// Authentication Options
'auth' => array(
// Available Registration Types
'modes' => array('local'),
// Local Authentication Options
'local' => array(
'freeRegistration' => true,
),
),
),
);
?>

View File

@ -0,0 +1,3 @@
<?php return array (
); ?>

View File

@ -0,0 +1,66 @@
<?php
/**
* Console Default Configuration
*
* This configuration file only affects only the console application.
*/
$pre_config = CMap::mergeArray(require (dirname(__FILE__) . '/_defaults.php'), require (dirname(__FILE__) . '/_settings.php'));
return CMap::mergeArray($pre_config, array(
'preload' => array('log'),
'behaviors' => array(
'viewRenderer' => 'HConsoleApplicationBehavior',
),
'components' => array(
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
),
'request' => array(
'class' => 'HHttpRequest',
),
'user' => array(
'class' => 'ConsoleUser',
),
'log' => array(
'class' => 'CLogRouter',
'routes' => array(
array(
'class' => 'CFileLogRoute',
'levels' => 'error, warning',
),
),
),
),
// autoloading model and component classes
'import' => array(
'application.models.*',
'application.forms.*',
'application.components.*',
'application.vendors.yii.cli.commands.*',
'application.libs.*',
'application.modules_core.user.components.*',
'ext.EZendAutoloader.EZendAutoloader',
'ext.migrate-command.*',
),
'commandMap' => array(
'message' => 'application.commands.shell.ZMessageCommand',
'search_rebuild' => 'application.commands.shell.SearchIndexer.Rebuilder',
'search_optimize' => 'application.commands.shell.SearchIndexer.Optimize',
'integritychecker' => 'application.commands.shell.Maintain.IntegrityChecker',
'search' => 'application.modules.zstunden.commands.Search',
'emailing' => 'application.commands.shell.EMailing.EMailing',
'emailing_test' => 'application.commands.shell.EMailing.TestMail',
'cron' => 'application.commands.shell.ZCron.ZCronRunner',
'migrate' => array(
'class' => 'application.commands.shell.ZMigrateCommand',
'migrationPath' => 'application.migrations',
'migrationTable' => 'migration',
),
),
));

View File

@ -0,0 +1,46 @@
<?php if ( ! defined('YII_PATH')) exit('No direct script access allowed');
return array(
/*'Attr.AllowedRel' => array('noindex','nofollow'),
'Attr.DefaultImageAlt' => NULL,
'Core.ColorKeywords' => array(
'maroon' => '#800000',
'red' => '#FF0000',
'orange' => '#FFA500',
'yellow' => '#FFFF00',
'olive' => '#808000',
'purple' => '#800080',
'fuchsia' => '#FF00FF',
'white' => '#FFFFFF',
'lime' => '#00FF00',
'green' => '#008000',
'navy' => '#000080',
'blue' => '#0000FF',
'aqua' => '#00FFFF',
'teal' => '#008080',
'black' => '#000000',
'silver' => '#C0C0C0',
'gray' => '#808080',
),
'Core.Encoding' => Yii::app()->charset,
'Core.EscapeInvalidTags' => FALSE,
'HTML.AllowedElements' => array(
'a','b','em','small','strong','del','q','img','span','ul','ol','li','h1','h2','h3','h4','h5','h6'
),
'HTML.AllowedAttributes' => array(
'href','rel','target','src', 'style',
),
*/
'HTML.Doctype' => 'XHTML 1.0 Transitional',
'URI.AllowedSchemes' => array(
'http' => true,
'https' => true,
'mailto' => true,
'ftp' => true,
'nntp' => true,
'news' => true,
),
'URI.Base'=>NULL,
);

27
protected/config/i18n.php Normal file
View File

@ -0,0 +1,27 @@
<?php
/**
* This is the configuration for generating message translations
* for the Yii framework. It is used by the 'yiic message' command.
*/
return array(
//'sourcePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'../..',
'sourcePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
'messagePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'messages',
//'languages'=>array('fi','zh_cn','zh_tw','de','de_du','1337', 'el','es','sv','he','nl','pt','pt_br','ru','it','fr','ja','pl','hu','ro','id','vi','bg','lv','sk','uk','ko_kr','kk','cs'),
'languages'=>array('de','fr'),
'fileTypes'=>array('php'),
'overwrite'=>true,
'exclude'=>array(
'.svn',
'.gitignore',
'yiilite.php',
'yiit.php',
'/i18n/data',
'/messages',
'/vendors',
'/web/js',
'yii',
),
);

61
protected/config/main.php Normal file
View File

@ -0,0 +1,61 @@
<?php
/**
* Web Application Default Configuration
*
* This file not affects console applications!
*/
Yii::setPathOfAlias('modules_core', dirname(__FILE__) . '/../modules_core');
$pre_config = CMap::mergeArray(require (dirname(__FILE__) . '/_defaults.php'), require (dirname(__FILE__) . '/_settings.php'));
return CMap::mergeArray($pre_config, array(
// preloading 'log' component
'preload' => array('log'),
// application components
'components' => array(
// Session specific settings
'session' => array(
),
'user' => array(
// enable cookie-based authentication
'allowAutoLogin' => true,
'class' => 'application.modules_core.user.components.WebUser',
'loginUrl' => array('//user/auth/login'),
),
'request' => array(
'class' => 'HHttpRequest',
'enableCsrfValidation' => true,
),
'clientScript' => array(
'class' => 'HClientScript',
),
// uncomment the following to enable URLs in path-format
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'<controller:\w+>/<id:\d+>' => '<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
),
),
'themeManager' => array(
'themeClass' => 'HTheme',
),
'errorHandler' => array(
// use 'site/error' action to display errors
'errorAction' => '//site/error',
),
'log' => array(
'class' => 'CLogRouter',
'routes' => array(
array(
'class' => 'CFileLogRoute',
'levels' => 'error, warning',
),
),
),
),
));

View File

@ -0,0 +1,182 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* Dashboard Controller
*
* @package humhub.controllers
* @since 0.5
*/
class DashboardController extends Controller {
/**
* @return array action filters
*/
public function filters() {
return array(
'accessControl', // perform access control for CRUD operations
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* @return array access control rules
*/
public function accessRules() {
return array(
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'users' => array('@'),
),
array('deny', // deny all users
'users' => array('*'),
),
);
}
/**
* Dashboard Index
*
* Show recent wall entries for this user
*/
public function actionIndex() {
// contains the current version to show the welcome modal
$version = 1;
Yii::app()->user->model->checkWall();
//$mySpaces = Yii::app()->user->getModel()->getSpaces();
//$this->render('index', array('mySpaces' => $mySpaces));
$this->render('index', array('version' => $version));
}
/**
* Page which shows all current workspaces
*/
public function actionSpaces() {
$pageSize = 5;
$criteria = new CDbCriteria();
$criteria->condition = 'visibility != ' . Space::VISIBILITY_NONE;
$criteria->order = 'id DESC';
//$criteria->params = array (':id'=>$id);
$workspaceCount = Space::model()->count($criteria);
$pages = new CPagination($workspaceCount);
$pages->setPageSize($pageSize);
$pages->applyLimit($criteria); // the trick is here!
$workspaces = Space::model()->findAll($criteria);
$this->render('workspaces', array(
'workspaces' => $workspaces,
'pages' => $pages,
'workspaceCount' => $workspaceCount,
'pageSize' => $pageSize,
));
}
/**
* Page which shows all people
*/
public function actionPeople() {
$criteria = new CDbCriteria();
//$criteria->condition = 'visibility != '.Space::VISIBILITY_NONE;
$criteria->order = 'firstname ASC';
$userCount = User::model()->count($criteria);
$pages = new CPagination($userCount);
$pages->setPageSize(HSetting::Get('paginationSize'));
$pages->applyLimit($criteria); // the trick is here!
$users = User::model()->findAll($criteria);
$this->render('people', array(
'users' => $users,
'pages' => $pages,
'userCount' => $userCount,
'pageSize' => HSetting::Get('paginationSize'),
));
}
/**
* Returns a JSON Object which contains a lot of informations about
* current states like new posts on workspaces
*/
public function actionGetFrontEndInfo() {
$json = array();
$json['workspaces'] = array();
$criteria = new CDbCriteria();
$criteria->order = 'last_visit DESC';
$memberships = UserSpaceMembership::model()->with('workspace')->findAllByAttributes(array(
'user_id' => Yii::app()->user->id,
'status' => UserSpaceMembership::STATUS_MEMBER
), $criteria);
foreach ($memberships as $membership) {
$workspace = $membership->workspace;
$info = array();
$info['name'] = $workspace->name;
#$info['id'] = $workspace->id; # should be hidden at frontend
$info['guid'] = $workspace->guid;
$info['totalItems'] = $workspace->countItems();
$info['newItems'] = $membership->countNewItems();
$json['workspaces'][] = $info;
}
if (Yii::app()->moduleManager->isEnabled('mail')) {
// New message count
$sql = "SELECT count(message_id)
FROM user_message
LEFT JOIN message on message.id = user_message.message_id
WHERE user_message.user_id = :user_id AND (message.updated_at > user_message.last_viewed OR user_message.last_viewed IS NULL)";
$connection = Yii::app()->db;
$command = $connection->createCommand($sql);
$userId = Yii::app()->user->id;
$command->bindParam(":user_id", $userId);
$json['newMessages'] = $command->queryScalar();
}
// New notification count
$sql = "SELECT count(id)
FROM notification
WHERE user_id = :user_id AND seen != 1";
$connection = Yii::app()->db;
$command = $connection->createCommand($sql);
$userId = Yii::app()->user->id;
$command->bindParam(":user_id", $userId);
$json['newNotifications'] = $command->queryScalar();
print CJSON::encode($json);
Yii::app()->end();
}
}

View File

@ -0,0 +1,156 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* Search Controller provides search functions inside the application.
*
* @author Luke
* @package humhub.controllers
* @since 0.5
*/
class SearchController extends Controller {
public $subLayout = "_layout";
/**
* @return array action filters
*/
public function filters() {
return array(
'accessControl', // perform access control for CRUD operations
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* @return array access control rules
*/
public function accessRules() {
return array(
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'users' => array('@'),
),
array('deny', // deny all users
'users' => array('*'),
),
);
}
/**
* SearchAction
*
* Modes: normal for full page, quick as partial for lightbox
*/
public function actionIndex() {
// Get Parameters
$keyword = Yii::app()->request->getParam('keyword', "");
$spaceGuid = Yii::app()->request->getParam('sguid', "");
$mode = Yii::app()->request->getParam('mode', "normal");
$page = (int) Yii::app()->request->getParam('page', 1); // current page (pagination)
// Cleanup
$keyword = Yii::app()->input->stripClean($keyword);
$spaceGuid = Yii::app()->input->stripClean($spaceGuid);
if ($mode != 'quick') {
$mode = "normal";
}
$limit = HSetting::Get('paginationSize'); // Show Hits
$hitCount = 0; // Total Hit Count
$query = ""; // Lucene Query
$append = " AND (model:User OR model:Space)"; // Appends for Lucene Query
$moreResults = false; // Indicates if there are more hits
$results = array();
// Quick Search shows always 1
if ($mode == 'quick')
$limit = 5;
// Load also Space if requested
$currentSpace = null;
if ($spaceGuid) {
$currentSpace = Space::model()->findByAttributes(array('guid' => $spaceGuid));
}
/*
* $index = new Zend_Search_Lucene_Interface_MultiSearcher();
* $index->addIndex(Zend_Search_Lucene::open('search/index1'));
* $index->addIndex(Zend_Search_Lucene::open('search/index2'));
* $index->find('someSearchQuery');
*/
// Do Search
if ($keyword != "") {
if ($currentSpace != null) {
$append = " AND (model:User OR model:Space OR (belongsToType:Space AND belongsToId:" . $currentSpace->id . "))";
}
$hits = new ArrayObject(HSearch::getInstance()->Find($keyword . $append));
$hitCount = count($hits);
// Limit Hits
$hits = new LimitIterator($hits->getIterator(), ($page - 1) * $limit, $limit);
if ($hitCount > $limit)
$moreResults = true;
// Build Results Array
foreach ($hits as $hit) {
$doc = $hit->getDocument();
$model = $doc->getField('model')->value;
$pk = $doc->getField('pk')->value;
$object = $model::model()->findByPk($pk);
$results[] = $object->getSearchResult();
}
}
// Create Pagination Class
$pages = new CPagination($hitCount);
$pages->setPageSize($limit);
$_GET['keyword'] = $keyword; // Fix for post var
if ($mode == 'quick') {
$this->renderPartial('quick', array(
'keyword' => $keyword,
'results' => $results,
'spaceGuid' => $spaceGuid,
'moreResults' => $moreResults,
'hitCount' => $hitCount,
));
} else {
$this->render('index', array(
'keyword' => $keyword,
'results' => $results,
'spaceGuid' => $spaceGuid,
'moreResults' => $moreResults,
'pages' => $pages, // CPagination,
'pageSize' => $limit,
'hitCount' => $hitCount,
));
}
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* HumHub
* Copyright © 2014 The HumHub Project
*
* The texts of the GNU Affero General Public License with an additional
* permission and of our proprietary license can be found at and
* in the LICENSE file you have received along with this program.
*
* According to our dual licensing model, this program can be used either
* under the terms of the GNU Affero General Public License, version 3,
* or under a proprietary license.
*
* 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.
*/
/**
* Site Controller
*
* @package humhub.controllers
* @since 0.5
*/
class SiteController extends Controller {
/**
* This is the default 'index' action that is invoked
* when an action is not explicitly requested by users.
*/
public function actionIndex() {
$this->redirect(array('dashboard/index'));
}
/**
* This is the action to handle external exceptions.
*/
public function actionError() {
if ($error = Yii::app()->errorHandler->error) {
if (Yii::app()->request->isAjaxRequest)
echo $error['message'];
else
$this->render('error', $error);
}
}
}

Binary file not shown.

View File

@ -0,0 +1,39 @@
-- phpMyAdmin SQL Dump
-- version 4.0.0-rc2
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Erstellungszeit: 21. Sep 2013 um 06:31
-- Server Version: 5.1.66-0+squeeze1
-- PHP-Version: 5.3.3-7+squeeze15
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Datenbank: `zamm_clean`
--
--
-- Daten für Tabelle `group`
--
INSERT INTO `group` (`id`, `space_id`, `name`, `description`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, NULL, 'Example Group', '', '2012-10-16 01:06:19', 1, '2012-10-16 01:06:19', 1);
--
-- Daten für Tabelle `registry`
--
INSERT INTO `registry` (`id`, `name`, `value`, `value_text`, `module_id`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 'dbVersion', '20', NULL, NULL, '0000-00-00 00:00:00', 0, '2013-06-08 15:15:45', 0);
--
-- Daten für Tabelle `user`
--
INSERT INTO `user` (`id`, `guid`, `user_invite_id`, `wall_id`, `group_id`, `status`, `super_admin`, `username`, `email`, `password`, `auth_mode`, `firstname`, `lastname`, `title`, `street`, `zip`, `city`, `country`, `state`, `about`, `tags`, `phone_private`, `phone_work`, `mobile`, `fax`, `language`, `im_skype`, `im_msn`, `im_icq`, `im_xmpp`, `url`, `url_facebook`, `url_linkedin`, `url_xing`, `url_youtube`, `url_vimeo`, `url_flickr`, `url_myspace`, `url_googleplus`, `url_twitter`, `receive_email_notifications`, `receive_email_messaging`, `receive_email_activities`, `last_activity_email`, `created_at`, `created_by`, `updated_at`, `updated_by`) VALUES
(1, 'b2fc71a5-abe6-adad-805f-588de32036f4', NULL, 2, 1, 1, 1, 'admin', 'l.bartholemy@zeros.ones.de', '___enc___08a593a5bec48fa3eb0c1a697968638527e83f81', 'local', 'System', 'Admin', '', '', '', 'Server', 'Germany', '', NULL, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 3, 3, 3, '2013-06-17 07:05:01', '2012-10-16 01:05:08', NULL, '2013-06-17 05:22:54', 1);

View File

@ -0,0 +1,625 @@
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
CREATE TABLE IF NOT EXISTS `activity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(45) DEFAULT NULL COMMENT 'CLASS_TYPE of Activity Object',
`module` varchar(100) NOT NULL,
`object_model` varchar(100) NOT NULL,
`object_id` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message` text,
`object_model` varchar(100) NOT NULL,
`object_id` int(11) NOT NULL,
`space_id` int(11) DEFAULT NULL COMMENT 'If inside a workspace (for Counting)',
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `object_id` (`object_id`,`object_model`),
KEY `workspace_id` (`space_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `content` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` varchar(45) NOT NULL,
`object_model` varchar(100) NOT NULL,
`object_id` int(11) NOT NULL,
`visibility` tinyint(4) DEFAULT NULL,
`sticked` tinyint(4) DEFAULT NULL,
`archived` tinytext,
`space_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `object_model` (`object_model`,`object_id`),
UNIQUE KEY `guid` (`guid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `file` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` varchar(45) DEFAULT NULL,
`object_model` varchar(100) NOT NULL,
`object_id` int(11) NOT NULL,
`file_name` varchar(255) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`mime_type` varchar(150) DEFAULT NULL,
`size` varchar(45) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `guid_UNIQUE` (`guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`space_id` int(10) DEFAULT NULL,
`name` varchar(45) DEFAULT NULL,
`description` text,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `group_admin` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `like` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`target_user_id` int(11) NOT NULL,
`object_model` varchar(100) NOT NULL,
`object_id` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `object_id_2` (`object_id`,`object_model`,`created_by`),
KEY `object_id` (`object_id`,`object_model`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `message_entry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`file_id` int(11) DEFAULT NULL,
`content` text NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_message_content_message1` (`message_id`),
KEY `fk_message_content_user1` (`user_id`),
KEY `fk_message_entry_file1` (`file_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `migration` (
`version` varchar(255) NOT NULL,
`apply_time` int(11) DEFAULT NULL,
PRIMARY KEY (`version`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `module_enabled` (
`module_id` varchar(100) NOT NULL,
PRIMARY KEY (`module_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `note` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `notification` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`class` varchar(100) NOT NULL,
`user_id` int(11) NOT NULL,
`seen` tinyint(4) DEFAULT NULL,
`source_object_model` varchar(100) DEFAULT NULL,
`source_object_id` int(11) DEFAULT NULL,
`target_object_model` varchar(100) DEFAULT NULL,
`target_object_id` int(11) DEFAULT NULL,
`space_id` int(11) DEFAULT NULL,
`emailed` tinyint(4) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `poll` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`question` varchar(255) NOT NULL,
`allow_multiple` tinyint(4) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `poll_answer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`poll_id` int(11) NOT NULL,
`answer` varchar(255) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `doodle_id` (`poll_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `poll_answer_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`poll_id` int(11) NOT NULL,
`poll_answer_id` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `doodle_answer_id_2` (`poll_answer_id`,`created_by`),
KEY `doodle_id` (`poll_id`),
KEY `doodle_answer_id` (`poll_answer_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `post` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message` text,
`original_message` text,
`url` varchar(255) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `profile` (
`user_id` int(11) NOT NULL,
`firstname` varchar(255) DEFAULT NULL,
`lastname` varchar(255) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`street` varchar(255) DEFAULT NULL,
`zip` int(11) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`country` varchar(255) DEFAULT NULL,
`state` varchar(255) DEFAULT NULL,
`about` text,
`phone_private` varchar(255) DEFAULT NULL,
`phone_work` varchar(255) DEFAULT NULL,
`mobile` varchar(255) DEFAULT NULL,
`fax` varchar(255) DEFAULT NULL,
`im_skype` varchar(255) DEFAULT NULL,
`im_msn` varchar(255) DEFAULT NULL,
`im_icq` int(11) DEFAULT NULL,
`im_xmpp` varchar(255) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
`url_facebook` varchar(255) DEFAULT NULL,
`url_linkedin` varchar(255) DEFAULT NULL,
`url_xing` varchar(255) DEFAULT NULL,
`url_youtube` varchar(255) DEFAULT NULL,
`url_vimeo` varchar(255) DEFAULT NULL,
`url_flickr` varchar(255) DEFAULT NULL,
`url_myspace` varchar(255) DEFAULT NULL,
`url_googleplus` varchar(255) DEFAULT NULL,
`url_twitter` varchar(255) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `profile_field` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`profile_field_category_id` int(11) NOT NULL,
`module_id` varchar(255) DEFAULT NULL,
`field_type_class` varchar(255) NOT NULL,
`field_type_config` text,
`internal_name` varchar(100) NOT NULL,
`title` varchar(255) NOT NULL,
`description` text,
`sort_order` int(11) NOT NULL,
`required` tinyint(4) DEFAULT NULL,
`show_at_registration` tinyint(4) DEFAULT NULL,
`editable` tinyint(4) NOT NULL DEFAULT '1',
`visible` tinyint(4) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `profile_field_category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
`sort_order` int(11) NOT NULL,
`module_id` int(11) DEFAULT NULL,
`visibility` tinyint(4) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `setting` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`value` varchar(255) NOT NULL,
`value_text` text,
`module_id` varchar(100) DEFAULT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`,`module_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `sifeedback` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`message` text NOT NULL,
`username` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`current_url` varchar(255) NOT NULL,
`rating` varchar(255) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `space` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` varchar(45) DEFAULT NULL,
`wall_id` int(11) DEFAULT NULL,
`name` varchar(45) NOT NULL,
`description` text,
`website` varchar(45) DEFAULT NULL,
`join_policy` tinyint(4) DEFAULT NULL COMMENT '0=NO; 1=application; 2=free',
`visibility` tinyint(4) DEFAULT NULL COMMENT '0=Unvisible; 1=Registered Only; 2=Always/Everybody',
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '0=Disabled; 1=Enabled; 2=Archived',
`tags` text,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `guid` (`guid`),
KEY `fk_Group_Wall1` (`wall_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `space_follow` (
`user_id` int(11) NOT NULL,
`space_id` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`user_id`,`space_id`),
KEY `fk_user_has_workspace_workspace1` (`space_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `space_module` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`module_id` varchar(255) NOT NULL,
`space_id` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `task` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` text NOT NULL,
`deathline` datetime DEFAULT NULL,
`max_users` int(11) NOT NULL,
`status` int(11) NOT NULL,
`percent` smallint(6) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `task_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`task_id` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`task_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` varchar(45) DEFAULT NULL,
`user_invite_id` int(11) DEFAULT NULL,
`wall_id` int(11) DEFAULT NULL,
`group_id` int(11) DEFAULT NULL,
`status` tinyint(4) NOT NULL DEFAULT '2' COMMENT '0=Disabled; 1=Enabled; 2=NeedApproval; 3=Deleted',
`super_admin` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'Is SuperAdmin?',
`username` varchar(25) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`password` varchar(200) DEFAULT NULL,
`auth_mode` varchar(10) NOT NULL,
`tags` text,
`language` varchar(5) NOT NULL,
`receive_email_notifications` tinyint(4) NOT NULL,
`receive_email_messaging` tinyint(4) NOT NULL,
`receive_email_activities` tinyint(4) NOT NULL,
`last_activity_email` datetime NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idUser_UNIQUE` (`id`),
UNIQUE KEY `email_UNIQUE` (`email`),
UNIQUE KEY `username_UNIQUE` (`username`),
UNIQUE KEY `idWall_UNIQUE` (`wall_id`),
UNIQUE KEY `idUserInvite_UNIQUE` (`user_invite_id`),
KEY `fk_user_group1` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_content` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`object_model` varchar(100) NOT NULL,
`object_id` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`object_model`,`object_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_follow` (
`user_follower_id` int(11) NOT NULL,
`user_followed_id` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`user_follower_id`,`user_followed_id`),
KEY `fk_UserFollows_User2` (`user_followed_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_http_session` (
`id` char(32) NOT NULL,
`expire` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`data` longblob,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_invite` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_originator_id` int(11) DEFAULT NULL,
`space_invite_id` int(11) DEFAULT NULL,
`email` varchar(45) NOT NULL,
`source` varchar(45) DEFAULT NULL COMMENT 'Source Key where invite comes from',
`token` varchar(45) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email_UNIQUE` (`email`),
UNIQUE KEY `token_UNIQUE` (`token`),
KEY `fk_user_invite_Group1` (`space_invite_id`),
KEY `fk_user_invite_user1` (`user_originator_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_message` (
`message_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`is_originator` tinyint(4) DEFAULT NULL,
`last_viewed` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`message_id`,`user_id`),
KEY `fk_message_has_user_user1` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_module` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`module_id` varchar(255) NOT NULL,
`user_id` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_old` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` varchar(45) DEFAULT NULL,
`user_invite_id` int(11) DEFAULT NULL,
`wall_id` int(11) DEFAULT NULL,
`group_id` int(11) DEFAULT NULL,
`status` tinyint(4) NOT NULL DEFAULT '2' COMMENT '0=Disabled; 1=Enabled; 2=NeedApproval; 3=Deleted',
`super_admin` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'Is SuperAdmin?',
`username` varchar(25) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`password` varchar(200) DEFAULT NULL,
`auth_mode` varchar(10) NOT NULL,
`firstname` varchar(45) DEFAULT NULL,
`lastname` varchar(45) DEFAULT NULL,
`title` varchar(45) DEFAULT NULL COMMENT 'z.B. Kaffeetrinker',
`street` varchar(45) DEFAULT NULL,
`zip` varchar(45) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
`country` varchar(45) DEFAULT NULL,
`state` varchar(45) DEFAULT NULL,
`about` text,
`tags` text,
`phone_private` varchar(100) NOT NULL,
`phone_work` varchar(100) NOT NULL,
`mobile` varchar(100) NOT NULL,
`fax` varchar(100) NOT NULL,
`language` varchar(5) NOT NULL,
`im_skype` varchar(100) NOT NULL,
`im_msn` varchar(100) NOT NULL,
`im_icq` varchar(100) NOT NULL,
`im_xmpp` varchar(100) NOT NULL,
`url` varchar(255) NOT NULL,
`url_facebook` varchar(255) NOT NULL,
`url_linkedin` varchar(255) NOT NULL,
`url_xing` varchar(255) NOT NULL,
`url_youtube` varchar(255) NOT NULL,
`url_vimeo` varchar(255) NOT NULL,
`url_flickr` varchar(255) NOT NULL,
`url_myspace` varchar(255) NOT NULL,
`url_googleplus` varchar(255) NOT NULL,
`url_twitter` varchar(255) NOT NULL,
`receive_email_notifications` tinyint(4) NOT NULL,
`receive_email_messaging` tinyint(4) NOT NULL,
`receive_email_activities` tinyint(4) NOT NULL,
`last_activity_email` datetime NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idUser_UNIQUE` (`id`),
UNIQUE KEY `email_UNIQUE` (`email`),
UNIQUE KEY `username_UNIQUE` (`username`),
UNIQUE KEY `idWall_UNIQUE` (`wall_id`),
UNIQUE KEY `idUserInvite_UNIQUE` (`user_invite_id`),
KEY `fk_user_group1` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_space_membership` (
`space_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`originator_user_id` varchar(45) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL COMMENT 'INVITED, APPLICANT, MEMBER',
`request_message` text,
`last_visit` datetime DEFAULT NULL,
`invite_role` tinyint(4) DEFAULT NULL,
`admin_role` tinyint(4) DEFAULT NULL,
`share_role` tinyint(4) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`space_id`,`user_id`),
KEY `fk_Group_has_User_User1` (`user_id`),
KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `wall` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(45) DEFAULT NULL COMMENT 'USER, WORKSPACE',
`object_model` varchar(50) NOT NULL,
`object_id` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `object_model` (`object_model`,`object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `wall_entry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`wall_id` int(11) NOT NULL,
`content_id` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_WallEntry_Wall1` (`wall_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zstunden_projekt_space` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`space_id` int(11) NOT NULL,
`projekt_nr` varchar(100) NOT NULL,
`created_at` datetime DEFAULT NULL,
`created_by` int(11) DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zstunden_timer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`projekt_nr` varchar(50) NOT NULL,
`projektname` varchar(255) NOT NULL,
`unterprojekt` varchar(255) NOT NULL,
`ansprechpartner` varchar(255) NOT NULL,
`pause_since` datetime NOT NULL,
`created_at` datetime NOT NULL,
`created_by` int(11) NOT NULL,
`updated_at` datetime NOT NULL,
`updated_by` int(11) NOT NULL,
`pause_total` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@ -0,0 +1,25 @@
Bundled Software / Libaries
===========================
* Yii Framework (Core Framework) http://www.yiiframework.com/
* Zend Framework (Lucene Index)
* Code Igniter (Security Functions)
* ADLdap (Active Directory / Ldap) http://adldap.sourceforge.net/
* Some Yii Extensions (See /protected/extensions/)
* PHP Markdown by by Michel Fortin (ZammDoc Module)
* Yii-Mail - http://www.yiiframework.com/extension/mail/
* SwiftMailer - http://swiftmailer.org
* jQuery - http://jquery.com
* jQuery Cookie Plugin - https://github.com/carhartl/jquery-cookie
* jQuery Knob - http://anthonyterrien.com/knob/
* Twitter Bootstrap - http://getbootstrap.com/
* Bootstrap-datepicker.js - http://www.eyecon.ro/bootstrap-datepicker
* Lightbox for Bootstrap 3 - https://github.com/ashleydw/lightbox
* Modernizr - http://modernizr.com/
* HTML5 Shiv - https://github.com/aFarkas/html5shiv
* Wysihtml5 - https://github.com/xing/wysihtml5
* Bootstrap-wysihtml5 - http://jhollingworth.github.io/bootstrap-wysihtml5/
* Autosize - http://www.jacklmoore.com/autosize
* Highlight - http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
* Timeago - http://timeago.yarp.com/

View File

@ -0,0 +1,9 @@
Console
=======
Zamm provides several console commands to manage the application.
Run ``./protected/yiic help`` for a full overview.
Make sure /protected/yiic or /protected/yiic.bat are executable.

View File

@ -0,0 +1,4 @@
CronJobs
========
See ``Administration -> Settings -> CronJobs`` for a complete list of required cronjobs.

View File

@ -0,0 +1,23 @@
Administration Guide/Notes
===========================
##Installation
- [Requirements](requirements.md)
- [Installer](installer.md)
- [Cronjobs](cronjobs.md)
##Updating
- [Updating](updating.md)
##Advanced Topics
- [Logging](logging.md)
- [Security](security.md)
- [Console](console.md)
- [Search](search.md)
- [X-Sendfile](xsendfile.md)
- [LDAP](ldap.md)
## More
- [Bundled Software](bundled_software.md)

View File

@ -0,0 +1,8 @@
Installation using the installer
=================================
1. Create a mysql database
2. Extract install package in a web/htdocs folder
3. Open that folder (e.g. http://localhost/humhub)
4. Installer will start

View File

@ -0,0 +1,47 @@
LDAP Support
============
This feature is highly experimental and requires PHP LDAP Support!
Configuration
--------------
Add following under ``protected/config/_settings.php`` in the ´´params -> auth`` array.
// LDAP Specifc Settings
'ldap' => array(
// User Group
'userGroup' => 'CN=office,CN=Users,DC=domain,DC=local',
// Account
'adminUser' => 'Admin User',
'adminPassword' => 'xxx',
// Connection String
'adldapConfig' => array('base_dn'=>'DC=domain,DC=local','account_suffix'=>'@domain.local', 'domain_controllers'=>array('localhost')),
// Mapping between LDAP Group and Space
'groupToSpaceMap' => array(
'CN=someGroup,CN=Users,DC=domain,DC=local' => 'Office',
// ...
),
// Field Sync (LDAP -> User Field)
'fieldMapping' => array(
'lastname' => array('ldapField'=>'sn', 'sync'=>'fromLdap'),
'firstname' => array('ldapField'=>'givenname', 'sync'=>'fromLdap'),
//'city' => array('ldapField'=>'givenname', 'sync'=>'full'),
//'state' => array('ldapField'=>'st', 'sync'=>'full'),
//'country' => array('ldapField'=>'c', 'sync'=>'fromLdap'),
//'country' => array('ldapField'=>'c', 'sync'=>'fromLdap'),
),
),
LDAP also needs a cronjob
# When using LDAP
45 * * * * /path/to/protected/protected/yiic ldap_update >/dev/null 2>&1

View File

@ -0,0 +1,4 @@
Logging
============
Log Files are stored unter ``protected/runtime/application.log``

View File

@ -0,0 +1,21 @@
Requirements
============
### General Requirements:
* PHP 5.2+
* MySQL
* Apache 2.x
* ImageMagick
* CUrl PHP Extension (For OEmbed Features)
### Packages for Debian/Ubuntu users:
* imagemagick
* php5-curl
* php5-mysql
* php5-gd
* php5-cli
* php5-ldap (optional)
* php-apc (optional)
* php5-memcached (optional)
* libapache2-mod-xsendfile (optional)

Some files were not shown because too many files have changed in this diff Show More