Merge branch 'storageareas' of github.com:/ConnorTechnology/ZoneMinder into storageareas
This commit is contained in:
commit
3d6efe2253
|
@ -17,6 +17,7 @@ In order to submit a bug report, please populate the fields below this line. Thi
|
|||
- Version of ZoneMinder [release version, development version, or commit]
|
||||
- How you installed ZoneMinder [e.g. PPA, RPMFusion, from-source, etc]
|
||||
- Full name and version of OS
|
||||
- Browser name and version (if this is an issue with the web interface)
|
||||
|
||||
**If the issue concerns a camera**
|
||||
- Make and Model
|
||||
|
|
|
@ -11,6 +11,7 @@ assignees: ''
|
|||
- Version of ZoneMinder [release version, development version, or commit]
|
||||
- How you installed ZoneMinder [e.g. PPA, RPMFusion, from-source, etc]
|
||||
- Full name and version of OS
|
||||
- Browser name and version (if this is an issue with the web interface)
|
||||
|
||||
**If the issue concerns a camera**
|
||||
- Make and Model
|
||||
|
|
10
AUTHORS
10
AUTHORS
|
@ -1,10 +0,0 @@
|
|||
ZoneMinder - A Linux based camera monitoring and analysis tool.
|
||||
|
||||
This project was imagined and created by Philip Coombes in
|
||||
September 2002, shortly after being burglarised of his power tools.
|
||||
He can be contacted at philip.coombes@zoneminder.com
|
||||
|
||||
In early 2013 after nearly two years of no development,
|
||||
the community reached out to Phil in an attempt to open up the
|
||||
project. With Phil's blessing, the code was migrated to github,
|
||||
and the community took over the project.
|
|
@ -1 +0,0 @@
|
|||
This is too hard to maintain. See https://github.com/ZoneMinder/ZoneMinder/commits/master
|
147
INSTALL
147
INSTALL
|
@ -1,147 +0,0 @@
|
|||
Installing ZoneMinder with cmake
|
||||
--------------------------------
|
||||
Starting with ZoneMinder 1.26.4, ZoneMinder can now be installed using cmake. This requires cmake version 2.6 or newer.
|
||||
cmake is an alternative to the autotools collection (libtool, autoconf, automake, autoheader and such). Its more recent and has many advantages, including, but not limited to:
|
||||
* One program (cmake) instead of multiple. (libtool, autoconf, automake, etc)
|
||||
* One file per directory (CMakeLists.txt) instead of multiple. (configure.ac, Makefile.am and sometimes more)
|
||||
* One syntax (cmake's syntax) instead of multiple. (bash and m4)
|
||||
* Generation of makefiles for many platforms, including Windows.
|
||||
* Newer than autotools and is being actively developed.
|
||||
* Generates colored makefiles with progress indicator.
|
||||
* Slightly faster because its based on C and not bash.
|
||||
* Lots of documentation, unlike autotools: http://www.cmake.org/cmake/help/cmake2.6docs.html
|
||||
|
||||
At this point, its still possible to use autotools for the ZoneMinder project. Choosing cmake or autotools is now a matter of preference.
|
||||
Hopefully in the future, cmake will become the default way to install ZoneMinder.
|
||||
|
||||
Important differences
|
||||
---------------------
|
||||
* Unlike the autotools way, the cmake way does not require any options. It attempts to detect some things by its own (system directories, libarch, web user and group) and uses defaults for others (installation paths and such).
|
||||
* Unlike the autotools way, which links the binaries to a fixed list of libraries, the cmake way only links to libraries that it found on the system. If a library is not found, but required, a fatal error will be shown during the configuration step.
|
||||
* Unlike the autotools way, the cmake way does not modify the system in any way it shouldn't. It only does what its supposed to do: Install files to your system. Nothing else and nothing leaks out of the DESTDIR environment variable (if used). This means that depending on your configuration, there might be an extra required step after installation: to link WEB_PATH/events and WEB_PATH/images folders to the correct places.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
cmake by default does not require any parameters, but its possible to override the defaults with the options below.
|
||||
|
||||
Configuration can be done in 4 ways:
|
||||
1) As a command line parameter, e.g. cmake -DCMAKE_VERBOSE_MAKEFILE=ON .
|
||||
2) Using cmake-gui
|
||||
3) Providing cmake with an initial cache file with the -C option
|
||||
IMPORTANT: Do not use the -C option if any major part of your system, excluding the version of zoneminder, has changed.
|
||||
For example, do not use this option if: you have upgraded your distro to a new version, have gone from 32 to 64 bits,
|
||||
or have migrated from one machine to another.
|
||||
4) By editing the cache file CMakeCache.txt (after it has been generated) - Not recommended
|
||||
|
||||
Possible configuration options:
|
||||
ZM_RUNDIR Location of transient process files, default: /var/run/zm
|
||||
ZM_SOCKDIR Location of Unix domain socket files, default /var/run/zm
|
||||
ZM_TMPDIR Location of temporary files, default: /tmp/zm
|
||||
ZM_LOGDIR Location of generated log files, default: /var/log/zm
|
||||
ZM_WEBDIR Location of the web files, default: <prefix>/share/zoneminder/www
|
||||
ZM_CGIDIR Location of the cgi-bin files, default: <prefix>/libexec/zoneminder/cgi-bin
|
||||
ZM_CONTENTDIR Location of dynamic content (events and images), default: /var/lib/zoneminder
|
||||
ZM_DB_HOST Hostname where ZoneMinder database located, default: localhost
|
||||
ZM_DB_NAME Name of ZoneMinder database, default: zm
|
||||
ZM_DB_USER Name of ZoneMinder database user, default: zmuser
|
||||
ZM_DB_PASS Password of ZoneMinder database user, default: zmpass
|
||||
ZM_DB_SSL_CA_CERT Path to SSL CA certificate, default: empty; SSL not enabled
|
||||
ZM_DB_SSL_CLIENT_KEY Path to SSL client key, default: empty; SSL not enabled
|
||||
ZM_DB_SSL_CLIENT_CERT Path to SSL client certificate, default: empty; SSL not enabled
|
||||
ZM_WEB_USER The user apache or the local web server runs on. Leave empty for automatic detection. If that fails, you can use this variable to force
|
||||
ZM_WEB_GROUP The group apache or the local web server runs on, Leave empty to be the same as the web user
|
||||
ZM_DIR_EVENTS Location where events are recorded to, default: ZM_CONTENTDIR/events
|
||||
ZM_DIR_SOUNDS Location to look for optional sound files, default: sounds
|
||||
ZM_PATH_ZMS Web url to zms streaming server, default: /cgi-bin/nph-zms
|
||||
Advanced:
|
||||
ZM_PATH_MAP Location to save mapped memory files, default: /dev/shm
|
||||
ZM_PATH_ARP Full path to compatible arp binary. Leave empty for automatic detection.
|
||||
ZM_CONFIG_DIR Location of the main ZoneMinder config file, zm.conf. default: /etc/zm
|
||||
ZM_CONFIG_SUBDIR Location of custom config files. default: ZM_CONFIG_DIR/conf.d
|
||||
ZM_EXTRA_LIBS A list of optional libraries, separated by semicolons, e.g. ssl;theora
|
||||
ZM_MYSQL_ENGINE MySQL engine to use with database, default: InnoDB
|
||||
ZM_NO_MMAP Set to ON to not use mmap shared memory. Shouldn't be enabled unless you experience problems with the shared memory. default: OFF
|
||||
ZM_NO_X10 Set to ON to build ZoneMinder without X10 support. default: OFF
|
||||
ZM_PERL_MM_PARMS By default, ZoneMinder's Perl modules are installed into the Vendor folders, as defined by your installation of Perl. You can change that here. Consult Perl's MakeMaker documentation for a definition of acceptable parameters. If you set this to something that causes the modules to be installed outside Perl's normal serach path, then you will also need to set ZM_PERL_SEARCH_PATH accordingly. default: "INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1"
|
||||
ZM_PERL_SEARCH_PATH Use to add a folder to your Perl's search path. This will need to be set in cases where ZM_PERL_MM_PARMS has been modified such that ZoneMinder's Perl modules are installed outside Perl's default search path. default: ""
|
||||
|
||||
Useful configuration options provided by cmake:
|
||||
CMAKE_VERBOSE_MAKEFILE - Set this to ON (default OFF) to see what cmake is doing. Very useful for troubleshooting.
|
||||
CMAKE_BUILD_TYPE - Set this to Debug (default Release) to build ZoneMinder with debugging enabled.
|
||||
CMAKE_INSTALL_PREFIX - Use this to change the prefix (default /usr/local). This option behaves like --prefix from autoconf. Package maintainers will probably want to set this to "/usr".
|
||||
|
||||
Useful environment variables provided by cmake:
|
||||
CMAKE_INCLUDE_PATH - Use this to add to the include search path.
|
||||
CMAKE_LIBRARY_PATH - Use this to add to the library search path.
|
||||
CMAKE_PREFIX_PATH - Use this to add to both include and library search paths. <path>/include will be added to the include search path and <path>/lib to the library search path. Multiple paths can be specified, separated by a : character. For example: export CMAKE_PREFIX_PATH="/opt/libjpeg-turbo:/opt/ffmpeg-from-git"
|
||||
|
||||
CFLAGS, CPPFLAGS and other environment variables:
|
||||
To append to the CFLAGS and CXXFLAGS, please use the CFLAGS and CXXFLAGS environment variables.
|
||||
Or use the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS configuration options.
|
||||
To replace the CFLAGS and CXXFLAGS entirely:
|
||||
* For the Release build type: use CMAKE_C_FLAGS_RELEASE for the CFLAGS and CMAKE_CXX_FLAGS_RELEASE for the CXXFLAGS
|
||||
* For the Debug build type: use CMAKE_C_FLAGS_DEBUG for the CFLAGS and CMAKE_CXX_FLAGS_DEBUG for the CXXFLAGS
|
||||
Other important environment variables (such as LDFLAGS) are also supported.
|
||||
|
||||
The DESTDIR environment variable is also supported, however it needs to be set before invoking make install. For example: DESTDIR=mydestdir make install
|
||||
For more information about DESTDIR, see:
|
||||
* http://www.gnu.org/prep/standards/html_node/DESTDIR.html
|
||||
|
||||
Basic steps for installing ZoneMinder on a fresh system
|
||||
-------------------------------------------------------
|
||||
1) After installing all the required dependencies, in the project directory, run "cmake [extra options] ."
|
||||
This behaves like ./configure. It is also possible to supply configuration options, e.g. cmake -DZM_DB_PASS="mypass" .
|
||||
IMPORTANT: Don't forget the dot "." at the end.
|
||||
2) Run "make" to compile ZoneMinder
|
||||
3) Run "make install" (as root, or use sudo) to install ZoneMinder to your system.
|
||||
4) Create a directory for the content and the necessary symlinks by running zmlinkcontent.sh with the directory you want to use. e.g. ./zmlinkcontent.sh /nfs/zm
|
||||
5) Create a database for zoneminder, called "zm".
|
||||
6) Create a user for the zoneminder database, called zmuser with password and full privileges to the "zm" database.
|
||||
NOTE: The database server, database name, user and password can be different and adjusted during configuration step with the options in this file, or by editing /etc/zm.conf
|
||||
7) Populate the zoneminder database using the script zm_create.sql. This should be found in <prefix>/share/zoneminder/db or in the project/db directory.
|
||||
|
||||
8) Create an apache virtual host for ZoneMinder. Make sure to use the same paths as ZM_WEBDIR and ZM_CGIDIR in /etc/zm.conf
|
||||
9) Verify date.timezone is set to your timezone. This parameter is often found inside the system php.ini file. Consult your distribution's documentation for the proper way to set this value.
|
||||
10) Create other config if desired (e.g. rsyslog, logrotate and such). Some of this can be found in <prefix>/share/zoneminder/misc or project/misc directory
|
||||
11) Setup an appropriate startup script for your system. Two generic startup scripts have been provided, a legacy Sys V Init script and a Systemd service file.
|
||||
|
||||
*Sys V Init Setup*
|
||||
- Copy the sys v init script /scripts/zm from the build folder to /etc/init.
|
||||
- Inspect the contents to make sure they apply to your distro.
|
||||
|
||||
*SystemD Setup*
|
||||
- Copy the zoneminder systemd service file /misc/zoneminder.service from the build folder to the systemd service file location.
|
||||
For Redhat based distros, that folder is /usr/lib/systemd/system.
|
||||
- Inspect the contents to make sure they apply to your distro.
|
||||
- Tell systemd to load the new service file: "sudo systemctl daemon-reload".
|
||||
- Copy /misc/zoneminder-tmpfiles.conf to /etc/tmpfiles.d
|
||||
- Tell systemd to process this file: "sudo /usr/bin/systemd-tmpfiles --create /etc/tmpfiles.d/zoneminder.conf".
|
||||
|
||||
Basic steps for upgrading ZoneMinder
|
||||
------------------------------------
|
||||
1) If you wish to use the same paths and configuration as the currently installed ZoneMinder, you need to provide cmake with options that match your current installation.
|
||||
You can provide those options in the command line to cmake, e.g. cmake -DZM_DB_PASS="blah" -DZM_WEBDIR="/usr/local/share/zoneminder/www" -DCMAKE_INSTALL_FULL_BINDIR="/usr/bin" .
|
||||
Or alternatively, for convenience, use the cmakecacheimport.sh script. This reads a zoneminder configuration file (zm.conf) and creates a cmake initial cache file called zm_conf.cmake, which you can then provide to cmake.
|
||||
For example:
|
||||
./cmakecacheimport.sh /etc/zm.conf
|
||||
cmake -C zm_conf.cmake [extra options] .
|
||||
|
||||
2) Run "make" to compile ZoneMinder
|
||||
3) Run "make install" (as root, or use sudo) to install ZoneMinder to your system.
|
||||
4) Depending on your configuration: If DIR_EVENTS is set to default, You will need to update the symlinks in the web directory to the correct folders. e.g. web directory/events should point to the real events directory.
|
||||
You can use the zmlinkcontent.sh script for this. For example, if /var/lib/zoneminder is the folder that contains the "events" directory, you can use:
|
||||
./zmlinkcontent.sh /var/lib/zoneminder
|
||||
By default, the content directory for new installations is /var/lib/zoneminder. This can be overridden in cmake with the ZM_CONTENTDIR option. e.g. cmake -DZM_CONTENTDIR="/some/big/storage/zm" .
|
||||
|
||||
5) Run zmupdate.pl to update the database layout to the new version.
|
||||
|
||||
Uninstallation:
|
||||
---------------
|
||||
By default, cmake does not have an uninstall target, however we have added a one. Simply run make uninstall (or DESTDIR=mydestdir make uninstall if a DESTDIR was used) and it will remove all the files that cmake installed.
|
||||
It's also possible to do this manually. The file install_manifest.txt contains the list of files installed to the system. This can be used in many ways to delete all files installed by cmake, such as: xargs rm < install_manifest.txt
|
||||
|
||||
Contributions:
|
||||
--------------
|
||||
Please visit our GitHub at http://github.com/ZoneMinder/ZoneMinder
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
Zoneminder with kfir performances patches and fixes from UnixMedia (nextime)
|
|
@ -1,6 +0,0 @@
|
|||
ZoneMinder - A Linux based camera monitoring and analysis tool.
|
||||
|
||||
This project was imagined and created by Philip Coombes in
|
||||
September 2002, shortly after being burglarised of his power tools.
|
||||
|
||||
mailto:philip.coombes@zoneminder.com
|
|
@ -1 +0,0 @@
|
|||
Please see README file.
|
340
doc-pak/COPYING
340
doc-pak/COPYING
|
@ -1,340 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -1 +0,0 @@
|
|||
Please see README file.
|
185
doc-pak/INSTALL
185
doc-pak/INSTALL
|
@ -1,185 +0,0 @@
|
|||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
Please see http://www.zoneminder.com/wiki/index.php/Documentation
|
||||
for full details.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
|
@ -1 +0,0 @@
|
|||
Please see README file.
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
All documentation for ZoneMinder is now online at
|
||||
|
||||
http://www.zoneminder.com/wiki/index.php/Documentation
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Please see README file.
|
||||
|
|
@ -3,6 +3,205 @@ Ubuntu
|
|||
|
||||
.. contents::
|
||||
|
||||
Easy Way: Ubuntu 18.04
|
||||
----------------------
|
||||
These instructions are for a brand new ubuntu 18.04 system which does not have ZM
|
||||
installed.
|
||||
|
||||
|
||||
It is recommended that you use an Ubuntu Server install and select the LAMP option
|
||||
during install to install Apache, MySQL and PHP. If you failed to do this you can
|
||||
achieve the same result by running:
|
||||
|
||||
::
|
||||
|
||||
sudo tasksel install lamp-server
|
||||
|
||||
During installation it will ask you to set up a master/root password for the MySQL.
|
||||
Installing LAMP is not ZoneMinder specific so you will find plenty of resources to
|
||||
guide you with a quick search.
|
||||
|
||||
**Step 1:** Either run commands in this install using sudo or use the below to become root
|
||||
::
|
||||
|
||||
sudo -i
|
||||
|
||||
**Step 2:** Update Repos
|
||||
|
||||
.. topic :: Latest Release
|
||||
|
||||
ZoneMinder is now part of the current standard Ubuntu repository, but
|
||||
sometimes the official repository can lag behind. To find out check our
|
||||
`releases page <https://github.com/ZoneMinder/zoneminder/releases>`_ for
|
||||
the latest release.
|
||||
|
||||
Alternatively, the ZoneMinder project team maintains a `PPA <https://askubuntu.com/questions/4983/what-are-ppas-and-how-do-i-use-them>`_, which is updated immediately
|
||||
following a new release of ZoneMinder. To use this repository instead of the
|
||||
official Ubuntu repository, enter the following from the command line:
|
||||
|
||||
::
|
||||
|
||||
add-apt-repository ppa:iconnor/zoneminder
|
||||
|
||||
Please note that as of 1.32.0 We are creating a new PPA for each major version, as a means to prevent automatic upgrades from one major version to another. So instead of the above ppa line use the following:
|
||||
|
||||
::
|
||||
|
||||
add-apt-repository ppa:iconnor/zoneminder-1.32
|
||||
|
||||
If you are on Trusty or Xenial, you may want to add both, as there are some packages for dependencies included in the old ppa.
|
||||
|
||||
|
||||
Update repo and upgrade.
|
||||
|
||||
::
|
||||
|
||||
apt-get update
|
||||
apt-get upgrade
|
||||
apt-get dist-upgrade
|
||||
|
||||
|
||||
**Step 3:** Configure MySQL
|
||||
|
||||
.. sidebar :: Note
|
||||
|
||||
The MySQL default configuration file (/etc/mysql/mysql.cnf)is read through
|
||||
several symbolic links beginning with /etc/mysql/my.cnf as follows:
|
||||
|
||||
| /etc/mysql/my.cnf -> /etc/alternatives/my.cnf
|
||||
| /etc/alternatives/my.cnf -> /etc/mysql/mysql.cnf
|
||||
| /etc/mysql/mysql.cnf is a basic file
|
||||
|
||||
Certain new defaults in MySQL 5.7 cause some issues with ZoneMinder < 1.32.0,
|
||||
the workaround is to modify the sql_mode setting of MySQL. Please note that these
|
||||
changes are NOT required for ZoneMinder 1.32.0 and some people have reported them
|
||||
causing problems in 1.32.0.
|
||||
|
||||
To better manage the MySQL server it is recommended to copy the sample config file and
|
||||
replace the default my.cnf symbolic link.
|
||||
|
||||
::
|
||||
|
||||
rm /etc/mysql/my.cnf (this removes the current symbolic link)
|
||||
cp /etc/mysql/mysql.conf.d/mysqld.cnf /etc/mysql/my.cnf
|
||||
|
||||
To change MySQL settings:
|
||||
|
||||
::
|
||||
|
||||
nano /etc/mysql/my.cnf
|
||||
|
||||
In the [mysqld] section add the following
|
||||
|
||||
::
|
||||
|
||||
sql_mode = NO_ENGINE_SUBSTITUTION
|
||||
|
||||
CTRL+o then [Enter] to save
|
||||
|
||||
CTRL+x to exit
|
||||
|
||||
Restart MySQL
|
||||
|
||||
::
|
||||
|
||||
systemctl restart mysql
|
||||
|
||||
|
||||
**Step 4:** Install ZoneMinder
|
||||
|
||||
::
|
||||
|
||||
apt-get install zoneminder
|
||||
|
||||
**Step 5:** Configure the ZoneMinder Database
|
||||
|
||||
This step should not be required on ZoneMinder 1.32.0.
|
||||
|
||||
::
|
||||
|
||||
mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
|
||||
mysql -uroot -p -e "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on zm.* to 'zmuser'@localhost identified by 'zmpass';"
|
||||
|
||||
|
||||
**Step 6:** Set permissions
|
||||
|
||||
Set /etc/zm/zm.conf to root:www-data 740 and www-data access to content
|
||||
|
||||
::
|
||||
|
||||
chmod 740 /etc/zm/zm.conf
|
||||
chown root:www-data /etc/zm/zm.conf
|
||||
chown -R www-data:www-data /usr/share/zoneminder/
|
||||
|
||||
**Step 7:** Configure Apache correctly:
|
||||
|
||||
::
|
||||
|
||||
a2enmod cgi
|
||||
a2enmod rewrite
|
||||
a2enconf zoneminder
|
||||
|
||||
You may also want to enable to following modules to improve caching performance
|
||||
|
||||
::
|
||||
|
||||
a2enmod expires
|
||||
a2enmod headers
|
||||
|
||||
**Step 8:** Enable and start Zoneminder
|
||||
|
||||
::
|
||||
|
||||
systemctl enable zoneminder
|
||||
systemctl start zoneminder
|
||||
|
||||
**Step 9:** Edit Timezone in PHP
|
||||
|
||||
::
|
||||
|
||||
nano /etc/php/7.2/apache2/php.ini
|
||||
|
||||
Search for [Date] (Ctrl + w then type Date and press Enter) and change
|
||||
date.timezone for your time zone, see [this](http://php.net/manual/en/timezones.php).
|
||||
**Don't forget to remove the ; from in front of date.timezone**
|
||||
|
||||
::
|
||||
|
||||
[Date]
|
||||
; Defines the default timezone used by the date functions
|
||||
; http://php.net/date.timezone
|
||||
date.timezone = America/New_York
|
||||
|
||||
CTRL+o then [Enter] to save
|
||||
|
||||
CTRL+x to exit
|
||||
|
||||
**Step 10:** Reload Apache service
|
||||
|
||||
::
|
||||
|
||||
systemctl reload apache2
|
||||
|
||||
**Step 11:** Making sure ZoneMinder works
|
||||
|
||||
1. Open up a browser and go to ``http://hostname_or_ip/zm`` - should bring up ZoneMinder Console
|
||||
|
||||
2. (Optional API Check)Open up a tab in the same browser and go to ``http://hostname_or_ip/zm/api/host/getVersion.json``
|
||||
|
||||
If it is working correctly you should get version information similar to the example below:
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"version": "1.29.0",
|
||||
"apiversion": "1.29.0.1"
|
||||
}
|
||||
|
||||
**Congratulations** Your installation is complete
|
||||
|
||||
PPA install may need some tweaking of ZMS_PATH in ZoneMinder options. `Socket_sendto or no live streaming`_
|
||||
|
||||
Easy Way: Ubuntu 16.04
|
||||
----------------------
|
||||
These instructions are for a brand new ubuntu 16.04 system which does not have ZM
|
||||
|
|
|
@ -257,7 +257,7 @@ sub saveConfigToDB {
|
|||
$option->{category},
|
||||
$option->{readonly} ? 1 : 0,
|
||||
$option->{db_requires}
|
||||
) or croak( "Can't execute: ".$sth->errstr() );
|
||||
) or croak("Can't execute when updating config entry $$option{name}: ".$sth->errstr() );
|
||||
} # end foreach option
|
||||
$sth->finish();
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ our @options = (
|
|||
},
|
||||
{
|
||||
name => 'ZM_ENABLE_CSRF_MAGIC',
|
||||
default => 'no',
|
||||
default => 'yes',
|
||||
description => 'Enable csrf-magic library',
|
||||
help => q`
|
||||
CSRF stands for Cross-Site Request Forgery which, under specific
|
||||
|
@ -375,11 +375,7 @@ our @options = (
|
|||
this, the attacker must write a very specific web page and get
|
||||
you to navigate to it, while you are logged into the ZoneMinder
|
||||
web console at the same time. Enabling ZM_ENABLE_CSRF_MAGIC will
|
||||
help mitigate these kinds of attackes. Be warned this feature
|
||||
is experimental and may cause problems, particularly with the API.
|
||||
If you find a false positive and can document how to reproduce it,
|
||||
then please report it. This feature defaults to OFF currently due to
|
||||
its experimental nature.
|
||||
help mitigate these kinds of attacks.
|
||||
`,
|
||||
type => $types{boolean},
|
||||
category => 'system',
|
||||
|
@ -3035,7 +3031,7 @@ our @options = (
|
|||
},
|
||||
{
|
||||
name => 'ZM_WEB_H_REFRESH_NAVBAR',
|
||||
default => '5',
|
||||
default => '60',
|
||||
description => 'How often (in seconds) the navigation header should refresh itself',
|
||||
help => q`
|
||||
The navigation header contains the general status information about server load and storage space.
|
||||
|
@ -3308,7 +3304,7 @@ our @options = (
|
|||
},
|
||||
{
|
||||
name => 'ZM_WEB_M_REFRESH_NAVBAR',
|
||||
default => '15',
|
||||
default => '120',
|
||||
description => 'How often (in seconds) the navigation header should refresh itself',
|
||||
help => q`
|
||||
The navigation header contains the general status information about server load and storage space.
|
||||
|
@ -3581,7 +3577,7 @@ our @options = (
|
|||
},
|
||||
{
|
||||
name => 'ZM_WEB_L_REFRESH_NAVBAR',
|
||||
default => '35',
|
||||
default => '180',
|
||||
description => 'How often (in seconds) the navigation header should refresh itself',
|
||||
help => q`
|
||||
The navigation header contains the general status information about server load and storage space.
|
||||
|
@ -3941,6 +3937,14 @@ our @options = (
|
|||
type => $types{string},
|
||||
category => 'mail',
|
||||
},
|
||||
{
|
||||
name => 'ZM_COOKIE_LIFETIME',
|
||||
default => '3600',
|
||||
description => q`The maximum life of a COOKIE used when setting up PHP's session handler.`,
|
||||
help => q`This will affect how long a session will be valid for since the last request. Keeping this short helps prevent session hijacking. Keeping it long allows you to stay logged in longer without refreshing the view.`,
|
||||
type => $types{integer},
|
||||
category => 'system',
|
||||
}
|
||||
);
|
||||
|
||||
our %options_hash = map { ( $_->{name}, $_ ) } @options;
|
||||
|
|
|
@ -147,7 +147,8 @@ sub Sql {
|
|||
if ( $filter_expr->{terms} ) {
|
||||
foreach my $term ( @{$filter_expr->{terms}} ) {
|
||||
|
||||
if ( exists($term->{cnj}) ) {
|
||||
# See getFilterQueryConjunctionTypes()
|
||||
if ( exists($term->{cnj}) and $term->{cnj} =~ /^(and|or)$/ ) {
|
||||
$self->{Sql} .= ' '.$term->{cnj}.' ';
|
||||
}
|
||||
if ( exists($term->{obr}) ) {
|
||||
|
|
|
@ -285,7 +285,11 @@ void zm_dump_frame(const AVFrame *frame,const char *text) {
|
|||
av_get_sample_fmt_name((AVSampleFormat)frame->format),
|
||||
frame->sample_rate,
|
||||
frame->nb_samples,
|
||||
#if LIBAVCODEC_VERSION_CHECK(56, 8, 0, 60, 100)
|
||||
frame->channels,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
frame->channel_layout
|
||||
);
|
||||
}
|
||||
|
|
|
@ -62,16 +62,16 @@ Storage::Storage( unsigned int p_id ) {
|
|||
|
||||
if ( p_id ) {
|
||||
char sql[ZM_SQL_SML_BUFSIZ];
|
||||
snprintf( sql, sizeof(sql), "SELECT Id, Name, Path, Type, Scheme from Storage WHERE Id=%d", p_id );
|
||||
snprintf(sql, sizeof(sql), "SELECT Id, Name, Path, Type, Scheme FROM Storage WHERE Id=%d", p_id);
|
||||
Debug(2,"Loading Storage for %d using %s", p_id, sql );
|
||||
zmDbRow dbrow;
|
||||
if ( ! dbrow.fetch( sql ) ) {
|
||||
Error( "Unable to load storage area for id %d: %s", p_id, mysql_error( &dbconn ) );
|
||||
if ( !dbrow.fetch(sql) ) {
|
||||
Error("Unable to load storage area for id %d: %s", p_id, mysql_error(&dbconn));
|
||||
} else {
|
||||
unsigned int index = 0;
|
||||
id = atoi( dbrow[index++] );
|
||||
strncpy( name, dbrow[index++], sizeof(name)-1 );
|
||||
strncpy( path, dbrow[index++], sizeof(path)-1 );
|
||||
id = atoi(dbrow[index++]);
|
||||
strncpy(name, dbrow[index++], sizeof(name)-1);
|
||||
strncpy(path, dbrow[index++], sizeof(path)-1);
|
||||
type_str = std::string(dbrow[index++]);
|
||||
scheme_str = std::string(dbrow[index++]);
|
||||
if ( scheme_str == "Deep" ) {
|
||||
|
@ -81,17 +81,17 @@ Storage::Storage( unsigned int p_id ) {
|
|||
} else {
|
||||
scheme = SHALLOW;
|
||||
}
|
||||
Debug( 1, "Loaded Storage area %d '%s'", id, this->Name() );
|
||||
Debug(1, "Loaded Storage area %d '%s'", id, this->Name());
|
||||
}
|
||||
}
|
||||
if ( ! id ) {
|
||||
if ( !id ) {
|
||||
if ( staticConfig.DIR_EVENTS[0] != '/' ) {
|
||||
// not using an absolute path. Make it one by appending ZM_PATH_WEB
|
||||
snprintf( path, sizeof (path), "%s/%s", staticConfig.PATH_WEB.c_str( ), staticConfig.DIR_EVENTS.c_str() );
|
||||
snprintf(path, sizeof (path), "%s/%s", staticConfig.PATH_WEB.c_str(), staticConfig.DIR_EVENTS.c_str());
|
||||
} else {
|
||||
strncpy(path, staticConfig.DIR_EVENTS.c_str(), sizeof(path)-1 );
|
||||
strncpy(path, staticConfig.DIR_EVENTS.c_str(), sizeof(path)-1);
|
||||
}
|
||||
Debug(1,"No id passed to Storage constructor. Using default path %s instead", path );
|
||||
Debug(1,"No id passed to Storage constructor. Using default path %s instead", path);
|
||||
strcpy(name, "Default");
|
||||
scheme = MEDIUM;
|
||||
scheme_str = "Medium";
|
||||
|
|
|
@ -89,18 +89,21 @@ bool User::canAccess( int monitor_id ) {
|
|||
// Please note that in auth relay mode = none, password is NULL
|
||||
User *zmLoadUser( const char *username, const char *password ) {
|
||||
char sql[ZM_SQL_MED_BUFSIZ] = "";
|
||||
char safer_username[65]; // current db username size is 32
|
||||
int username_length = strlen(username);
|
||||
char *safer_username = new char[(username_length * 2) + 1];
|
||||
|
||||
// According to docs, size of safer_whatever must be 2*length+1 due to unicode conversions + null terminator.
|
||||
mysql_real_escape_string(&dbconn, safer_username, username, strlen( username ) );
|
||||
mysql_real_escape_string(&dbconn, safer_username, username, username_length );
|
||||
|
||||
if ( password ) {
|
||||
char safer_password[129]; // current db password size is 64
|
||||
mysql_real_escape_string(&dbconn, safer_password, password, strlen( password ) );
|
||||
int password_length = strlen(password);
|
||||
char *safer_password = new char[(password_length * 2) + 1];
|
||||
mysql_real_escape_string(&dbconn, safer_password, password, password_length);
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds"
|
||||
" FROM Users WHERE Username = '%s' AND Password = password('%s') AND Enabled = 1",
|
||||
safer_username, safer_password );
|
||||
delete safer_password;
|
||||
} else {
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds"
|
||||
|
@ -131,6 +134,7 @@ User *zmLoadUser( const char *username, const char *password ) {
|
|||
Info("Authenticated user '%s'", user->getUsername());
|
||||
|
||||
mysql_free_result(result);
|
||||
delete safer_username;
|
||||
|
||||
return user;
|
||||
}
|
||||
|
|
|
@ -31,17 +31,21 @@ extern "C" {
|
|||
#include "libavutil/time.h"
|
||||
}
|
||||
|
||||
VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
||||
AVStream *p_video_in_stream,
|
||||
AVStream *p_audio_in_stream, int64_t nStartTime,
|
||||
Monitor *monitor) {
|
||||
VideoStore::VideoStore(
|
||||
const char *filename_in,
|
||||
const char *format_in,
|
||||
AVStream *p_video_in_stream,
|
||||
AVStream *p_audio_in_stream,
|
||||
int64_t nStartTime,
|
||||
Monitor *monitor
|
||||
) {
|
||||
video_in_stream = p_video_in_stream;
|
||||
audio_in_stream = p_audio_in_stream;
|
||||
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
video_in_ctx = avcodec_alloc_context3(NULL);
|
||||
avcodec_parameters_to_context(video_in_ctx,
|
||||
video_in_stream->codecpar);
|
||||
avcodec_parameters_to_context(video_in_ctx, video_in_stream->codecpar);
|
||||
video_in_ctx->time_base = video_in_stream->time_base;
|
||||
// zm_dump_codecpar( video_in_stream->codecpar );
|
||||
#else
|
||||
video_in_ctx = video_in_stream->codec;
|
||||
|
@ -91,18 +95,17 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
video_out_ctx = avcodec_alloc_context3(NULL);
|
||||
|
||||
// Copy params from instream to ctx
|
||||
ret = avcodec_parameters_to_context(video_out_ctx,
|
||||
video_in_stream->codecpar);
|
||||
if (ret < 0) {
|
||||
Error("Could not initialize ctx parameteres");
|
||||
ret = avcodec_parameters_to_context(video_out_ctx, video_in_stream->codecpar);
|
||||
if ( ret < 0 ) {
|
||||
Error("Could not initialize video_out_ctx parameters");
|
||||
return;
|
||||
} else {
|
||||
zm_dump_codec(video_out_ctx);
|
||||
}
|
||||
|
||||
video_out_stream = avformat_new_stream(oc, NULL);
|
||||
if (!video_out_stream) {
|
||||
Error("Unable to create video out stream\n");
|
||||
if ( !video_out_stream ) {
|
||||
Error("Unable to create video out stream");
|
||||
return;
|
||||
} else {
|
||||
Debug(2, "Success creating video out stream");
|
||||
|
@ -117,7 +120,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
// Now copy them to the out stream
|
||||
ret = avcodec_parameters_from_context(video_out_stream->codecpar,
|
||||
video_out_ctx);
|
||||
if (ret < 0) {
|
||||
if ( ret < 0 ) {
|
||||
Error("Could not initialize stream parameteres");
|
||||
return;
|
||||
} else {
|
||||
|
@ -143,7 +146,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
} else {
|
||||
Debug(3, "Success copying ctx");
|
||||
}
|
||||
if (!video_out_ctx->codec_tag) {
|
||||
if ( !video_out_ctx->codec_tag ) {
|
||||
Debug(2, "No codec_tag");
|
||||
if (!oc->oformat->codec_tag ||
|
||||
av_codec_get_id(oc->oformat->codec_tag,
|
||||
|
@ -182,17 +185,17 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
}
|
||||
|
||||
Monitor::Orientation orientation = monitor->getOrientation();
|
||||
if (orientation) {
|
||||
if (orientation == Monitor::ROTATE_0) {
|
||||
if ( orientation ) {
|
||||
if ( orientation == Monitor::ROTATE_0 ) {
|
||||
} else if (orientation == Monitor::ROTATE_90) {
|
||||
dsr = av_dict_set(&video_out_stream->metadata, "rotate", "90", 0);
|
||||
if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__);
|
||||
} else if (orientation == Monitor::ROTATE_180) {
|
||||
if ( dsr < 0 ) Warning("%s:%d: title set failed", __FILE__, __LINE__);
|
||||
} else if ( orientation == Monitor::ROTATE_180 ) {
|
||||
dsr = av_dict_set(&video_out_stream->metadata, "rotate", "180", 0);
|
||||
if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__);
|
||||
} else if (orientation == Monitor::ROTATE_270) {
|
||||
if ( dsr < 0 ) Warning("%s:%d: title set failed", __FILE__, __LINE__);
|
||||
} else if ( orientation == Monitor::ROTATE_270 ) {
|
||||
dsr = av_dict_set(&video_out_stream->metadata, "rotate", "270", 0);
|
||||
if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__);
|
||||
if ( dsr < 0 ) Warning("%s:%d: title set failed", __FILE__, __LINE__);
|
||||
} else {
|
||||
Warning("Unsupported Orientation(%d)", orientation);
|
||||
}
|
||||
|
@ -209,13 +212,14 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
resample_ctx = NULL;
|
||||
#endif
|
||||
|
||||
if (audio_in_stream) {
|
||||
if ( audio_in_stream ) {
|
||||
Debug(3, "Have audio stream");
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
|
||||
|
||||
audio_in_ctx = avcodec_alloc_context3(NULL);
|
||||
ret = avcodec_parameters_to_context(audio_in_ctx,
|
||||
audio_in_stream->codecpar);
|
||||
audio_in_ctx->time_base = audio_in_stream->time_base;
|
||||
#else
|
||||
audio_in_ctx = audio_in_stream->codec;
|
||||
#endif
|
||||
|
@ -225,7 +229,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
|
|||
avcodec_string(error_buffer, sizeof(error_buffer), audio_in_ctx, 0);
|
||||
Debug(2, "Got something other than AAC (%s)", error_buffer);
|
||||
|
||||
if (!setup_resampler()) {
|
||||
if ( !setup_resampler() ) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -541,6 +545,7 @@ bool VideoStore::setup_resampler() {
|
|||
// Some formats (i.e. WAV) do not produce the proper channel layout
|
||||
if ( audio_in_ctx->channel_layout == 0 ) {
|
||||
Debug(2, "Setting input channel layout to mono");
|
||||
// Perhaps we should not be modifying the audio_in_ctx....
|
||||
audio_in_ctx->channel_layout = av_get_channel_layout("mono");
|
||||
}
|
||||
|
||||
|
@ -635,10 +640,10 @@ bool VideoStore::setup_resampler() {
|
|||
|
||||
#if defined(HAVE_LIBSWRESAMPLE)
|
||||
resample_ctx = swr_alloc_set_opts(NULL,
|
||||
av_get_default_channel_layout(audio_out_ctx->channels),
|
||||
audio_out_ctx->channel_layout,
|
||||
audio_out_ctx->sample_fmt,
|
||||
audio_out_ctx->sample_rate,
|
||||
av_get_default_channel_layout(audio_in_ctx->channels),
|
||||
audio_in_ctx->channel_layout,
|
||||
audio_in_ctx->sample_fmt,
|
||||
audio_in_ctx->sample_rate,
|
||||
0, NULL);
|
||||
|
@ -716,10 +721,11 @@ bool VideoStore::setup_resampler() {
|
|||
}
|
||||
|
||||
// Setup the data pointers in the AVFrame
|
||||
if ( avcodec_fill_audio_frame(out_frame, audio_out_ctx->channels,
|
||||
audio_out_ctx->sample_fmt,
|
||||
(const uint8_t *)converted_in_samples,
|
||||
audioSampleBuffer_size, 0) < 0 ) {
|
||||
if ( avcodec_fill_audio_frame(
|
||||
out_frame, audio_out_ctx->channels,
|
||||
audio_out_ctx->sample_fmt,
|
||||
(const uint8_t *)converted_in_samples,
|
||||
audioSampleBuffer_size, 0) < 0) {
|
||||
Error("Could not allocate converted in sample pointers");
|
||||
return false;
|
||||
}
|
||||
|
@ -897,10 +903,14 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
|
|||
return 0;
|
||||
}
|
||||
Debug(2,
|
||||
"Input Frame: samples(%d), format(%d), sample_rate(%d), channel "
|
||||
"layout(%d)",
|
||||
in_frame->nb_samples, in_frame->format,
|
||||
in_frame->sample_rate, in_frame->channel_layout);
|
||||
"In Frame: samples(%d), format(%d), sample_rate(%d), "
|
||||
"channels(%d) channel layout(%d) pts(%" PRId64 ")",
|
||||
in_frame->nb_samples,
|
||||
in_frame->format,
|
||||
in_frame->sample_rate,
|
||||
in_frame->channels,
|
||||
in_frame->channel_layout,
|
||||
in_frame->pts);
|
||||
#else
|
||||
/**
|
||||
* Decode the audio frame stored in the packet.
|
||||
|
@ -926,30 +936,29 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
|
|||
// decoded data
|
||||
zm_dump_frame(in_frame, "In frame");
|
||||
zm_dump_frame(out_frame, "Out frame before resample");
|
||||
if (
|
||||
#if defined(HAVE_LIBSWRESAMPLE)
|
||||
#if 0
|
||||
(ret = swr_convert(resample_ctx,
|
||||
out_frame->data, frame_size,
|
||||
(const uint8_t**)in_frame->data, in_frame->nb_samples
|
||||
(const uint8_t**)in_frame->data,
|
||||
in_frame->nb_samples
|
||||
))
|
||||
#else
|
||||
(ret = swr_convert_frame(resample_ctx, out_frame, in_frame))
|
||||
ret = swr_convert_frame(resample_ctx, out_frame, in_frame);
|
||||
|
||||
#endif
|
||||
#else
|
||||
#if defined(HAVE_LIBAVRESAMPLE)
|
||||
(ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,
|
||||
0, in_frame->nb_samples))
|
||||
ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,
|
||||
0, in_frame->nb_samples);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
< 0 ) {
|
||||
av_frame_unref(in_frame);
|
||||
if ( ret < 0 ) {
|
||||
Error("Could not resample frame (error '%s')",
|
||||
av_make_error_string(ret).c_str());
|
||||
av_frame_unref(in_frame);
|
||||
return 0;
|
||||
}
|
||||
av_frame_unref(in_frame);
|
||||
|
||||
#if defined(HAVE_LIBAVRESAMPLE)
|
||||
int samples_available = avresample_available(resample_ctx);
|
||||
|
@ -981,8 +990,8 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
|
|||
|
||||
// av_frame_unref( out_frame );
|
||||
|
||||
if ((ret = avcodec_receive_packet(audio_out_ctx, &opkt)) < 0) {
|
||||
if (AVERROR(EAGAIN) == ret) {
|
||||
if ( (ret = avcodec_receive_packet(audio_out_ctx, &opkt)) < 0 ) {
|
||||
if ( AVERROR(EAGAIN) == ret ) {
|
||||
// THe codec may need more samples than it has, perfectly valid
|
||||
Debug(3, "Could not recieve packet (error '%s')",
|
||||
av_make_error_string(ret).c_str());
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
#http://tom.webarts.ca/Blog/new-blog-items/buildingzoneminderandrequiredffmpegandx264fromsource
|
||||
|
||||
export LD_LIBRARY_PATH="/usr/local/lib:/opt/libjpeg-turbo/lib:$LD_LIBRARY_PATH"
|
||||
export LDFLAGS=" -L/home/nextime/zm/libjpeg-turbo-1.2.1/.libs "
|
||||
|
||||
|
||||
DEB_HOST_GNU_TYPE=$(dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE=$(dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
CXXFLAGS=" -DZM_FFMPEG_CVS -DHAVE_LIBCRYPTO -msse2 -DJPEG_INCLUDE_DIR=/home/nextime/zm/libjpeg-turbo-1.2.1/ "
|
||||
CXXFLAGS="$CXXFLAGS -I/home/nextime/zm/libjpeg-turbo-1.2.1/ "
|
||||
|
||||
CXXFLAGS="$CXXFLAGS" ./configure --with-libarch=lib/$DEB_HOST_GNU_TYPE --disable-debug --host=$DEB_HOST_GNU_TYPE --build=$DEB_BUILD_GNU_TYPE --sysconfdir=/etc/zm --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-mysql=/usr --with-webdir=/usr/share/zoneminder --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-crashtrace=no --enable-mmap=yes
|
||||
|
|
@ -15,7 +15,7 @@ switch ( $_REQUEST['task'] ) {
|
|||
|
||||
$file = !empty($_POST['file']) ? preg_replace( '/\w+:\/\/[\w.:]+\//', '', $_POST['file'] ) : '';
|
||||
if ( !empty( $_POST['line'] ) )
|
||||
$line = $_POST['line'];
|
||||
$line = validInt($_POST['line']);
|
||||
else
|
||||
$line = NULL;
|
||||
|
||||
|
|
|
@ -270,14 +270,32 @@ function collectData() {
|
|||
}
|
||||
$index++;
|
||||
}
|
||||
$sql .= ' where '.join( ' and ', $where );
|
||||
$sql .= ' WHERE '.join( ' AND ', $where );
|
||||
}
|
||||
if ( $groupSql )
|
||||
$sql .= ' GROUP BY '.join( ',', array_unique( $groupSql ) );
|
||||
if ( !empty($_REQUEST['sort']) ) {
|
||||
$sql .= ' order by :sort';
|
||||
$values[':sort'] = $_REQUEST['sort'];
|
||||
}
|
||||
$sql .= ' ORDER BY ';
|
||||
$sort_fields = explode(',',$_REQUEST['sort']);
|
||||
foreach ( $sort_fields as $sort_field ) {
|
||||
|
||||
preg_match('/^(\w+)\s*(ASC|DESC)?( NULLS FIRST)?$/i', $sort_field, $matches);
|
||||
if ( count($matches) ) {
|
||||
if ( in_array($matches[1], $fieldSql) ) {
|
||||
$sql .= $matches[1];
|
||||
} else {
|
||||
Error('Sort field ' . $matches[1] . ' not in SQL Fields');
|
||||
}
|
||||
if ( count($matches) > 2 ) {
|
||||
$sql .= ' '.strtoupper($matches[2]);
|
||||
if ( count($matches) > 3 )
|
||||
$sql .= ' '.strtoupper($matches[3]);
|
||||
}
|
||||
} else {
|
||||
Error("Sort field didn't match regexp $sort_field");
|
||||
}
|
||||
} # end foreach sort field
|
||||
} # end if has sort
|
||||
if ( !empty($entitySpec['limit']) )
|
||||
$limit = $entitySpec['limit'];
|
||||
elseif ( !empty($_REQUEST['count']) )
|
||||
|
|
|
@ -167,7 +167,7 @@ public $defaults = array(
|
|||
} # end find_one()
|
||||
|
||||
public function delete() {
|
||||
dbQuery('DELETE FROM Filters WHERE Id = ?', array($this->{'Id'}));
|
||||
dbQuery('DELETE FROM Filters WHERE Id=?', array($this->{'Id'}));
|
||||
} # end function delete()
|
||||
|
||||
public function set( $data ) {
|
||||
|
@ -186,6 +186,60 @@ public $defaults = array(
|
|||
}
|
||||
}
|
||||
} # end function set
|
||||
|
||||
public function control($command, $server_id=null) {
|
||||
$Servers = $server_id ? Server::find(array('Id'=>$server_id)) : Server::find();
|
||||
if ( !count($Servers) and !$server_id ) {
|
||||
# This will be the non-multi-server case
|
||||
$Servers = array(new Server());
|
||||
}
|
||||
foreach ( $Servers as $Server ) {
|
||||
|
||||
if ( !defined('ZM_SERVER_ID') or !$Server->Id() or ZM_SERVER_ID==$Server->Id() ) {
|
||||
# Local
|
||||
Logger::Debug("Controlling filter locally $command for server ".$Server->Id());
|
||||
daemonControl($command, 'zmfilter.pl', '--filter_id='.$this->{'Id'});
|
||||
} else {
|
||||
# Remote case
|
||||
|
||||
$url = $Server->UrlToIndex();
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash(ZM_AUTH_HASH_IPS);
|
||||
} else if ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
$url = '?pass='.$_SESSION['password'];
|
||||
} else if ( ZM_AUTH_RELAY == 'none' ) {
|
||||
$url = '?user='.$_SESSION['username'];
|
||||
}
|
||||
}
|
||||
$url .= '&view=filter&action=control&command='.$command.'&Id='.$this->Id().'&ServerId'.$Server->Id();
|
||||
Logger::Debug("sending command to $url");
|
||||
$data = array();
|
||||
if ( defined('ZM_ENABLE_CSRF_MAGIC') )
|
||||
$data['__csrf_magic'] = csrf_get_secret();
|
||||
|
||||
// use key 'http' even if you send the request to https://...
|
||||
$options = array(
|
||||
'http' => array(
|
||||
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||
'method' => 'POST',
|
||||
'content' => http_build_query($data)
|
||||
)
|
||||
);
|
||||
$context = stream_context_create($options);
|
||||
try {
|
||||
$result = file_get_contents($url, false, $context);
|
||||
if ( $result === FALSE ) { /* Handle error */
|
||||
Error("Error restarting zmfilter.pl using $url");
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
Error("Except $e thrown trying to restart zmfilter");
|
||||
}
|
||||
} # end if local or remote
|
||||
} # end foreach erver
|
||||
} # end function control
|
||||
|
||||
} # end class Filter
|
||||
|
||||
?>
|
||||
|
|
|
@ -50,9 +50,8 @@ class Frame {
|
|||
}
|
||||
|
||||
public function getImageSrc( $show='capture' ) {
|
||||
|
||||
return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'FrameId'}.'&eid='.$this->{'EventId'}.'&show='.$show;
|
||||
#return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'Id'}.'&show='.$show.'&filename='.$this->Event()->MonitorId().'_'.$this->{'EventId'}.'_'.$this->{'FrameId'}.'.jpg';
|
||||
return '?view=image&fid='.$this->{'FrameId'}.'&eid='.$this->{'EventId'}.'&show='.$show;
|
||||
#return '?view=image&fid='.$this->{'Id'}.'&show='.$show.'&filename='.$this->Event()->MonitorId().'_'.$this->{'EventId'}.'_'.$this->{'FrameId'}.'.jpg';
|
||||
} // end function getImageSrc
|
||||
|
||||
public static function find( $parameters = array(), $options = NULL ) {
|
||||
|
|
|
@ -331,6 +331,20 @@ private $control_fields = array(
|
|||
return $this->defaults{$field};
|
||||
} // end function Height
|
||||
|
||||
public function SignalCheckColour($new=null) {
|
||||
$field = 'SignalCheckColour';
|
||||
if ($new) {
|
||||
$this->{$field} = $new;
|
||||
}
|
||||
|
||||
// Validate that it's a valid colour (we seem to allow color names, not just hex).
|
||||
// This also helps prevent XSS.
|
||||
if (array_key_exists($field, $this) && preg_match('/^[#0-9a-zA-Z]+$/', $this->{$field})) {
|
||||
return $this->{$field};
|
||||
}
|
||||
return $this->defaults{$field};
|
||||
} // end function SignalCheckColour
|
||||
|
||||
public function set($data) {
|
||||
foreach ($data as $k => $v) {
|
||||
if ( method_exists($this, $k) ) {
|
||||
|
|
|
@ -117,7 +117,8 @@ class Server {
|
|||
if ( isset($this->{'PathToIndex'}) and $this->{'PathToIndex'} ) {
|
||||
return $this->{'PathToIndex'};
|
||||
}
|
||||
return $_SERVER['PHP_SELF'];
|
||||
// We can't trust PHP_SELF to not include an XSS vector. See note in skin.js.php.
|
||||
return preg_replace('/\.php.*$/i', '.php', $_SERVER['PHP_SELF']);
|
||||
}
|
||||
|
||||
public function UrlToIndex( $port=null ) {
|
||||
|
|
|
@ -223,5 +223,19 @@ class Storage {
|
|||
}
|
||||
return $this->{'Server'};
|
||||
}
|
||||
|
||||
public function to_json() {
|
||||
$json = array();
|
||||
foreach ($this->defaults as $key => $value) {
|
||||
if ( is_callable(array($this, $key)) ) {
|
||||
$json[$key] = $this->$key();
|
||||
} else if ( array_key_exists($key, $this) ) {
|
||||
$json[$key] = $this->{$key};
|
||||
} else {
|
||||
$json[$key] = $this->defaults{$key};
|
||||
}
|
||||
}
|
||||
return json_encode($json);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -23,5 +23,7 @@ if ( $action == 'bandwidth' && isset($_REQUEST['newBandwidth']) ) {
|
|||
$_COOKIE['zmBandwidth'] = validStr($_REQUEST['newBandwidth']);
|
||||
setcookie('zmBandwidth', validStr($_REQUEST['newBandwidth']), time()+3600*24*30*12*10);
|
||||
$refreshParent = true;
|
||||
$view = 'none';
|
||||
$closePopup = true;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -19,63 +19,93 @@
|
|||
//
|
||||
|
||||
// Event scope actions, view permissions only required
|
||||
if ( canView('Events') ) {
|
||||
if ( !canView('Events') ) {
|
||||
Warning('You do not have permission to view Events.');
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
|
||||
if ( $action == 'addterm' ) {
|
||||
$_REQUEST['filter'] = addFilterTerm($_REQUEST['filter'], $_REQUEST['line']);
|
||||
} elseif ( $action == 'delterm' ) {
|
||||
$_REQUEST['filter'] = delFilterTerm($_REQUEST['filter'], $_REQUEST['line']);
|
||||
} else if ( canEdit('Events') ) {
|
||||
if ( $action == 'delete' ) {
|
||||
if ( ! empty($_REQUEST['Id']) ) {
|
||||
dbQuery('DELETE FROM Filters WHERE Id=?', array($_REQUEST['Id']));
|
||||
}
|
||||
} else if ( ( $action == 'Save' ) or ( $action == 'SaveAs' ) or ( $action == 'execute' ) ) {
|
||||
# or ( $action == 'submit' ) ) {
|
||||
if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
|
||||
if ( $action == 'addterm' ) {
|
||||
$_REQUEST['filter'] = addFilterTerm($_REQUEST['filter'], $_REQUEST['line']);
|
||||
} elseif ( $action == 'delterm' ) {
|
||||
$_REQUEST['filter'] = delFilterTerm($_REQUEST['filter'], $_REQUEST['line']);
|
||||
} else if ( canEdit('Events') ) {
|
||||
if ( empty($_REQUEST['Id']) ) {
|
||||
Error("No filter id specified.");
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = '';
|
||||
$_REQUEST['filter']['Query']['sort_field'] = validStr($_REQUEST['filter']['Query']['sort_field']);
|
||||
$_REQUEST['filter']['Query']['sort_asc'] = validStr($_REQUEST['filter']['Query']['sort_asc']);
|
||||
$_REQUEST['filter']['Query']['limit'] = validInt($_REQUEST['filter']['Query']['limit']);
|
||||
if ( $action == 'execute' ) {
|
||||
$tempFilterName = '_TempFilter'.time();
|
||||
$sql .= ' Name = \''.$tempFilterName.'\'';
|
||||
} else {
|
||||
$sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']);
|
||||
}
|
||||
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']['Query']));
|
||||
$sql .= ', AutoArchive = '.(!empty($_REQUEST['filter']['AutoArchive']) ? 1 : 0);
|
||||
$sql .= ', AutoVideo = '. ( !empty($_REQUEST['filter']['AutoVideo']) ? 1 : 0);
|
||||
$sql .= ', AutoUpload = '. ( !empty($_REQUEST['filter']['AutoUpload']) ? 1 : 0);
|
||||
$sql .= ', AutoEmail = '. ( !empty($_REQUEST['filter']['AutoEmail']) ? 1 : 0);
|
||||
$sql .= ', AutoMessage = '. ( !empty($_REQUEST['filter']['AutoMessage']) ? 1 : 0);
|
||||
$sql .= ', AutoExecute = '. ( !empty($_REQUEST['filter']['AutoExecute']) ? 1 : 0);
|
||||
$sql .= ', AutoExecuteCmd = '.dbEscape($_REQUEST['filter']['AutoExecuteCmd']);
|
||||
$sql .= ', AutoDelete = '. ( !empty($_REQUEST['filter']['AutoDelete']) ? 1 : 0);
|
||||
if ( !empty($_REQUEST['filter']['AutoMove']) ? 1 : 0) {
|
||||
$sql .= ', AutoMove = 1, AutoMoveTo='. validInt($_REQUEST['filter']['AutoMoveTo']);
|
||||
} else {
|
||||
$sql .= ', AutoMove = 0';
|
||||
}
|
||||
$sql .= ', UpdateDiskSpace = '. ( !empty($_REQUEST['filter']['UpdateDiskSpace']) ? 1 : 0);
|
||||
$sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0);
|
||||
$sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0);
|
||||
require_once('includes/Filter.php');
|
||||
$filter = new Filter($_REQUEST['Id']);
|
||||
|
||||
if ( $_REQUEST['Id'] and ( $action == 'Save' ) ) {
|
||||
dbQuery('UPDATE Filters SET ' . $sql. ' WHERE Id=?', array($_REQUEST['Id']));
|
||||
} else {
|
||||
dbQuery('INSERT INTO Filters SET' . $sql);
|
||||
$_REQUEST['Id'] = dbInsertId();
|
||||
}
|
||||
if ( $action == 'execute' ) {
|
||||
executeFilter( $tempFilterName );
|
||||
}
|
||||
if ( $action == 'delete' ) {
|
||||
if ( !empty($_REQUEST['Id']) ) {
|
||||
if ( $filter->Background() ) {
|
||||
$filter->control('stop');
|
||||
}
|
||||
$filter->delete();
|
||||
|
||||
} // end if save or execute
|
||||
} // end if canEdit(Events)
|
||||
return;
|
||||
} // end if object == filter
|
||||
} // end canView(Events)
|
||||
} else {
|
||||
Error("No filter id passed when deleting");
|
||||
}
|
||||
} else if ( ( $action == 'Save' ) or ( $action == 'SaveAs' ) or ( $action == 'execute' ) ) {
|
||||
|
||||
$sql = '';
|
||||
$_REQUEST['filter']['Query']['sort_field'] = validStr($_REQUEST['filter']['Query']['sort_field']);
|
||||
$_REQUEST['filter']['Query']['sort_asc'] = validStr($_REQUEST['filter']['Query']['sort_asc']);
|
||||
$_REQUEST['filter']['Query']['limit'] = validInt($_REQUEST['filter']['Query']['limit']);
|
||||
if ( $action == 'execute' ) {
|
||||
$tempFilterName = '_TempFilter'.time();
|
||||
$sql .= ' Name = \''.$tempFilterName.'\'';
|
||||
} else {
|
||||
$sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']);
|
||||
}
|
||||
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']['Query']));
|
||||
$sql .= ', AutoArchive = '.(!empty($_REQUEST['filter']['AutoArchive']) ? 1 : 0);
|
||||
$sql .= ', AutoVideo = '. ( !empty($_REQUEST['filter']['AutoVideo']) ? 1 : 0);
|
||||
$sql .= ', AutoUpload = '. ( !empty($_REQUEST['filter']['AutoUpload']) ? 1 : 0);
|
||||
$sql .= ', AutoEmail = '. ( !empty($_REQUEST['filter']['AutoEmail']) ? 1 : 0);
|
||||
$sql .= ', AutoMessage = '. ( !empty($_REQUEST['filter']['AutoMessage']) ? 1 : 0);
|
||||
$sql .= ', AutoExecute = '. ( !empty($_REQUEST['filter']['AutoExecute']) ? 1 : 0);
|
||||
$sql .= ', AutoExecuteCmd = '.dbEscape($_REQUEST['filter']['AutoExecuteCmd']);
|
||||
$sql .= ', AutoDelete = '. ( !empty($_REQUEST['filter']['AutoDelete']) ? 1 : 0);
|
||||
if ( !empty($_REQUEST['filter']['AutoMove']) ? 1 : 0) {
|
||||
$sql .= ', AutoMove = 1, AutoMoveTo='. validInt($_REQUEST['filter']['AutoMoveTo']);
|
||||
} else {
|
||||
$sql .= ', AutoMove = 0';
|
||||
}
|
||||
$sql .= ', UpdateDiskSpace = '. ( !empty($_REQUEST['filter']['UpdateDiskSpace']) ? 1 : 0);
|
||||
$sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0);
|
||||
$sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0);
|
||||
|
||||
if ( $_REQUEST['Id'] and ( $action == 'Save' ) ) {
|
||||
dbQuery('UPDATE Filters SET '.$sql.' WHERE Id=?', array($_REQUEST['Id']));
|
||||
if ( $filter->Background() )
|
||||
$filter->control('stop');
|
||||
} else {
|
||||
dbQuery('INSERT INTO Filters SET'.$sql);
|
||||
$_REQUEST['Id'] = dbInsertId();
|
||||
$filter = new Filter($_REQUEST['Id']);
|
||||
}
|
||||
if ( !empty($_REQUEST['filter']['Background']) )
|
||||
$filter->control('start');
|
||||
|
||||
if ( $action == 'execute' ) {
|
||||
executeFilter($_REQUEST['Id']);
|
||||
$view = 'events';
|
||||
}
|
||||
|
||||
} else if ( $action == 'control' ) {
|
||||
if ( $_REQUEST['command'] == 'start'
|
||||
or $_REQUEST['command'] == 'stop'
|
||||
or $_REQUEST['command'] == 'restart'
|
||||
) {
|
||||
$filter->control($_REQUEST['command'], $_REQUEST['ServerId']);
|
||||
} else {
|
||||
Error('Invalid command for filter ('.$_REQUEST['command'].')');
|
||||
}
|
||||
} // end if save or execute
|
||||
} // end if canEdit(Events)
|
||||
} // end if object == filter
|
||||
|
||||
?>
|
||||
|
|
|
@ -43,7 +43,7 @@ if ( $action == 'delete' ) {
|
|||
$Group->delete();
|
||||
}
|
||||
}
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=groups';
|
||||
$redirect = '?view=groups';
|
||||
$refreshParent = true;
|
||||
} # end if action
|
||||
?>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
//
|
||||
|
||||
|
||||
if ( $action == 'login' && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == 'remote' || isset($_REQUEST['password']) ) ) {
|
||||
if ( ('login' == $action) && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == 'remote' || isset($_REQUEST['password']) ) ) {
|
||||
|
||||
$refreshParent = true;
|
||||
// User login is automatically performed in includes/auth.php So we don't need to perform a login here,
|
||||
|
@ -29,7 +29,6 @@ if ( $action == 'login' && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == 're
|
|||
$view = 'login';
|
||||
} else {
|
||||
$view = 'postlogin';
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=console';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -23,5 +23,6 @@ if ( $action == 'logout' ) {
|
|||
userLogout();
|
||||
$refreshParent = true;
|
||||
$view = 'none';
|
||||
$closePopup = true;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -40,7 +40,7 @@ if ( isset($_REQUEST['object']) ) {
|
|||
$_SESSION['zmMontageLayout'] = $Layout->Id();
|
||||
setcookie('zmMontageLayout', $Layout->Id(), 1);
|
||||
session_write_close();
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=montage';
|
||||
$redirect = '?view=montage';
|
||||
} // end if save
|
||||
|
||||
} # end if isset($_REQUEST['object'] )
|
||||
|
|
|
@ -89,7 +89,7 @@ if ( $action == 'delete' ) {
|
|||
case 'lowband' :
|
||||
break;
|
||||
}
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=options&tab='.$_REQUEST['tab'];
|
||||
$redirect = '?view=options&tab='.$_REQUEST['tab'];
|
||||
}
|
||||
loadConfig(false);
|
||||
return;
|
||||
|
|
|
@ -28,12 +28,12 @@ if ( ($action == 'privacy') && isset($_REQUEST['option']) ) {
|
|||
case 'decline' :
|
||||
dbQuery("UPDATE Config SET Value = '0' WHERE Name = 'ZM_SHOW_PRIVACY'");
|
||||
dbQuery("UPDATE Config SET Value = '0' WHERE Name = 'ZM_TELEMETRY_DATA'");
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=console';
|
||||
$redirect = '?view=console';
|
||||
break;
|
||||
case 'accept' :
|
||||
dbQuery("UPDATE Config SET Value = '0' WHERE Name = 'ZM_SHOW_PRIVACY'");
|
||||
dbQuery("UPDATE Config SET Value = '1' WHERE Name = 'ZM_TELEMETRY_DATA'");
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=console';
|
||||
$redirect = '?view=console';
|
||||
break;
|
||||
default: # Enable the privacy statement if we somehow submit something other than accept or decline
|
||||
dbQuery("UPDATE Config SET Value = '1' WHERE Name = 'ZM_SHOW_PRIVACY'");
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
// System edit actions
|
||||
if ( !canEdit('System') ) {
|
||||
Warning("Need System Permission to edit states");
|
||||
Warning('Need System Permission to edit states');
|
||||
return;
|
||||
}
|
||||
if ( $action == 'state' ) {
|
||||
|
@ -29,7 +29,7 @@ if ( $action == 'state' ) {
|
|||
packageControl($_REQUEST['runState']);
|
||||
$refreshParent = true;
|
||||
}
|
||||
} elseif ( $action == 'save' ) {
|
||||
} else if ( $action == 'save' ) {
|
||||
if ( !empty($_REQUEST['runState']) || !empty($_REQUEST['newState']) ) {
|
||||
$sql = 'SELECT Id,Function,Enabled FROM Monitors ORDER BY Id';
|
||||
$definitions = array();
|
||||
|
@ -41,8 +41,9 @@ if ( $action == 'state' ) {
|
|||
$_REQUEST['runState'] = $_REQUEST['newState'];
|
||||
dbQuery('REPLACE INTO States SET Name=?, Definition=?', array($_REQUEST['runState'],$definition));
|
||||
}
|
||||
} elseif ( $action == 'delete' ) {
|
||||
} else if ( $action == 'delete' ) {
|
||||
if ( isset($_REQUEST['runState']) )
|
||||
dbQuery('DELETE FROM States WHERE Name=?', array($_REQUEST['runState']));
|
||||
}
|
||||
$view = 'console';
|
||||
?>
|
||||
|
|
|
@ -88,12 +88,12 @@ function userLogin($username='', $password='', $passwordHashed=false) {
|
|||
$_SESSION['remoteAddr'] = $_SERVER['REMOTE_ADDR']; // To help prevent session hijacking
|
||||
if ( $dbUser = dbFetchOne($sql, NULL, $sql_values) ) {
|
||||
Info("Login successful for user \"$username\"");
|
||||
$_SESSION['user'] = $user = $dbUser;
|
||||
$user = $dbUser;
|
||||
unset($_SESSION['loginFailed']);
|
||||
if ( ZM_AUTH_TYPE == 'builtin' ) {
|
||||
$_SESSION['passwordHash'] = $user['Password'];
|
||||
}
|
||||
session_regenerate_id();
|
||||
zm_session_regenerate_id();
|
||||
} else {
|
||||
Warning("Login denied for user \"$username\"");
|
||||
$_SESSION['loginFailed'] = true;
|
||||
|
@ -107,10 +107,8 @@ function userLogin($username='', $password='', $passwordHashed=false) {
|
|||
function userLogout() {
|
||||
global $user;
|
||||
Info('User "'.$user['Username'].'" logged out');
|
||||
session_start();
|
||||
unset($_SESSION['user']);
|
||||
unset($user);
|
||||
session_destroy();
|
||||
zm_session_clear();
|
||||
}
|
||||
|
||||
function getAuthUser($auth) {
|
||||
|
@ -205,31 +203,39 @@ function canEdit($area, $mid=false) {
|
|||
return ( $user[$area] == 'Edit' && ( !$mid || visibleMonitor($mid) ));
|
||||
}
|
||||
|
||||
function is_session_started() {
|
||||
if ( php_sapi_name() !== 'cli' ) {
|
||||
if ( version_compare(phpversion(), '5.4.0', '>=') ) {
|
||||
return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
|
||||
} else {
|
||||
return session_id() === '' ? FALSE : TRUE;
|
||||
}
|
||||
} else {
|
||||
Warning("php_sapi_name === 'cli'");
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_HASH_LOGINS && empty($user) && ! empty($_REQUEST['auth']) ) {
|
||||
if ( isset($_SESSION['username']) ) {
|
||||
# Need to refresh permissions and validate that the user still exists
|
||||
$sql = 'SELECT * FROM Users WHERE Enabled=1 AND Username=?';
|
||||
$user = dbFetchOne($sql, NULL, array($_SESSION['username']));
|
||||
}
|
||||
|
||||
$close_session = 0;
|
||||
if ( !is_session_started() ) {
|
||||
session_start();
|
||||
$close_session = 1;
|
||||
}
|
||||
|
||||
if ( ZM_AUTH_RELAY == 'plain' ) {
|
||||
// Need to save this in session
|
||||
$_SESSION['password'] = $password;
|
||||
}
|
||||
$_SESSION['remoteAddr'] = $_SERVER['REMOTE_ADDR']; // To help prevent session hijacking
|
||||
|
||||
if ( ZM_AUTH_HASH_LOGINS && empty($user) && !empty($_REQUEST['auth']) ) {
|
||||
if ( $authUser = getAuthUser($_REQUEST['auth']) ) {
|
||||
userLogin($authUser['Username'], $authUser['Password'], true);
|
||||
}
|
||||
}
|
||||
else if ( isset($_REQUEST['username']) and isset($_REQUEST['password']) ) {
|
||||
} else if ( isset($_REQUEST['username']) and isset($_REQUEST['password']) ) {
|
||||
userLogin($_REQUEST['username'], $_REQUEST['password'], false);
|
||||
}
|
||||
if ( !empty($user) ) {
|
||||
// generate it once here, while session is open. Value will be cached in session and return when called later on
|
||||
generateAuthHash(ZM_AUTH_HASH_IPS);
|
||||
}
|
||||
if ( $close_session )
|
||||
session_write_close();
|
||||
} else {
|
||||
$user = $defaultUser;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -288,9 +288,13 @@ function csrf_callback($tokens) {
|
|||
echo "<html><head><title>CSRF check failed</title></head>
|
||||
<body>
|
||||
<p>CSRF check failed. Your form session may have expired, or you may not have
|
||||
cookies enabled.</p>
|
||||
<form method='post' action=''>$data<input type='submit' value='Try again' /></form>
|
||||
<p>Debug: $tokens</p></body></html>
|
||||
cookies enabled.</p>";
|
||||
if (ZM_LOG_DEBUG) {
|
||||
// Don't make it too easy for users to inflict a CSRF attack on themselves.
|
||||
echo "<p><strong>Only try again if you weren't sent to this page by someone as this is potentially a sign of an attack.</strong></p>";
|
||||
echo "<form method='post' action=''>$data<input type='submit' value='Try again' /></form>";
|
||||
}
|
||||
echo "<p>Debug: $tokens</p></body></html>
|
||||
";
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,24 @@ function CSPHeaders($view, $nonce) {
|
|||
case 'blank':
|
||||
case 'console':
|
||||
case 'controlcap':
|
||||
case 'cycle':
|
||||
case 'donate':
|
||||
case 'download':
|
||||
case 'error':
|
||||
case 'events':
|
||||
case 'export':
|
||||
case 'frame':
|
||||
case 'function':
|
||||
case 'log':
|
||||
case 'logout':
|
||||
case 'optionhelp':
|
||||
case 'options':
|
||||
case 'plugin':
|
||||
case 'postlogin':
|
||||
case 'privacy':
|
||||
case 'server':
|
||||
case 'state':
|
||||
case 'status':
|
||||
case 'storage':
|
||||
case 'version': {
|
||||
// Enforce script-src on pages where inline scripts and event handlers have been fixed.
|
||||
|
@ -281,7 +294,7 @@ function getImageStreamHTML( $id, $src, $width, $height, $title='' ) {
|
|||
|
||||
function outputControlStream( $src, $width, $height, $monitor, $scale, $target ) {
|
||||
?>
|
||||
<form name="ctrlForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>" target="<?php echo $target ?>">
|
||||
<form name="ctrlForm" method="post" action="?" target="<?php echo $target ?>">
|
||||
<input type="hidden" name="view" value="blank">
|
||||
<input type="hidden" name="mid" value="<?php echo $monitor['Id'] ?>">
|
||||
<input type="hidden" name="action" value="control">
|
||||
|
@ -351,7 +364,7 @@ function getWebSiteUrl( $id, $src, $width, $height, $title='' ) {
|
|||
|
||||
function outputControlStill( $src, $width, $height, $monitor, $scale, $target ) {
|
||||
?>
|
||||
<form name="ctrlForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>" target="<?php echo $target ?>">
|
||||
<form name="ctrlForm" method="post" action="?" target="<?php echo $target ?>">
|
||||
<input type="hidden" name="view" value="blank">
|
||||
<input type="hidden" name="mid" value="<?php echo $monitor['Id'] ?>">
|
||||
<input type="hidden" name="action" value="control">
|
||||
|
@ -441,6 +454,9 @@ function makeLink( $url, $label, $condition=1, $options='' ) {
|
|||
return( $string );
|
||||
}
|
||||
|
||||
/**
|
||||
* $label must be already escaped. It can't be done here since it sometimes contains HTML tags.
|
||||
*/
|
||||
function makePopupLink( $url, $winName, $winSize, $label, $condition=1, $options='' ) {
|
||||
// Avoid double-encoding since some consumers incorrectly pass a pre-escaped URL.
|
||||
$string = '<a class="popup-link" href="' . htmlspecialchars($url, ENT_COMPAT | ENT_HTML401, ini_get("default_charset"), false) . '"';
|
||||
|
@ -482,7 +498,6 @@ function makePopupButton( $url, $winName, $winSize, $buttonValue, $condition=1,
|
|||
}
|
||||
|
||||
function htmlSelect( $name, $contents, $values, $behaviours=false ) {
|
||||
|
||||
$behaviourText = '';
|
||||
if ( !empty($behaviours) ) {
|
||||
if ( is_array($behaviours) ) {
|
||||
|
@ -520,10 +535,10 @@ function htmlOptions($contents, $values) {
|
|||
$text = $option;
|
||||
}
|
||||
$selected = is_array($values) ? in_array($value, $values) : !strcmp($value, $values);
|
||||
$options_html .= "<option value=\"$value\"".
|
||||
$options_html .= "<option value=\"".htmlspecialchars($value, ENT_COMPAT | ENT_HTML401, ini_get('default_charset'), false)."\"".
|
||||
($selected?' selected="selected"':'').
|
||||
($disabled?' disabled="disabled"':'').
|
||||
">$text</option>";
|
||||
">".htmlspecialchars($text, ENT_COMPAT | ENT_HTML401, ini_get('default_charset'), false)."</option>";
|
||||
}
|
||||
return $options_html;
|
||||
}
|
||||
|
@ -598,7 +613,7 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false ) {
|
|||
{
|
||||
if ( is_array($newValues[$key]) ) {
|
||||
if ( (!isset($values[$key])) or ( join(',',$newValues[$key]) != $values[$key] ) ) {
|
||||
$changes[$key] = "`$key` = ".dbEscape(join(',',$newValues[$key]));
|
||||
$changes[$key] = "`$key` = '".dbEscape(join(',',$newValues[$key]))."'";
|
||||
}
|
||||
} else if ( (!isset($values[$key])) or $values[$key] ) {
|
||||
$changes[$key] = "`$key` = ''";
|
||||
|
@ -958,11 +973,11 @@ Logger::Debug("generating Video $command: result($result outptu:(".implode("\n",
|
|||
return( $status?"":rtrim($result) );
|
||||
}
|
||||
|
||||
function executeFilter( $filter ) {
|
||||
$command = ZM_PATH_BIN."/zmfilter.pl --filter ".escapeshellarg($filter);
|
||||
$result = exec( $command, $output, $status );
|
||||
dbQuery( "delete from Filters where Name like '_TempFilter%'" );
|
||||
return( $status );
|
||||
function executeFilter( $filter_id ) {
|
||||
$command = ZM_PATH_BIN.'/zmfilter.pl --filter_id '.escapeshellarg($filter_id);
|
||||
$result = exec($command, $output, $status);
|
||||
dbQuery('DELETE FROM Filters WHERE Id=?', array($filter_id));
|
||||
return $status;
|
||||
}
|
||||
|
||||
# This takes more than one scale amount, so it runs through each and alters dimension.
|
||||
|
@ -1071,27 +1086,34 @@ function parseSort( $saveToSession=false, $querySep='&' ) {
|
|||
$_SESSION['sort_asc'] = validHtmlStr($_REQUEST['sort_asc']);
|
||||
}
|
||||
if ($_REQUEST['limit'] != '') {
|
||||
$limitQuery = "&limit=".$_REQUEST['limit'];
|
||||
$limitQuery = "&limit=".validInt($_REQUEST['limit']);
|
||||
}
|
||||
}
|
||||
|
||||
function getFilterQueryConjunctionTypes() {
|
||||
return array(
|
||||
'and' => translate('ConjAnd'),
|
||||
'or' => translate('ConjOr')
|
||||
);
|
||||
}
|
||||
|
||||
function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
||||
$filter['query'] = '';
|
||||
$filter['query'] = '';
|
||||
$filter['sql'] = '';
|
||||
$filter['fields'] = '';
|
||||
|
||||
$validQueryConjunctionTypes = getFilterQueryConjunctionTypes();
|
||||
$StorageArea = NULL;
|
||||
|
||||
$terms = isset($filter['Query']) ? $filter['Query']['terms'] : NULL;
|
||||
|
||||
if ( isset($terms) && count($terms) ) {
|
||||
for ( $i = 0; $i < count($terms); $i++ ) {
|
||||
if ( isset($terms[$i]['cnj']) ) {
|
||||
if ( isset($terms[$i]['cnj']) && array_key_exists($terms[$i]['cnj'], $validQueryConjunctionTypes) ) {
|
||||
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cnj]").'='.urlencode($terms[$i]['cnj']);
|
||||
$filter['sql'] .= ' '.$terms[$i]['cnj'].' ';
|
||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][cnj]\" value=\"".htmlspecialchars($terms[$i]['cnj'])."\"/>\n";
|
||||
}
|
||||
if ( isset($terms[$i]['obr']) ) {
|
||||
if ( isset($terms[$i]['obr']) && (string)(int)$terms[$i]['obr'] == $terms[$i]['obr'] ) {
|
||||
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][obr]").'='.urlencode($terms[$i]['obr']);
|
||||
$filter['sql'] .= ' '.str_repeat('(', $terms[$i]['obr']).' ';
|
||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][obr]\" value=\"".htmlspecialchars($terms[$i]['obr'])."\"/>\n";
|
||||
|
@ -1101,7 +1123,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
|||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][attr]\" value=\"".htmlspecialchars($terms[$i]['attr'])."\"/>\n";
|
||||
switch ( $terms[$i]['attr'] ) {
|
||||
case 'MonitorName':
|
||||
$filter['sql'] .= 'M.'.preg_replace('/^Monitor/', '', $terms[$i]['attr']);
|
||||
$filter['sql'] .= 'M.Name';
|
||||
break;
|
||||
case 'ServerId':
|
||||
case 'MonitorServerId':
|
||||
|
@ -1295,7 +1317,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
|
|||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][val]\" value=\"".htmlspecialchars($terms[$i]['val'])."\"/>\n";
|
||||
}
|
||||
} // end foreach term
|
||||
if ( isset($terms[$i]['cbr']) ) {
|
||||
if ( isset($terms[$i]['cbr']) && (string)(int)$terms[$i]['cbr'] == $terms[$i]['cbr'] ) {
|
||||
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cbr]").'='.urlencode($terms[$i]['cbr']);
|
||||
$filter['sql'] .= ' '.str_repeat( ')', $terms[$i]['cbr'] ).' ';
|
||||
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][cbr]\" value=\"".htmlspecialchars($terms[$i]['cbr'])."\"/>\n";
|
||||
|
@ -1405,7 +1427,7 @@ function getPagination( $pages, $page, $maxShortcuts, $query, $querySep='&'
|
|||
|
||||
function sortHeader( $field, $querySep='&' ) {
|
||||
global $view;
|
||||
return( '?view='.$view.$querySep.'page=1'.$_REQUEST['filter']['query'].$querySep.'sort_field='.$field.$querySep.'sort_asc='.($_REQUEST['sort_field'] == $field?!$_REQUEST['sort_asc']:0).$querySep.'limit='.$_REQUEST['limit'] );
|
||||
return '?view='.$view.$querySep.'page=1'.$_REQUEST['filter']['query'].$querySep.'sort_field='.$field.$querySep.'sort_asc='.($_REQUEST['sort_field'] == $field?!$_REQUEST['sort_asc']:0).$querySep.'limit='.validInt($_REQUEST['limit']);
|
||||
}
|
||||
|
||||
function sortTag( $field ) {
|
||||
|
|
|
@ -455,7 +455,10 @@ function Error( $string ) {
|
|||
|
||||
function Fatal( $string ) {
|
||||
Logger::fetch()->logPrint( Logger::FATAL, $string );
|
||||
die( htmlentities($string) );
|
||||
if (Logger::fetch()->debugOn()) {
|
||||
echo(htmlentities($string));
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function Panic( $string ) {
|
||||
|
@ -474,7 +477,10 @@ function Panic( $string ) {
|
|||
}
|
||||
}
|
||||
Logger::fetch()->logPrint( Logger::PANIC, $string.$backtrace );
|
||||
die( $string );
|
||||
if (Logger::fetch()->debugOn()) {
|
||||
echo $string;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
function ErrorHandler( $error, $string, $file, $line ) {
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
// ZM session start function support timestamp management
|
||||
function zm_session_start() {
|
||||
// Make sure use_strict_mode is enabled.
|
||||
// use_strict_mode is mandatory for security reasons.
|
||||
ini_set('session.use_strict_mode', 1);
|
||||
|
||||
$currentCookieParams = session_get_cookie_params();
|
||||
$currentCookieParams['lifetime'] = ZM_COOKIE_LIFETIME;
|
||||
|
||||
Logger::Debug('Setting cookie parameters to lifetime('.$currentCookieParams['lifetime'].') path('.$currentCookieParams['path'].') domain ('.$currentCookieParams['domain'].') secure('.$currentCookieParams['secure'].') httpOnly(1)');
|
||||
session_set_cookie_params(
|
||||
$currentCookieParams['lifetime'],
|
||||
$currentCookieParams['path'],
|
||||
$currentCookieParams['domain'],
|
||||
$currentCookieParams['secure'],
|
||||
true
|
||||
);
|
||||
|
||||
ini_set('session.name', 'ZMSESSID');
|
||||
|
||||
session_start();
|
||||
// Do not allow to use expired session ID
|
||||
if ( !empty($_SESSION['last_time']) && ($_SESSION['last_time'] < (time() - 180)) ) {
|
||||
Info('Destroying session due to timeout. ');
|
||||
session_destroy();
|
||||
session_start();
|
||||
}
|
||||
} // function zm_session_start()
|
||||
|
||||
// My session regenerate id function
|
||||
function zm_session_regenerate_id() {
|
||||
if ( session_status() != PHP_SESSION_ACTIVE ) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Set deleted timestamp. Session data must not be deleted immediately for reasons.
|
||||
$_SESSION['last_time'] = time();
|
||||
// Finish session
|
||||
session_write_close();
|
||||
|
||||
session_start();
|
||||
session_regenerate_id();
|
||||
unset($_SESSION['last_time']);
|
||||
} // function zm_session_regenerate_id()
|
||||
|
||||
function is_session_started() {
|
||||
if ( php_sapi_name() !== 'cli' ) {
|
||||
if ( version_compare(phpversion(), '5.4.0', '>=') ) {
|
||||
return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
|
||||
} else {
|
||||
return session_id() === '' ? FALSE : TRUE;
|
||||
}
|
||||
} else {
|
||||
Warning("php_sapi_name === 'cli'");
|
||||
}
|
||||
return FALSE;
|
||||
} // function is_session_started()
|
||||
|
||||
function zm_session_clear() {
|
||||
session_start();
|
||||
$_SESSION = array();
|
||||
if ( ini_get('session.use_cookies') ) {
|
||||
$p = session_get_cookie_params();
|
||||
# Update the cookie to expire in the past.
|
||||
setcookie(session_name(), '', time() - 31536000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
|
||||
}
|
||||
session_unset();
|
||||
session_destroy();
|
||||
} // function zm_session_clear()
|
||||
?>
|
101
web/index.php
101
web/index.php
|
@ -44,6 +44,7 @@ if ( false ) {
|
|||
}
|
||||
|
||||
require_once('includes/config.php');
|
||||
require_once('includes/session.php');
|
||||
require_once('includes/logger.php');
|
||||
require_once('includes/Server.php');
|
||||
require_once('includes/Storage.php');
|
||||
|
@ -51,7 +52,6 @@ require_once('includes/Event.php');
|
|||
require_once('includes/Group.php');
|
||||
require_once('includes/Monitor.php');
|
||||
|
||||
|
||||
if (
|
||||
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
|
||||
or
|
||||
|
@ -115,39 +115,28 @@ if ( !file_exists(ZM_SKIN_PATH) )
|
|||
Fatal("Invalid skin '$skin'");
|
||||
$skinBase[] = $skin;
|
||||
|
||||
$currentCookieParams = session_get_cookie_params();
|
||||
//Logger::Debug('Setting cookie parameters to lifetime('.$currentCookieParams['lifetime'].') path('.$currentCookieParams['path'].') domain ('.$currentCookieParams['domain'].') secure('.$currentCookieParams['secure'].') httpOnly(1)');
|
||||
session_set_cookie_params(
|
||||
$currentCookieParams['lifetime'],
|
||||
$currentCookieParams['path'],
|
||||
$currentCookieParams['domain'],
|
||||
$currentCookieParams['secure'],
|
||||
true
|
||||
);
|
||||
zm_session_start();
|
||||
|
||||
ini_set('session.name', 'ZMSESSID');
|
||||
|
||||
session_start();
|
||||
|
||||
if ( !isset($_SESSION['skin']) || isset($_REQUEST['skin']) || !isset($_COOKIE['zmSkin']) || $_COOKIE['zmSkin'] != $skin ) {
|
||||
if (
|
||||
!isset($_SESSION['skin']) ||
|
||||
isset($_REQUEST['skin']) ||
|
||||
!isset($_COOKIE['zmSkin']) ||
|
||||
$_COOKIE['zmSkin'] != $skin
|
||||
) {
|
||||
$_SESSION['skin'] = $skin;
|
||||
setcookie('zmSkin', $skin, time()+3600*24*30*12*10);
|
||||
}
|
||||
|
||||
if ( !isset($_SESSION['css']) || isset($_REQUEST['css']) || !isset($_COOKIE['zmCSS']) || $_COOKIE['zmCSS'] != $css ) {
|
||||
if (
|
||||
!isset($_SESSION['css']) ||
|
||||
isset($_REQUEST['css']) ||
|
||||
!isset($_COOKIE['zmCSS']) ||
|
||||
$_COOKIE['zmCSS'] != $css
|
||||
) {
|
||||
$_SESSION['css'] = $css;
|
||||
setcookie('zmCSS', $css, time()+3600*24*30*12*10);
|
||||
}
|
||||
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( isset($_SESSION['user']) ) {
|
||||
$user = $_SESSION['user'];
|
||||
} else {
|
||||
unset($user);
|
||||
}
|
||||
} else {
|
||||
$user = $defaultUser;
|
||||
}
|
||||
# Only one request can open the session file at a time, so let's close the session here to improve concurrency.
|
||||
# Any file/page that sets session variables must re-open it.
|
||||
session_write_close();
|
||||
|
@ -166,6 +155,7 @@ if ( !is_writable(ZM_DIR_EVENTS) ) {
|
|||
}
|
||||
|
||||
# Globals
|
||||
$action = null;
|
||||
$error_message = null;
|
||||
$redirect = null;
|
||||
$view = null;
|
||||
|
@ -179,16 +169,18 @@ $request = null;
|
|||
if ( isset($_REQUEST['request']) )
|
||||
$request = detaintPath($_REQUEST['request']);
|
||||
|
||||
foreach ( getSkinIncludes('skin.php') as $includeFile )
|
||||
require_once $includeFile;
|
||||
|
||||
# User Login will be performed in auth.php
|
||||
require_once('includes/auth.php');
|
||||
|
||||
if ( isset($_REQUEST['action']) ) {
|
||||
$action = detaintPath($_REQUEST['action']);
|
||||
foreach ( getSkinIncludes('skin.php') as $includeFile ) {
|
||||
#Logger::Debug("including $includeFile");
|
||||
require_once $includeFile;
|
||||
}
|
||||
|
||||
if ( isset($_REQUEST['action']) )
|
||||
$action = detaintPath($_REQUEST['action']);
|
||||
|
||||
|
||||
# The only variable we really need to set is action. The others are informal.
|
||||
isset($view) || $view = NULL;
|
||||
isset($request) || $request = NULL;
|
||||
|
@ -220,19 +212,22 @@ if ( $action ) {
|
|||
}
|
||||
|
||||
# If I put this here, it protects all views and popups, but it has to go after actions.php because actions.php does the actual logging in.
|
||||
if ( ZM_OPT_USE_AUTH and !isset($user) ) {
|
||||
if ( ZM_OPT_USE_AUTH and !isset($user) and ($view != 'login') ) {
|
||||
Logger::Debug('Redirecting to login');
|
||||
$view = 'login';
|
||||
$view = 'none';
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=login';
|
||||
$request = null;
|
||||
} else if ( ZM_SHOW_PRIVACY && ($action != 'privacy') && ($view != 'options') && (!$request) && canEdit('System') ) {
|
||||
} else if ( ZM_SHOW_PRIVACY && ($view != 'privacy') && ($view != 'options') && (!$request) && canEdit('System') ) {
|
||||
$view = 'none';
|
||||
Logger::Debug('Redirecting to privacy');
|
||||
$view = 'privacy';
|
||||
$redirect = ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=privacy';
|
||||
$request = null;
|
||||
}
|
||||
|
||||
CSPHeaders($view, $cspNonce);
|
||||
|
||||
if ( $redirect ) {
|
||||
Logger::Debug("Redirecting to $redirect");
|
||||
header('Location: '.$redirect);
|
||||
return;
|
||||
}
|
||||
|
@ -244,27 +239,27 @@ if ( $request ) {
|
|||
require_once $includeFile;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if ( $includeFiles = getSkinIncludes('views/'.$view.'.php', true, true) ) {
|
||||
foreach ( $includeFiles as $includeFile ) {
|
||||
if ( !file_exists($includeFile) )
|
||||
Fatal("View '$view' does not exist");
|
||||
require_once $includeFile;
|
||||
}
|
||||
// If the view overrides $view to 'error', and the user is not logged in, then the
|
||||
// issue is probably resolvable by logging in, so provide the opportunity to do so.
|
||||
// The login view should handle redirecting to the correct location afterward.
|
||||
if ( $view == 'error' && !isset($user) ) {
|
||||
$view = 'login';
|
||||
foreach ( getSkinIncludes('views/login.php', true, true) as $includeFile )
|
||||
require_once $includeFile;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $includeFiles = getSkinIncludes('views/'.$view.'.php', true, true) ) {
|
||||
foreach ( $includeFiles as $includeFile ) {
|
||||
if ( !file_exists($includeFile) )
|
||||
Fatal("View '$view' does not exist");
|
||||
require_once $includeFile;
|
||||
}
|
||||
// If the view is missing or the view still returned error with the user logged in,
|
||||
// then it is not recoverable.
|
||||
if ( !$includeFiles || $view == 'error' ) {
|
||||
foreach ( getSkinIncludes('views/error.php', true, true) as $includeFile )
|
||||
// If the view overrides $view to 'error', and the user is not logged in, then the
|
||||
// issue is probably resolvable by logging in, so provide the opportunity to do so.
|
||||
// The login view should handle redirecting to the correct location afterward.
|
||||
if ( $view == 'error' && !isset($user) ) {
|
||||
$view = 'login';
|
||||
foreach ( getSkinIncludes('views/login.php', true, true) as $includeFile )
|
||||
require_once $includeFile;
|
||||
}
|
||||
}
|
||||
// If the view is missing or the view still returned error with the user logged in,
|
||||
// then it is not recoverable.
|
||||
if ( !$includeFiles || $view == 'error' ) {
|
||||
foreach ( getSkinIncludes('views/error.php', true, true) as $includeFile )
|
||||
require_once $includeFile;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -9,8 +9,3 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#controls a {
|
||||
width: 40px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,3 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#controls a {
|
||||
width: 40px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,3 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#controls a {
|
||||
width: 40px;
|
||||
margin-left: -20px;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ function xhtmlHeaders( $file, $title ) {
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title><?php echo ZM_WEB_TITLE_PREFIX ?> - <?php echo validHtmlStr($title) ?></title>
|
||||
<title><?php echo validHtmlStr(ZM_WEB_TITLE_PREFIX); ?> - <?php echo validHtmlStr($title) ?></title>
|
||||
<?php
|
||||
if ( file_exists( "skins/$skin/css/$css/graphics/favicon.ico" ) ) {
|
||||
echo "
|
||||
|
@ -91,7 +91,7 @@ echo output_link_if_exists( array(
|
|||
<!--Chosen can't be cache-busted because it loads sprites by relative path-->
|
||||
<link rel="stylesheet" href="skins/classic/js/chosen/chosen.min.css" type="text/css"/>
|
||||
<?php
|
||||
if ($basename == 'watch') {
|
||||
if ( $basename == 'watch' ) {
|
||||
echo output_link_if_exists( array(
|
||||
'/css/base/views/control.css',
|
||||
'/css/'.$css.'/views/control.css'
|
||||
|
@ -100,11 +100,9 @@ echo output_link_if_exists( array(
|
|||
if ( $viewCssPhpFile ) {
|
||||
?>
|
||||
<style type="text/css">
|
||||
/*<![CDATA[*/
|
||||
<?php
|
||||
require_once( $viewCssPhpFile );
|
||||
require_once($viewCssPhpFile);
|
||||
?>
|
||||
/*]]>*/
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
|
@ -131,7 +129,7 @@ echo output_link_if_exists( array(
|
|||
var $j = jQuery.noConflict();
|
||||
// $j is now an alias to the jQuery function; creating the new alias is optional.
|
||||
</script>
|
||||
<script src="skins/<?php echo $skin; ?>/views/js/state.js"></script>
|
||||
<script src="<?php echo cache_bust('skins/'.$skin.'/views/js/state.js') ?>"></script>
|
||||
<?php
|
||||
if ( $title == 'Login' && (defined('ZM_OPT_USE_GOOG_RECAPTCHA') && ZM_OPT_USE_GOOG_RECAPTCHA) ) {
|
||||
?>
|
||||
|
@ -207,7 +205,7 @@ function getBodyTopHTML() {
|
|||
<body>
|
||||
<noscript>
|
||||
<div style="background-color:red;color:white;font-size:x-large;">
|
||||
'. ZM_WEB_TITLE .' requires Javascript. Please enable Javascript in your browser for this site.
|
||||
'. validHtmlStr(ZM_WEB_TITLE) .' requires Javascript. Please enable Javascript in your browser for this site.
|
||||
|
||||
</div>
|
||||
</noscript>
|
||||
|
@ -219,7 +217,7 @@ function getBodyTopHTML() {
|
|||
} // end function getBodyTopHTML
|
||||
|
||||
function getNavBarHTML($reload = null) {
|
||||
# Provide a facility to turn off the headers if you put headers=0 into the url
|
||||
# Provide a facility to turn off the headers if you put navbar=0 into the url
|
||||
if ( isset($_REQUEST['navbar']) and $_REQUEST['navbar']=='0' )
|
||||
return '';
|
||||
|
||||
|
@ -254,14 +252,16 @@ function getNavBarHTML($reload = null) {
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<div class="navbar-brand"><a href="<?php echo ZM_HOME_URL?>" target="<?php echo ZM_WEB_TITLE ?>"><?php echo ZM_HOME_CONTENT ?></a></div>
|
||||
<div class="navbar-brand"><a href="<?php echo validHtmlStr(ZM_HOME_URL); ?>" target="<?php echo validHtmlStr(ZM_WEB_TITLE); ?>"><?php echo validHtmlStr(ZM_HOME_CONTENT); ?></a></div>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="main-header-nav">
|
||||
<?php if ( canView('Monitors') ) { ?>
|
||||
<ul class="nav navbar-nav">
|
||||
<?php if ( $user and $user['Username'] ) { ?>
|
||||
<?php if ( canView('Monitors') ) { ?>
|
||||
<li><a href="?view=console"><?php echo translate('Console') ?></a></li>
|
||||
<?php if ( canView( 'System' ) ) { ?>
|
||||
<?php } // end if canView('Monitors') ?>
|
||||
<?php if ( canView('System') ) { ?>
|
||||
<li><a href="?view=options"><?php echo translate('Options') ?></a></li>
|
||||
<li>
|
||||
<?php
|
||||
|
@ -272,17 +272,17 @@ function getNavBarHTML($reload = null) {
|
|||
}
|
||||
echo makePopupLink( '?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>' );
|
||||
}
|
||||
} // end if canview(System)
|
||||
?></li>
|
||||
<?php
|
||||
if ( ZM_OPT_X10 && canView( 'Devices' ) ) { ?>
|
||||
} // end if canview(System)
|
||||
if ( ZM_OPT_X10 && canView('Devices') ) { ?>
|
||||
<li><a href="?view=devices">Devices</a></li>
|
||||
<?php } ?>
|
||||
<li><a href="?view=groups"<?php echo $view=='groups'?' class="selected"':''?>><?php echo translate('Groups') ?></a></li>
|
||||
<li><a href="?view=filter<?php echo $filterQuery.$sortQuery.$limitQuery ?>"<?php echo $view=='filter'?' class="selected"':''?>><?php echo translate('Filters') ?></a></li>
|
||||
|
||||
<?php
|
||||
if ( canView( 'Stream' ) ) {
|
||||
if ( canView('Stream') ) {
|
||||
?>
|
||||
<li><a href="?view=cycle"<?php echo $view=='cycle'?' class="selected"':''?>><?php echo translate('Cycle') ?></a></li>
|
||||
<li><a href="?view=montage"<?php echo $view=='montage'?' class="selected"':''?>><?php echo translate('Montage') ?></a></li>
|
||||
|
@ -295,44 +295,44 @@ if (isset($_REQUEST['filter']['Query']['terms']['attr'])) {
|
|||
$terms = $_REQUEST['filter']['Query']['terms'];
|
||||
$count = 0;
|
||||
foreach ($terms as $term) {
|
||||
if ($term['attr'] == "StartDateTime") {
|
||||
if ( $term['attr'] == 'StartDateTime' ) {
|
||||
$count += 1;
|
||||
if ($term['op'] == '>=') $minTime = $term['val'];
|
||||
if ($term['op'] == '<=') $maxTime = $term['val'];
|
||||
}
|
||||
}
|
||||
if ($count == 2) {
|
||||
if ( $count == 2 ) {
|
||||
$montageReviewQuery = '&minTime='.$minTime.'&maxTime='.$maxTime;
|
||||
}
|
||||
}
|
||||
if ( canView('Events') ) {
|
||||
?>
|
||||
<li><a href="?view=montagereview<?php echo isset($montageReviewQuery)?'&fit=1'.$montageReviewQuery.'&live=0':'' ?>"<?php echo $view=='montagereview'?' class="selected"':''?>><?php echo translate('MontageReview')?></a></li>
|
||||
<li><a href="?view=montagereview<?php echo isset($montageReviewQuery)?'&fit=1'.$montageReviewQuery.'&live=0':'' ?>"<?php echo $view=='montagereview'?' class="selected"':''?>><?php echo translate('MontageReview')?></a></li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<li><a href="?view=report_event_audit"<?php echo $view=='report_event_audit'?' class="selected"':''?>><?php echo translate('ReportEventAudit') ?></a></li>
|
||||
<li><a href="#"><span id="flip" class="glyphicon glyphicon-menu-<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down') ? 'down' : 'up' ?> pull-right"></span></a></li>
|
||||
</ul>
|
||||
<?php } // end if canView('Monitors') ?>
|
||||
|
||||
<div class="navbar-right">
|
||||
<?php if ( ZM_OPT_USE_AUTH and $user ) { ?>
|
||||
<p class="navbar-text"><i class="material-icons">account_circle</i> <?php echo makePopupLink( '?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == "builtin") ) ?> </p>
|
||||
<?php } ?>
|
||||
|
||||
<?php if ( canEdit( 'System' ) ) { ?>
|
||||
<?php if ( canEdit('System') ) { ?>
|
||||
<button type="button" class="btn btn-default navbar-btn" data-toggle="modal" data-target="#modalState"><?php echo $status ?></button>
|
||||
|
||||
<?php } else if ( canView( 'System' ) ) { ?>
|
||||
<p class="navbar-text"> <?php echo $status ?> </p>
|
||||
<?php } else if ( canView('System') ) { ?>
|
||||
<p class="navbar-text"> <?php echo $status ?></p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } # end if !$user or $user['Id'] meaning logged in ?>
|
||||
</div><!-- End .navbar-collapse -->
|
||||
</div> <!-- End .container-fluid -->
|
||||
<div id="panel"<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down' ) ? 'style="display:none;"' : '' ?>>
|
||||
<?php
|
||||
}//end reload null. Runs on full page load
|
||||
} //end reload null. Runs on full page load
|
||||
|
||||
if ( (!ZM_OPT_USE_AUTH) or $user ) {
|
||||
if ($reload == 'reload') ob_start();
|
||||
|
@ -342,7 +342,7 @@ if ($reload == 'reload') ob_start();
|
|||
<?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', "<i class='material-icons md-18'>network_check</i> ".$bandwidth_options[$_COOKIE['zmBandwidth']] . ' ', ($user && $user['MaxBandwidth'] != 'low' ) ) ?>
|
||||
</div>
|
||||
<div id="Version" class="pull-right">
|
||||
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="version '.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?>
|
||||
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="version '.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit('System') ) ?>
|
||||
</div>
|
||||
<ul class="list-inline">
|
||||
<li class="Load"><i class="material-icons md-18">trending_up</i> <?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
|
||||
|
@ -366,9 +366,9 @@ if ($reload == 'reload') ob_start();
|
|||
$func = function($S){
|
||||
$class = '';
|
||||
if ( $S->disk_usage_percent() > 98 ) {
|
||||
$class = "error";
|
||||
$class = 'error';
|
||||
} else if ( $S->disk_usage_percent() > 90 ) {
|
||||
$class = "warning";
|
||||
$class = 'warning';
|
||||
}
|
||||
$title = human_filesize($S->disk_used_space()) . ' of ' . human_filesize($S->disk_total_space()).
|
||||
( ( $S->disk_used_space() != $S->event_disk_space() ) ? ' ' .human_filesize($S->event_disk_space()) . ' used by events' : '' );
|
||||
|
@ -383,7 +383,7 @@ if ($reload == 'reload') ob_start();
|
|||
?></li>
|
||||
</ul>
|
||||
<?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?>
|
||||
<h3 id="development"><?php echo ZM_WEB_CONSOLE_BANNER ?></h3>
|
||||
<h3 id="development"><?php echo validHtmlStr(ZM_WEB_CONSOLE_BANNER); ?></h3>
|
||||
<?php } ?>
|
||||
<!-- End .footer/reload --></div>
|
||||
<?php
|
||||
|
|
|
@ -64,8 +64,8 @@ var popupSizes = {
|
|||
'stats': {'width': 840, 'height': 200},
|
||||
'storage': {'width': 600, 'height': 405},
|
||||
'timeline': {'width': 760, 'height': 540},
|
||||
'user': {'width': 360, 'height': 720},
|
||||
'version': {'width': 360, 'height': 185},
|
||||
'user': {'width': 460, 'height': 720},
|
||||
'version': {'width': 360, 'height': 210},
|
||||
'video': {'width': 420, 'height': 360},
|
||||
'videoview': {'addWidth': 48, 'addHeight': 80},
|
||||
'watch': {'addWidth': 96, 'minWidth': 420, 'addHeight': 384},
|
||||
|
|
|
@ -126,33 +126,44 @@ function createPopup( url, name, tag, width, height ) {
|
|||
}
|
||||
}
|
||||
|
||||
$j(document).ready(function() {
|
||||
$j("form.validateFormOnSubmit").submit(function onSubmit(evt) {
|
||||
if (!validateForm(this)) {
|
||||
// Polyfill for NodeList.prototype.forEach on IE.
|
||||
if (window.NodeList && !NodeList.prototype.forEach) {
|
||||
NodeList.prototype.forEach = Array.prototype.forEach;
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", function onSkinDCL() {
|
||||
document.querySelectorAll("form.validateFormOnSubmit").forEach(function(el) {
|
||||
el.addEventListener("submit", function onSubmit(evt) {
|
||||
if (!validateForm(this)) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll(".popup-link").forEach(function(el) {
|
||||
el.addEventListener("click", function onClick(evt) {
|
||||
var el = this;
|
||||
var url;
|
||||
if (el.hasAttribute("href")) {
|
||||
// <a>
|
||||
url = el.getAttribute("href");
|
||||
} else {
|
||||
// buttons
|
||||
url = el.getAttribute("data-url");
|
||||
}
|
||||
var name = el.getAttribute("data-window-name");
|
||||
var tag = el.getAttribute("data-window-tag");
|
||||
var width = el.getAttribute("data-window-width");
|
||||
var height = el.getAttribute("data-window-height");
|
||||
evt.preventDefault();
|
||||
}
|
||||
createPopup(url, name, tag, width, height);
|
||||
});
|
||||
});
|
||||
|
||||
$j(".popup-link").click(function onClick(evt) {
|
||||
var el = this;
|
||||
var url;
|
||||
if (el.hasAttribute("href")) {
|
||||
// <a>
|
||||
url = el.getAttribute("href");
|
||||
} else {
|
||||
// buttons
|
||||
url = el.getAttribute("data-url");
|
||||
}
|
||||
var name = el.getAttribute("data-window-name");
|
||||
var tag = el.getAttribute("data-window-tag");
|
||||
var width = el.getAttribute("data-window-width");
|
||||
var height = el.getAttribute("data-window-height");
|
||||
createPopup(url, name, tag, width, height);
|
||||
evt.preventDefault();
|
||||
document.querySelectorAll(".tabList a").forEach(function addOnClick(el) {
|
||||
el.addEventListener("click", submitTab);
|
||||
});
|
||||
|
||||
$j(".tabList a").click(submitTab);
|
||||
|
||||
// 'data-on-click-this' calls the global function in the attribute value with the element when a click happens.
|
||||
document.querySelectorAll("a[data-on-click-this], button[data-on-click-this], input[data-on-click-this]").forEach(function attachOnClick(el) {
|
||||
var fnName = el.getAttribute("data-on-click-this");
|
||||
|
@ -167,6 +178,14 @@ $j(document).ready(function() {
|
|||
};
|
||||
});
|
||||
|
||||
// 'data-on-click-true' calls the global function in the attribute value with no arguments when a click happens.
|
||||
document.querySelectorAll("a[data-on-click-true], button[data-on-click-true], input[data-on-click-true]").forEach(function attachOnClick(el) {
|
||||
var fnName = el.getAttribute("data-on-click-true");
|
||||
el.onclick = function() {
|
||||
window[fnName](true);
|
||||
};
|
||||
});
|
||||
|
||||
// 'data-on-change-this' calls the global function in the attribute value with the element when a change happens.
|
||||
document.querySelectorAll("select[data-on-change-this], input[data-on-change-this]").forEach(function attachOnChangeThis(el) {
|
||||
var fnName = el.getAttribute("data-on-change-this");
|
||||
|
@ -250,7 +269,7 @@ if ( currentView != 'none' && currentView != 'login' ) {
|
|||
$j.ajaxSetup({timeout: AJAX_TIMEOUT}); //sets timeout for all getJSON.
|
||||
|
||||
$j(document).ready(function() {
|
||||
if ($j('.navbar').length) {
|
||||
if ( $j('.navbar').length ) {
|
||||
setInterval(getNavBar, navBarRefresh);
|
||||
}
|
||||
});
|
||||
|
@ -258,12 +277,12 @@ if ( currentView != 'none' && currentView != 'login' ) {
|
|||
function getNavBar() {
|
||||
$j.getJSON(thisUrl + '?view=request&request=status&entity=navBar')
|
||||
.done(setNavBar)
|
||||
.fail(function( jqxhr, textStatus, error ) {
|
||||
console.log( "Request Failed: " + textStatus + ", " + error);
|
||||
.fail(function(jqxhr, textStatus, error) {
|
||||
console.log("Request Failed: " + textStatus + ", " + error);
|
||||
if ( textStatus != "timeout" ) {
|
||||
// The idea is that this should only fail due to auth, so reload the page
|
||||
// which should go to login if it can't stay logged in.
|
||||
window.location.reload( true );
|
||||
window.location.reload(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -29,16 +29,20 @@ var AJAX_TIMEOUT = <?php echo ZM_WEB_AJAX_TIMEOUT ?>;
|
|||
var navBarRefresh = <?php echo 1000*ZM_WEB_REFRESH_NAVBAR ?>;
|
||||
|
||||
var currentView = '<?php echo $view ?>';
|
||||
var thisUrl = "<?php echo ZM_BASE_URL.$_SERVER['PHP_SELF'] ?>";
|
||||
var skinPath = "<?php echo ZM_SKIN_PATH ?>";
|
||||
<?php
|
||||
/* We can't trust PHP_SELF on a path like /index.php/"%3E%3Cimg src=x onerror=prompt('1');%3E which
|
||||
will still load index.php but will include the arbitrary payload after `.php/`. To mitigate this,
|
||||
try to avoid using PHP_SELF but here I try to replace everything after '.php'. */ ?>
|
||||
var thisUrl = '<?php echo ZM_BASE_URL.preg_replace('/\.php.*$/i', '.php', $_SERVER['PHP_SELF']) ?>';
|
||||
var skinPath = '<?php echo ZM_SKIN_PATH ?>';
|
||||
var serverId = '<?php echo defined('ZM_SERVER_ID') ? ZM_SERVER_ID : '' ?>';
|
||||
|
||||
var canEditSystem = <?php echo canEdit('System' )?'true':'false' ?>;
|
||||
var canViewSystem = <?php echo canView('System' )?'true':'false' ?>;
|
||||
var canEditEvents = <?php echo canEdit('Events' )?'true':'false' ?>;
|
||||
var canViewEvents = <?php echo canView('Events' )?'true':'false' ?>;
|
||||
var canEditSystem = <?php echo canEdit('System')?'true':'false' ?>;
|
||||
var canViewSystem = <?php echo canView('System')?'true':'false' ?>;
|
||||
var canEditEvents = <?php echo canEdit('Events')?'true':'false' ?>;
|
||||
var canViewEvents = <?php echo canView('Events')?'true':'false' ?>;
|
||||
|
||||
var canEditGroups = <?php echo canEdit('Groups' )?'true':'false' ?>;
|
||||
var canEditGroups = <?php echo canEdit('Groups')?'true':'false' ?>;
|
||||
|
||||
var refreshParent = <?php
|
||||
if ( ! empty($refreshParent) ) {
|
||||
|
|
|
@ -29,14 +29,15 @@ if ( empty($_COOKIE['zmBandwidth']) )
|
|||
//if ( $skinLangFile = loadLanguage( ZM_SKIN_PATH ) )
|
||||
//require_once( $skinLangFile );
|
||||
|
||||
foreach ( getSkinIncludes( 'includes/config.php' ) as $includeFile )
|
||||
foreach ( getSkinIncludes('includes/config.php') as $includeFile )
|
||||
require_once $includeFile;
|
||||
|
||||
foreach ( getSkinIncludes( 'includes/functions.php' ) as $includeFile )
|
||||
foreach ( getSkinIncludes('includes/functions.php') as $includeFile )
|
||||
require_once $includeFile;
|
||||
|
||||
if ( empty($view) )
|
||||
if ( empty($view) ) {
|
||||
$view = isset($user)?'console':'login';
|
||||
}
|
||||
|
||||
if ( !isset($user) && ZM_OPT_USE_AUTH && ZM_AUTH_TYPE == 'remote' && !empty( $_SERVER['REMOTE_USER']) ) {
|
||||
$view = 'postlogin';
|
||||
|
|
|
@ -95,7 +95,7 @@ if ( ! empty($user['MonitorIds']) ) {
|
|||
}
|
||||
|
||||
$html .= '<span class="MonitorNameFilter"><label>'.translate('Name').'</label>';
|
||||
$html .= '<input type="text" name="MonitorName" value="'.(isset($_SESSION['MonitorName'])?$_SESSION['MonitorName']:'').'" placeholder="text or regular expression"/>';
|
||||
$html .= '<input type="text" name="MonitorName" value="'.(isset($_SESSION['MonitorName'])?validHtmlStr($_SESSION['MonitorName']):'').'" placeholder="text or regular expression"/>';
|
||||
$html .= '</span>';
|
||||
|
||||
$Functions = array();
|
||||
|
@ -160,7 +160,7 @@ $html .= htmlSelect( 'Status[]', $status_options,
|
|||
$html .= '</span>';
|
||||
|
||||
$html .= '<span class="SourceFilter"><label>'.translate('Source').'</label>';
|
||||
$html .= '<input type="text" name="Source" value="'.(isset($_SESSION['Source'])?$_SESSION['Source']:'').'" placeholder="text or regular expression"/>';
|
||||
$html .= '<input type="text" name="Source" value="'.(isset($_SESSION['Source'])?validHtmlStr($_SESSION['Source']):'').'" placeholder="text or regular expression"/>';
|
||||
$html .= '</span>';
|
||||
|
||||
$sql = 'SELECT *,S.Status AS Status, S.CaptureFPS AS CaptureFPS, S.AnalysisFPS AS AnalysisFPS, S.CaptureBandwidth AS CaptureBandwidth
|
||||
|
|
|
@ -33,7 +33,7 @@ xhtmlHeaders(__FILE__, translate('AddMonitors'));
|
|||
<?php echo $navbar ?>
|
||||
<div id="content">
|
||||
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<div style="position:relative;">
|
||||
<div id="results" style="position: absolute; top:0; right: 0; width: 50%; height: 100%;">
|
||||
<fieldset><legend>Results</legend>
|
||||
|
|
|
@ -20,22 +20,19 @@
|
|||
|
||||
$newBandwidth = $_COOKIE['zmBandwidth'];
|
||||
|
||||
if ( $user && !empty($user['MaxBandwidth']) )
|
||||
{
|
||||
if ( $user['MaxBandwidth'] == "low" )
|
||||
{
|
||||
unset( $bandwidth_options['high'] );
|
||||
unset( $bandwidth_options['medium'] );
|
||||
}
|
||||
elseif ( $user['MaxBandwidth'] == "medium" )
|
||||
{
|
||||
unset( $bandwidth_options['high'] );
|
||||
}
|
||||
# Limit available options to what are available in user
|
||||
if ( $user && !empty($user['MaxBandwidth']) ) {
|
||||
if ( $user['MaxBandwidth'] == 'low' ) {
|
||||
unset($bandwidth_options['high']);
|
||||
unset($bandwidth_options['medium']);
|
||||
} else if ( $user['MaxBandwidth'] == 'medium' ) {
|
||||
unset($bandwidth_options['high']);
|
||||
}
|
||||
}
|
||||
|
||||
$focusWindow = true;
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('Bandwidth') );
|
||||
xhtmlHeaders(__FILE__, translate('Bandwidth'));
|
||||
?>
|
||||
<body>
|
||||
<div id="page">
|
||||
|
@ -43,13 +40,14 @@ xhtmlHeaders(__FILE__, translate('Bandwidth') );
|
|||
<h2><?php echo translate('Bandwidth') ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="bandwidth"/>
|
||||
<input type="hidden" name="action" value="bandwidth"/>
|
||||
<p><?php echo translate('SetNewBandwidth') ?></p>
|
||||
<p><?php echo buildSelect( "newBandwidth", $bandwidth_options ) ?></p>
|
||||
<p><?php echo buildSelect('newBandwidth', $bandwidth_options) ?></p>
|
||||
<div id="contentButtons">
|
||||
<input type="submit" value="<?php echo translate('Save') ?>"/><input type="button" value="<?php echo translate('Cancel') ?>" data-on-click="closeWindow"/>
|
||||
<button type="submit" value="Save"><?php echo translate('Save') ?></button>
|
||||
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -160,7 +160,7 @@ if ( $show_storage_areas ) $left_columns += 1;
|
|||
xhtmlHeaders( __FILE__, translate('Console') );
|
||||
getBodyTopHTML();
|
||||
?>
|
||||
<form name="monitorForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="monitorForm" method="get" action="?">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value=""/>
|
||||
|
||||
|
@ -280,7 +280,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
|||
$Groups = $Group->Parents();
|
||||
array_push( $Groups, $Group );
|
||||
}
|
||||
return implode(' > ', array_map(function($Group){ return '<a href="'. ZM_BASE_URL.$_SERVER['PHP_SELF'].'?view=montagereview&GroupId='.$Group->Id().'">'.$Group->Name().'</a>'; }, $Groups ));
|
||||
return implode(' > ', array_map(function($Group){ return '<a href="?view=montagereview&GroupId='.$Group->Id().'">'.$Group->Name().'</a>'; }, $Groups ));
|
||||
}, $Monitor->GroupIds() ) );
|
||||
?>
|
||||
</div></td>
|
||||
|
@ -308,7 +308,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
|||
<td class="colServer"><?php $Server = isset($ServersById[$monitor['ServerId']]) ? $ServersById[$monitor['ServerId']] : new Server( $monitor['ServerId'] ); echo $Server->Name(); ?></td>
|
||||
<?php
|
||||
}
|
||||
echo '<td class="colSource">'. makePopupLink( '?view=monitor&mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$source_class.'">'.$Monitor->Source().'</span>', canEdit('Monitors') ).'</td>';
|
||||
echo '<td class="colSource">'. makePopupLink( '?view=monitor&mid='.$monitor['Id'], 'zmMonitor'.$monitor['Id'], 'monitor', '<span class="'.$source_class.'">'.validHtmlStr($Monitor->Source()).'</span>', canEdit('Monitors') ).'</td>';
|
||||
if ( $show_storage_areas ) {
|
||||
?>
|
||||
<td class="colStorage"><?php if ( isset($StorageById[$monitor['StorageId']]) ) { echo $StorageById[ $monitor['StorageId'] ]->Name(); } ?></td>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView( 'Control' ) ) {
|
||||
if ( !canView('Control') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
@ -26,16 +26,16 @@ if ( !canView( 'Control' ) ) {
|
|||
$params = array();
|
||||
$groupSql = '';
|
||||
if ( !empty($_REQUEST['group']) ) {
|
||||
$groupSql = " AND gm.GroupId = :groupid";
|
||||
$params[":groupid"] = $_REQUEST['group'];
|
||||
$groupSql = ' AND gm.GroupId = :groupid';
|
||||
$params[':groupid'] = $_REQUEST['group'];
|
||||
}
|
||||
|
||||
$mid = !empty($_REQUEST['mid']) ? validInt($_REQUEST['mid']) : 0;
|
||||
|
||||
$sql = "SELECT m.* FROM Monitors m INNER JOIN Groups_Monitors AS gm ON m.Id = gm.MonitorId WHERE m.Function != 'None' AND m.Controllable = 1$groupSql ORDER BY Sequence";
|
||||
$mids = array();
|
||||
foreach( dbFetchAll( $sql, false, $params ) as $row ) {
|
||||
if ( !visibleMonitor( $row['Id'] ) ) {
|
||||
foreach ( dbFetchAll($sql, false, $params) as $row ) {
|
||||
if ( !visibleMonitor($row['Id']) ) {
|
||||
continue;
|
||||
}
|
||||
if ( empty($mid) )
|
||||
|
@ -43,14 +43,14 @@ foreach( dbFetchAll( $sql, false, $params ) as $row ) {
|
|||
$mids[$row['Id']] = $row['Name'];
|
||||
}
|
||||
|
||||
foreach ( getSkinIncludes( 'includes/control_functions.php' ) as $includeFile )
|
||||
foreach ( getSkinIncludes('includes/control_functions.php') as $includeFile )
|
||||
require_once $includeFile;
|
||||
|
||||
$monitor = new Monitor( $mid );
|
||||
$monitor = new Monitor($mid);
|
||||
|
||||
$focusWindow = true;
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('Control') );
|
||||
xhtmlHeaders(__FILE__, translate('Control'));
|
||||
?>
|
||||
<body>
|
||||
<div id="page">
|
||||
|
@ -60,15 +60,15 @@ xhtmlHeaders(__FILE__, translate('Control') );
|
|||
</div>
|
||||
<h2><?php echo translate('Control') ?></h2>
|
||||
<div id="headerControl">
|
||||
<form name="contentForm" id="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="get" action="?">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<?php echo buildSelect( "mid", $mids, "this.form.submit();" ); ?>
|
||||
<?php echo buildSelect('mid', $mids, 'this.form.submit();'); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="ptzControls" class="ptzControls">
|
||||
<?php echo ptzControls( $monitor ) ?>
|
||||
<?php echo ptzControls($monitor) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -183,7 +183,7 @@ foreach ( $tabs as $name=>$value )
|
|||
?>
|
||||
</ul>
|
||||
<div class="clear"></div>
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>" class="validateFormOnSubmit">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?" class="validateFormOnSubmit">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
|
||||
<input type="hidden" name="action" value="controlcap"/>
|
||||
|
|
|
@ -39,7 +39,7 @@ xhtmlHeaders(__FILE__, translate('ControlCaps') );
|
|||
<h2><?php echo translate('ControlCaps') ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>" onsubmit="return( confirmDelete( 'Warning, deleting a control will reset all monitors that use it to be uncontrollable.\nAre you sure you wish to delete?' ) );">
|
||||
<form name="contentForm" id="contentForm" method="get" action="?" onsubmit="return( confirmDelete( 'Warning, deleting a control will reset all monitors that use it to be uncontrollable.\nAre you sure you wish to delete?' ) );">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value="delete"/>
|
||||
<table id="contentTable" class="major" cellspacing="0">
|
||||
|
@ -63,9 +63,9 @@ foreach( $controls as $control )
|
|||
{
|
||||
?>
|
||||
<tr>
|
||||
<td class="colName"><?php echo makePopupLink( '?view=controlcap&cid='.$control['Id'], 'zmControlCap', 'controlcap', $control['Name'], canView( 'Control' ) ) ?></td>
|
||||
<td class="colName"><?php echo makePopupLink( '?view=controlcap&cid='.$control['Id'], 'zmControlCap', 'controlcap', validHtmlStr($control['Name']), canView( 'Control' ) ) ?></td>
|
||||
<td class="colType"><?php echo $control['Type'] ?></td>
|
||||
<td class="colProtocol"><?php echo $control['Protocol'] ?></td>
|
||||
<td class="colProtocol"><?php echo validHtmlStr($control['Protocol']) ?></td>
|
||||
<td class="colCanMove"><?php echo $control['CanMove']?translate('Yes'):translate('No') ?></td>
|
||||
<td class="colCanZoom"><?php echo $control['CanZoom']?translate('Yes'):translate('No') ?></td>
|
||||
<td class="colCanFocus"><?php echo $control['CanFocus']?translate('Yes'):translate('No') ?></td>
|
||||
|
|
|
@ -48,7 +48,7 @@ xhtmlHeaders(__FILE__, translate('SetPreset') );
|
|||
<h2><?php echo translate('SetPreset') ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="mid" value="<?php echo $monitor['Id'] ?>"/>
|
||||
<input type="hidden" name="action" value="control"/>
|
||||
|
|
|
@ -41,7 +41,7 @@ xhtmlHeaders( __FILE__, translate('Device')." - ".$newDevice['Name'] );
|
|||
<h2><?php echo translate('Device')." - ".validHtmlStr($newDevice['Name']) ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" method="get" action="?">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="action" value="device"/>
|
||||
<input type="hidden" name="did" value="<?php echo $newDevice['Id'] ?>"/>
|
||||
|
|
|
@ -40,7 +40,7 @@ xhtmlHeaders(__FILE__, translate('Devices') );
|
|||
<h2><?php echo translate('Devices') ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" method="get" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="action" value="device"/>
|
||||
<input type="hidden" name="key" value=""/>
|
||||
|
|
|
@ -45,7 +45,7 @@ xhtmlHeaders(__FILE__, translate('Donate') );
|
|||
<h1>ZoneMinder - <?php echo translate('Donate') ?></h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="action" value="donate"/>
|
||||
<p>
|
||||
|
|
|
@ -45,6 +45,23 @@ if (isset($_SESSION['montageReviewFilter']) and !isset($_REQUEST['eids']) ) {
|
|||
#Logger::Debug("NO montageReviewFilter");
|
||||
}
|
||||
|
||||
$exportFormat = '';
|
||||
if (isset($_REQUEST['exportFormat'])) {
|
||||
if (!in_array($_REQUEST['exportFormat'], array('zip', 'tar'))) {
|
||||
Error('Invalid exportFormat');
|
||||
return;
|
||||
}
|
||||
$exportFormat = $_REQUEST['exportFormat'];
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['eid'])) {
|
||||
$Event = new Event( $_REQUEST['eid'] );
|
||||
if (!$Event->Id) {
|
||||
Error('Invalid event id');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$focusWindow = true;
|
||||
$connkey = isset($_REQUEST['connkey']) ? $_REQUEST['connkey'] : generateConnKey();
|
||||
|
||||
|
@ -67,7 +84,7 @@ if ( !empty($_REQUEST['eid']) ) {
|
|||
<input type="hidden" name="id" value="<?php echo validInt($_REQUEST['eid']) ?>"/>
|
||||
<?php
|
||||
$Event = new Event($_REQUEST['eid']);
|
||||
echo 'Downloading event ' . $_REQUEST['eid'] . ' Resulting file should be approximately ' . human_filesize( $Event->DiskSpace() );
|
||||
echo 'Downloading event ' . $Event->Id . '. Resulting file should be approximately ' . human_filesize( $Event->DiskSpace() );
|
||||
} else if ( !empty($_REQUEST['eids']) ) {
|
||||
$total_size = 0;
|
||||
foreach ( $_REQUEST['eids'] as $eid ) {
|
||||
|
@ -95,9 +112,9 @@ if ( !empty($_REQUEST['eid']) ) {
|
|||
<tr>
|
||||
<th scope="row"><?php echo translate('ExportFormat') ?></th>
|
||||
<td>
|
||||
<input type="radio" id="exportFormatTar" name="exportFormat" value="tar" data-on-click-this="configureExportButton"/>
|
||||
<input type="radio" id="exportFormatTar" name="exportFormat" value="tar"/>
|
||||
<label for="exportFormatTar"><?php echo translate('ExportFormatTar') ?></label>
|
||||
<input type="radio" id="exportFormatZip" name="exportFormat" value="zip" checked="checked" data-on-click-this="configureExportButton"/>
|
||||
<input type="radio" id="exportFormatZip" name="exportFormat" value="zip" checked="checked"/>
|
||||
<label for="exportFormatZip"><?php echo translate('ExportFormatZip') ?></label>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -126,7 +143,7 @@ if ( !empty($_REQUEST['eid']) ) {
|
|||
}
|
||||
if ( !empty($_REQUEST['generated']) ) {
|
||||
?>
|
||||
<h3 id="downloadLink"><a href="<?php echo validHtmlStr($_REQUEST['exportFile']) ?>"><?php echo translate('Download') ?></a></h3>
|
||||
<h3 id="downloadLink"><a href="?view=archive&type=<?php echo $exportFormat; ?>"><?php echo translate('Download') ?></a></h3>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -74,7 +74,7 @@ if ( $mode == 'single' ) {
|
|||
?>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="action" value="eventdetail"/>
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<?php
|
||||
|
|
|
@ -79,7 +79,9 @@ $pagination = getPagination($pages, $page, $maxShortcuts, $filterQuery.$sortQuer
|
|||
$focusWindow = true;
|
||||
|
||||
if ( $_POST ) {
|
||||
header('Location: ' . $_SERVER['REQUEST_URI'].htmlspecialchars_decode($filterQuery).htmlspecialchars_decode($sortQuery).$limitQuery.'&page='.$page);
|
||||
// I think this is basically so that a refresh doesn't repost
|
||||
Logger::Debug("Redirecting to " . $_SERVER['REQUEST_URI']);
|
||||
header('Location: ?view=' . $view.htmlspecialchars_decode($filterQuery).htmlspecialchars_decode($sortQuery).$limitQuery.'&page='.$page);
|
||||
exit();
|
||||
}
|
||||
|
||||
|
@ -98,7 +100,7 @@ xhtmlHeaders(__FILE__, translate('Events') );
|
|||
<div id="header">
|
||||
<div id="info">
|
||||
<h2><?php echo sprintf($CLANG['EventCount'], $nEvents, zmVlang($VLANG['Event'], $nEvents)) ?></h2>
|
||||
<a id="refreshLink" href="#" onclick="location.reload(true);"><?php echo translate('Refresh') ?></a>
|
||||
<a id="refreshLink" href="#"><?php echo translate('Refresh') ?></a>
|
||||
</div>
|
||||
<div id="pagination">
|
||||
<?php
|
||||
|
@ -123,7 +125,7 @@ if ( $pages > 1 ) {
|
|||
?>
|
||||
</div>
|
||||
<div id="controls">
|
||||
<a href="#" onclick="window.history.back();return false;"><?php echo translate('Back') ?></a>
|
||||
<a href="#" id="backLink"><?php echo translate('Back') ?></a>
|
||||
<a id="timelineLink" href="?view=timeline<?php echo $filterQuery ?>"><?php echo translate('ShowTimeline') ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -188,11 +190,27 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
$scale = max( reScale( SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
||||
?>
|
||||
<tr<?php if ($event->Archived()) echo ' class="archived"' ?>>
|
||||
<td class="colId"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1"> '.$event->Id().($event->Archived()?'*':'') ?></a></td>
|
||||
<td class="colName"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1"> '.validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a></td>
|
||||
<td class="colId"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.$event->Id().($event->Archived()?'*':'') ?></a></td>
|
||||
<td class="colName"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a></td>
|
||||
<td class="colMonitorName"><?php echo makePopupLink( '?view=monitor&mid='.$event->MonitorId(), 'zmMonitor'.$event->Monitorid(), 'monitor', $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
|
||||
<td class="colCause"><?php echo makePopupLink( '?view=eventdetail&eid='.$event->Id(), 'zmEventDetail', 'eventdetail', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="'.htmlspecialchars($event->Notes()).'"' ) ?>
|
||||
<?php if ($event->Notes() && ($event->Notes() != 'Forced Web: ')) echo "<br/><div class=\"small text-nowrap text-muted\">".$event->Notes()."</div>" ?></td>
|
||||
<?php
|
||||
# display notes as small text
|
||||
if ($event->Notes()) {
|
||||
# if notes include detection objects, then link it to objdetect.jpg
|
||||
if (strpos($event->Notes(),"detected:")!== false){
|
||||
# make a link
|
||||
echo makePopupLink( '?view=image&eid='.$event->Id().'&fid=objdetect', 'zmImage',
|
||||
array('image', reScale($event->Width(), $scale), reScale($event->Height(), $scale)),
|
||||
"<div class=\"small text-nowrap text-muted\"><u>".$event->Notes()."</u></div>");
|
||||
}
|
||||
elseif ($event->Notes() != 'Forced Web: ') {
|
||||
echo "<br/><div class=\"small text-nowrap text-muted\">".$event->Notes()."</div>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</td>
|
||||
<td class="colTime"><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) .
|
||||
( $event->EndTime() ? ' until ' . strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime()) ) : '' ) ?>
|
||||
</td>
|
||||
|
@ -225,12 +243,12 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
$streamSrc = $event->getStreamSrc(array(
|
||||
'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single'));
|
||||
|
||||
$imgHtml = '<img id="thumbnail'.$event->id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($event->ThumbnailWidth()) .'px;height:'. validInt($event->ThumbnailHeight()).'px;" onmouseover="this.src=\''.$streamSrc.'\';" onmouseout="this.src=\''.$imgSrc.'\';"/>';
|
||||
$imgHtml = '<img id="thumbnail'.$event->id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($event->ThumbnailWidth()) .'px;height:'. validInt($event->ThumbnailHeight()).'px;" stream_src="'.$streamSrc.'" still_src="'.$imgSrc.'"/>';
|
||||
echo '<a href="?view=event&eid='. $event->Id().$filterQuery.$sortQuery.'&page=1">'.$imgHtml.'</a>';
|
||||
echo '</td>';
|
||||
} // end if ZM_WEB_LIST_THUMBS
|
||||
?>
|
||||
<td class="colMark"><input type="checkbox" name="eids[]" value="<?php echo $event->Id() ?>" onclick="configureButton(this, 'eids[]');"/></td>
|
||||
<td class="colMark"><input type="checkbox" name="eids[]" value="<?php echo $event->Id() ?>" data-on-click-this="configureButton"/></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
@ -272,25 +290,25 @@ if ( $pagination ) {
|
|||
}
|
||||
?>
|
||||
<div id="contentButtons">
|
||||
<button type="button" name="viewBtn" value="View" onclick="viewEvents(this, 'eids[]');" disabled="disabled">
|
||||
<?php echo translate('View') ?>"
|
||||
<button type="button" name="viewBtn" value="View" data-on-click-this="viewEvents" disabled="disabled">
|
||||
<?php echo translate('View') ?>
|
||||
</button>
|
||||
<button type="button" name="archiveBtn" value="Archive" onclick="archiveEvents(this, 'eids[]')" disabled="disabled">
|
||||
<button type="button" name="archiveBtn" value="Archive" data-on-click-this="archiveEvents" disabled="disabled">
|
||||
<?php echo translate('Archive') ?>
|
||||
</button>
|
||||
<button type="button" name="unarchiveBtn" value="Unarchive" onclick="unarchiveEvents(this, 'eids[]');" disabled="disabled">
|
||||
<button type="button" name="unarchiveBtn" value="Unarchive" data-on-click-this="unarchiveEvents" disabled="disabled">
|
||||
<?php echo translate('Unarchive') ?>
|
||||
</button>
|
||||
<button type="button" name="editBtn" value="Edit" onclick="editEvents(this, 'eids[]')" disabled="disabled">
|
||||
<button type="button" name="editBtn" value="Edit" data-on-click-this="editEvents" disabled="disabled">
|
||||
<?php echo translate('Edit') ?>
|
||||
</button>
|
||||
<button type="button" name="exportBtn" value="Export" onclick="exportEvents(this, 'eids[]')" disabled="disabled">
|
||||
<button type="button" name="exportBtn" value="Export" data-on-click-this="exportEvents" disabled="disabled">
|
||||
<?php echo translate('Export') ?>
|
||||
</button>
|
||||
<button type="button" name="downloadBtn" value="DownloadVideo" onclick="downloadVideo(this, 'eids[]')" disabled="disabled">
|
||||
<button type="button" name="downloadBtn" value="DownloadVideo" data-on-click-this="downloadVideo" disabled="disabled">
|
||||
<?php echo translate('DownloadVideo') ?>
|
||||
</button>
|
||||
<button type="button" name="deleteBtn" value="Delete" onclick="deleteEvents(this, 'eids[]');" disabled="disabled">
|
||||
<button type="button" name="deleteBtn" value="Delete" data-on-click-this="deleteEvents" disabled="disabled">
|
||||
<?php echo translate('Delete') ?>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -299,6 +317,7 @@ if ( $pagination ) {
|
|||
</div>
|
||||
<script nonce="<?php echo $cspNonce;?>">
|
||||
// These are defined in the .js.php but need to be updated down here.
|
||||
// This might be better done by selecting through the dom for the archived class
|
||||
archivedEvents = <?php echo !empty($archived)?'true':'false' ?>;
|
||||
unarchivedEvents = <?php echo !empty($unarchived)?'true':'false' ?>;
|
||||
</script>
|
||||
|
|
|
@ -47,6 +47,13 @@ if ( isset($_SESSION['export']) ) {
|
|||
$_REQUEST['exportCompress'] = 0;
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['exportFormat'])) {
|
||||
if (!in_array($_REQUEST['exportFormat'], array('zip', 'tar'))) {
|
||||
Error('Invalid exportFormat');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$focusWindow = true;
|
||||
$connkey = isset($_REQUEST['connkey']) ? $_REQUEST['connkey'] : generateConnKey();
|
||||
|
||||
|
@ -205,7 +212,7 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="button" id="exportButton" name="exportButton" value="Export" onclick="exportEvent(this.form);" disabled="disabled"><?php echo translate('Export') ?></button>
|
||||
<button type="button" id="exportButton" name="exportButton" value="Export" disabled="disabled"><?php echo translate('Export') ?></button>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
|
|
|
@ -50,18 +50,15 @@ if ( isset($_REQUEST['sort_field']) && isset($_REQUEST['filter']) ) {
|
|||
}
|
||||
|
||||
if ( isset($_REQUEST['filter']) ) {
|
||||
$filter->set( $_REQUEST['filter'] );
|
||||
$filter->set($_REQUEST['filter']);
|
||||
# Update our filter object with whatever changes we have made before saving
|
||||
}
|
||||
|
||||
$conjunctionTypes = array(
|
||||
'and' => translate('ConjAnd'),
|
||||
'or' => translate('ConjOr')
|
||||
);
|
||||
$conjunctionTypes = getFilterQueryConjunctionTypes();
|
||||
$obracketTypes = array();
|
||||
$cbracketTypes = array();
|
||||
|
||||
if (count($filter->terms()) > 0) {
|
||||
if ( count($filter->terms()) > 0 ) {
|
||||
$terms = $filter->terms();
|
||||
} else {
|
||||
$terms[] = array();
|
||||
|
@ -162,13 +159,13 @@ xhtmlHeaders(__FILE__, translate('EventFilter') );
|
|||
<div id="page">
|
||||
<?php echo $navbar = getNavBarHTML(); ?>
|
||||
<div id="content">
|
||||
<form name="selectForm" id="selectForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="selectForm" id="selectForm" method="get" action="?">
|
||||
<input type="hidden" name="view" value="filter"/>
|
||||
<hr/>
|
||||
<div id="filterSelector"><label for="<?php echo 'Id' ?>"><?php echo translate('UseFilter') ?></label>
|
||||
<?php
|
||||
if ( count($filterNames) > 1 ) {
|
||||
echo htmlSelect('Id', $filterNames, $filter->Id(), 'this.form.submit();');
|
||||
echo htmlSelect('Id', $filterNames, $filter->Id(), array('data-on-change-this'=>'selectFilter'));
|
||||
} else {
|
||||
?><select disabled="disabled"><option><?php echo translate('NoSavedFilters') ?></option></select>
|
||||
<?php
|
||||
|
@ -180,9 +177,9 @@ if ( (null !== $filter->Concurrent()) and $filter->Concurrent() )
|
|||
?>
|
||||
</div>
|
||||
</form>
|
||||
<form name="contentForm" id="contentForm" method="post" class="validateFormOnSubmit">
|
||||
<form name="contentForm" id="contentForm" method="post" class="validateFormOnSubmit" action="?view=filter">
|
||||
<input type="hidden" name="Id" value="<?php echo $filter->Id() ?>"/>
|
||||
<input type="hidden" name="action" value=""/>
|
||||
<input type="hidden" name="action"/>
|
||||
<input type="hidden" name="object" value="filter"/>
|
||||
|
||||
<hr/>
|
||||
|
@ -191,7 +188,7 @@ if ( (null !== $filter->Concurrent()) and $filter->Concurrent() )
|
|||
<?php } ?>
|
||||
<p class="Name">
|
||||
<label for="filter[Name]"><?php echo translate('Name') ?></label>
|
||||
<input type="text" id="filter[Name]" name="filter[Name]" value="<?php echo $filter->Name() ?>" oninput="updateButtons(this);"/>
|
||||
<input type="text" id="filter[Name]" name="filter[Name]" value="<?php echo validHtmlStr($filter->Name()) ?>" oninput="updateButtons(this);"/>
|
||||
</p>
|
||||
<table id="fieldsTable" class="filterTable">
|
||||
<tbody>
|
||||
|
@ -284,13 +281,13 @@ for ( $i=0; $i < count($terms); $i++ ) {
|
|||
} else {
|
||||
?>
|
||||
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||
<td><input type="text" name="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo $term['val'] ?>"/></td>
|
||||
<td><input type="text" name="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo validHtmlStr($term['val']) ?>"/></td>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||
<td><input type="text" name="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?$term['val']:'' ?>"/></td>
|
||||
<td><input type="text" name="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?validHtmlStr($term['val']):'' ?>"/></td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -388,7 +385,7 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
<p>
|
||||
<label><?php echo translate('FilterExecuteEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoExecute]" value="1"<?php if ( $filter->AutoExecute() ) { ?> checked="checked"<?php } ?>/>
|
||||
<input type="text" name="filter[AutoExecuteCmd]" value="<?php echo (null !==$filter->AutoExecuteCmd())?$filter->AutoExecuteCmd():'' ?>" maxlength="255" data-on-change-this="updateButtons"/>
|
||||
<input type="text" name="filter[AutoExecuteCmd]" value="<?php echo (null !==$filter->AutoExecuteCmd())?validHtmlStr($filter->AutoExecuteCmd()):'' ?>" maxlength="255" data-on-change-this="updateButtons"/>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php echo translate('FilterDeleteEvents') ?></label>
|
||||
|
@ -396,7 +393,7 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
</p>
|
||||
<p><label><?php echo translate('FilterMoveEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoMove]" value="1"<?php if ( $filter->AutoMove() ) { ?> checked="checked"<?php } ?> onclick="updateButtons(this);if(this.checked){$j(this.form.elements['filter[AutoMoveTo]']).css('display','inline');}else{this.form.elements['filter[AutoMoveTo]'].hide();};"/>
|
||||
<?php echo htmlSelect( "filter[AutoMoveTo]", $storageareas, $filter->AutoMoveTo(), $filter->AutoMove() ? null : array('style'=>'display:none;' ) ); ?>
|
||||
<?php echo htmlSelect('filter[AutoMoveTo]', $storageareas, $filter->AutoMoveTo(), $filter->AutoMove() ? null : array('style'=>'display:none;' )); ?>
|
||||
</p>
|
||||
<p>
|
||||
<label for="background"><?php echo translate('BackgroundFilter') ?></label>
|
||||
|
@ -411,7 +408,7 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
<div id="contentButtons">
|
||||
<button type="submit" data-on-click-this="submitToEvents"><?php echo translate('ListMatches') ?></button>
|
||||
<button type="button" data-on-click-this="submitToExport"><?php echo translate('ExportMatches') ?></button>
|
||||
<button type="submit" name="executeButton" id="executeButton" data-on-click-this="executeFilter"><?php echo translate('Execute') ?></button>
|
||||
<button type="button" name="executeButton" id="executeButton" data-on-click-this="executeFilter"><?php echo translate('Execute') ?></button>
|
||||
<?php
|
||||
if ( canEdit('Events') ) {
|
||||
?>
|
||||
|
@ -420,7 +417,7 @@ if ( canEdit('Events') ) {
|
|||
<?php
|
||||
if ( $filter->Id() ) {
|
||||
?>
|
||||
<button type="button" value="Delete" onclick="deleteFilter(this, '<?php echo $filter->Name() ?>');"><?php echo translate('Delete') ?></button>
|
||||
<button type="button" value="Delete" data-on-click-this="deleteFilter"><?php echo translate('Delete') ?></button>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,14 +51,15 @@ $lastFid = $maxFid;
|
|||
$alarmFrame = $Frame->Type()=='Alarm';
|
||||
|
||||
if ( isset( $_REQUEST['scale'] ) ) {
|
||||
$scale = $_REQUEST['scale'];
|
||||
$scale = validNum($_REQUEST['scale']);
|
||||
} else if ( isset( $_COOKIE['zmWatchScale'.$Monitor->Id()] ) ) {
|
||||
$scale = $_COOKIE['zmWatchScale'.$Monitor->Id()];
|
||||
$scale = validNum($_COOKIE['zmWatchScale'.$Monitor->Id()]);
|
||||
} else if ( isset( $_COOKIE['zmWatchScale'] ) ) {
|
||||
$scale = $_COOKIE['zmWatchScale'];
|
||||
$scale = validNum($_COOKIE['zmWatchScale']);
|
||||
} else {
|
||||
$scale = max( reScale( SCALE_BASE, $Monitor->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
||||
}
|
||||
$scale = $scale ?: "auto";
|
||||
|
||||
$imageData = $Event->getImageSrc( $frame, $scale, 0 );
|
||||
if ( ! $imageData ) {
|
||||
|
@ -67,7 +68,7 @@ if ( ! $imageData ) {
|
|||
}
|
||||
|
||||
$show = 'capt';
|
||||
if ( isset($_REQUEST['show']) ) {
|
||||
if (isset($_REQUEST['show']) && in_array($_REQUEST['show'], array('capt', 'anal'))) {
|
||||
$show = $_REQUEST['show'];
|
||||
} else if ( $imageData['hasAnalImage'] ) {
|
||||
$show = 'anal';
|
||||
|
@ -89,9 +90,9 @@ xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id()." - ".$Frame->Frame
|
|||
<div id="headerButtons">
|
||||
<?php if ( ZM_RECORD_EVENT_STATS && $alarmFrame ) { echo makePopupLink( '?view=stats&eid='.$Event->Id().'&fid='.$Frame->FrameId(), 'zmStats', 'stats', translate('Stats') ); } ?>
|
||||
<?php if ( canEdit( 'Events' ) ) { ?><a href="?view=none&action=delete&markEid=<?php echo $Event->Id() ?>"><?php echo translate('Delete') ?></a><?php } ?>
|
||||
<a href="#" onclick="closeWindow(); return( false );"><?php echo translate('Close') ?></a>
|
||||
<a href="#" data-on-click="closeWindow"><?php echo translate('Close') ?></a>
|
||||
</div>
|
||||
<div id="scaleControl"><label for="scale"><?php echo translate('Scale') ?></label><?php echo buildSelect('scale', $scales, 'changeScale();'); ?></div>
|
||||
<div id="scaleControl"><label for="scale"><?php echo translate('Scale') ?></label><?php echo buildSelect('scale', $scales); ?></div>
|
||||
<h2><?php echo translate('Frame') ?> <?php echo $Event->Id().'-'.$Frame->FrameId().' ('.$Frame->Score().')' ?></h2>
|
||||
<input type="hidden" name="base_width" id="base_width" value="<?php echo $Event->Width(); ?>"/>
|
||||
<input type="hidden" name="base_height" id="base_height" value="<?php echo $Event->Height(); ?>"/>
|
||||
|
@ -103,19 +104,19 @@ xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id()." - ".$Frame->Frame
|
|||
<?php if ( $imageData['hasAnalImage'] ) {
|
||||
echo sprintf('<a href="?view=frame&eid=%d&fid=%d&scale=%d&show=%s">', $Event->Id(), $Frame->FrameId(), $scale, ( $show=='anal'?'capt':'anal' ) );
|
||||
} ?>
|
||||
<img id="frameImg" src="<?php echo $Frame->getImageSrc($show=='anal'?'analyse':'capture') ?>" width="<?php echo reScale( $Event->Width(), $Event->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Event->DefaultScale(), $scale ) ?>" alt="<?php echo $Frame->EventId()."-".$Frame->FrameId() ?>" class="<?php echo $imageData['imageClass'] ?>"/>
|
||||
<img id="frameImg" src="<?php echo validHtmlStr($Frame->getImageSrc($show=='anal'?'analyse':'capture')) ?>" width="<?php echo reScale( $Event->Width(), $Event->DefaultScale(), $scale ) ?>" height="<?php echo reScale( $Event->Height(), $Event->DefaultScale(), $scale ) ?>" alt="<?php echo $Frame->EventId()."-".$Frame->FrameId() ?>" class="<?php echo $imageData['imageClass'] ?>"/>
|
||||
<?php if ( $imageData['hasAnalImage'] ) { ?></a><?php } ?>
|
||||
|
||||
</p>
|
||||
<p id="controls">
|
||||
<?php if ( $Frame->FrameId() > 1 ) { ?>
|
||||
<button type="button" id="firstLink" onclick="window.location='?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $firstFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>';"><?php echo translate('First') ?></button>
|
||||
<button type="button" id="prevLink" onclick="window.location='?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $prevFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>';"><?php echo translate('Prev') ?></button>
|
||||
<a class="btn-primary" id="firstLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $firstFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>"><?php echo translate('First') ?></a>
|
||||
<a class="btn-primary" id="prevLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $prevFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>"><?php echo translate('Prev') ?></a>
|
||||
<?php
|
||||
}
|
||||
if ( $Frame->FrameId() < $maxFid ) { ?>
|
||||
<button type="button" id="nextLink" onclick="window.location='?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $nextFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>';"><?php echo translate('Next') ?></button>
|
||||
<button type="button" id="lastLink" onclick="window.location='?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $lastFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>';"><?php echo translate('Last') ?></button>
|
||||
<a class="btn-primary" id="nextLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $nextFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>"><?php echo translate('Next') ?></a>
|
||||
<a class="btn-primary" id="lastLink" href="?view=frame&eid=<?php echo $Event->Id() ?>&fid=<?php echo $lastFid ?>&scale=<?php echo $scale ?>&show=<?php echo $show ?>"><?php echo translate('Last') ?></a>
|
||||
<?php } ?>
|
||||
</p>
|
||||
<?php if (file_exists ($dImagePath)) { ?>
|
||||
|
|
|
@ -39,7 +39,7 @@ xhtmlHeaders(__FILE__, translate('Frames').' - '.$Event->Id() );
|
|||
<h2><?php echo translate('Frames') ?> - <?php echo $Event->Id() ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="get" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<table id="contentTable" class="major" cellspacing="0">
|
||||
<thead>
|
||||
|
|
|
@ -35,7 +35,7 @@ xhtmlHeaders(__FILE__, translate('Function').' - '.validHtmlStr($monitor['Name']
|
|||
<h2><?php echo translate('Function').' - '.validHtmlStr($monitor['Name']) ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="function"/>
|
||||
<input type="hidden" name="action" value="function"/>
|
||||
<input type="hidden" name="mid" value="<?php echo $monitor['Id'] ?>"/>
|
||||
|
|
|
@ -34,10 +34,10 @@ xhtmlHeaders(__FILE__, translate('Group').' - '.$newGroup->Name());
|
|||
<body>
|
||||
<div id="page">
|
||||
<div id="header">
|
||||
<h2><?php echo translate('Group') ?> - <?php echo $newGroup->Name() ?></h2>
|
||||
<h2><?php echo translate('Group') ?> - <?php echo validHtmlStr($newGroup->Name()); ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="groupForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="groupForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="gid" value="<?php echo $newGroup->Id() ?>"/>
|
||||
<table id="contentTable" class="major">
|
||||
|
|
|
@ -47,7 +47,7 @@ xhtmlHeaders(__FILE__, translate('Groups'));
|
|||
<div id="page">
|
||||
<?php echo $navbar = getNavBarHTML(); ?>
|
||||
<div id="content">
|
||||
<form name="groupsForm" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="groupsForm" method="get" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="action" value="setgroup"/>
|
||||
<table id="contentTable" class="major">
|
||||
|
|
|
@ -29,7 +29,7 @@ function exportProgress() {
|
|||
}
|
||||
|
||||
function exportResponse( respObj, respText ) {
|
||||
window.location.replace( thisUrl+'?view='+currentView+'&'+eidParm+'&exportFile='+respObj.exportFile+'&generated='+((respObj.result=='Ok')?1:0) );
|
||||
window.location.replace( thisUrl+'?view='+currentView+'&'+eidParm+'&exportFormat='+respObj.exportFormat+'&generated='+((respObj.result=='Ok')?1:0) );
|
||||
}
|
||||
|
||||
function exportEvent( form ) {
|
||||
|
@ -48,6 +48,9 @@ function initPage() {
|
|||
if ( exportReady ) {
|
||||
startDownload.pass( exportFile ).delay( 1500 );
|
||||
}
|
||||
document.getElementById('exportButton').addEventListener("click", function onClick(evt) {
|
||||
exportEvent(this.form);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener( 'DOMContentLoaded', initPage );
|
||||
|
|
|
@ -14,6 +14,6 @@ var eidParm = 'eid=<?php echo validInt($_REQUEST['eid']) ?>';
|
|||
?>
|
||||
|
||||
var exportReady = <?php echo !empty($_REQUEST['generated'])?'true':'false' ?>;
|
||||
var exportFile = '<?php echo !empty($_REQUEST['exportFile'])?validJsStr($_REQUEST['exportFile']):'' ?>';
|
||||
var exportFile = '?view=archive&type=<?php echo $exportFormat; ?>';
|
||||
|
||||
var exportProgressString = '<?php echo addslashes(translate('Exporting')) ?>';
|
||||
|
|
|
@ -901,8 +901,19 @@ function actQuery( action, parms ) {
|
|||
|
||||
function deleteEvent() {
|
||||
pauseClicked(); //Provides visual feedback that your click happened.
|
||||
actQuery( 'delete' );
|
||||
streamNext( true );
|
||||
|
||||
var deleteReq = new Request.JSON({
|
||||
url: thisUrl,
|
||||
method: 'post',
|
||||
timeout: AJAX_TIMEOUT,
|
||||
onSuccess: function onDeleteSuccess(respObj, respText) {
|
||||
getActResponse(respObj, respText);
|
||||
// We must wait for the deletion to happen before navigating to the next
|
||||
// event or this request will be cancelled.
|
||||
streamNext( true );
|
||||
},
|
||||
});
|
||||
deleteReq.send("view=request&request=event&id="+eventData.Id+"&action=delete");
|
||||
}
|
||||
|
||||
function renameEvent() {
|
||||
|
|
|
@ -17,12 +17,13 @@ function setButtonStates( element ) {
|
|||
form.deleteBtn.disabled = !(canEditEvents && checked);
|
||||
}
|
||||
|
||||
function configureButton( element, name ) {
|
||||
function configureButton(event) {
|
||||
var element = event.target;
|
||||
var form = element.form;
|
||||
var checked = element.checked;
|
||||
if ( !checked ) {
|
||||
for (var i = 0; i < form.elements.length; i++) {
|
||||
if ( form.elements[i].name.indexOf(name) == 0) {
|
||||
for (var i = 0, len=form.elements.length; i < len; i++) {
|
||||
if ( form.elements[i].name.indexOf('eids') == 0) {
|
||||
if ( form.elements[i].checked ) {
|
||||
checked = true;
|
||||
break;
|
||||
|
@ -42,15 +43,17 @@ function configureButton( element, name ) {
|
|||
form.deleteBtn.disabled = !(canEditEvents && checked);
|
||||
}
|
||||
|
||||
function deleteEvents( element, name ) {
|
||||
function deleteEvents( element ) {
|
||||
if ( ! canEditEvents ) {
|
||||
alert("You do not have permission to delete events.");
|
||||
return;
|
||||
}
|
||||
var form = element.form;
|
||||
|
||||
var count = 0;
|
||||
for (var i = 0, len=form.elements.length; i < len; i++) {
|
||||
if ( form.elements[i].name.indexOf(name) == 0 ) {
|
||||
// This is slightly more efficient than a jquery selector because we stop after finding one.
|
||||
for (var i = 0; i < form.elements.length; i++) {
|
||||
if (form.elements[i].name.indexOf('eids') == 0) {
|
||||
if ( form.elements[i].checked ) {
|
||||
count++;
|
||||
break;
|
||||
|
@ -65,7 +68,7 @@ function deleteEvents( element, name ) {
|
|||
}
|
||||
}
|
||||
|
||||
function editEvents( element, name ) {
|
||||
function editEvents( element ) {
|
||||
if ( ! canEditEvents ) {
|
||||
alert("You do not have permission to delete events.");
|
||||
return;
|
||||
|
@ -73,7 +76,7 @@ function editEvents( element, name ) {
|
|||
var form = element.form;
|
||||
var eids = new Array();
|
||||
for (var i = 0, len=form.elements.length; i < len; i++) {
|
||||
if ( form.elements[i].name.indexOf(name) == 0 ) {
|
||||
if (form.elements[i].name.indexOf('eids') == 0) {
|
||||
if ( form.elements[i].checked ) {
|
||||
eids[eids.length] = 'eids[]='+form.elements[i].value;
|
||||
}
|
||||
|
@ -82,25 +85,25 @@ function editEvents( element, name ) {
|
|||
createPopup('?view=eventdetail&'+eids.join('&'), 'zmEventDetail', 'eventdetail');
|
||||
}
|
||||
|
||||
function downloadVideo( element, name ) {
|
||||
function downloadVideo( element ) {
|
||||
var form = element.form;
|
||||
var eids = new Array();
|
||||
for (var i = 0; i < form.elements.length; i++) {
|
||||
if (form.elements[i].name.indexOf(name) == 0) {
|
||||
for (var i = 0, len=form.elements.length; i < len; i++) {
|
||||
if (form.elements[i].name.indexOf('eids') == 0 ) {
|
||||
if ( form.elements[i].checked ) {
|
||||
eids[eids.length] = 'eids[]='+form.elements[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
createPopup( '?view=download&'+eids.join( '&' ), 'zmDownload', 'download' );
|
||||
createPopup( '?view=download&'+eids.join('&'), 'zmDownload', 'download' );
|
||||
}
|
||||
|
||||
function exportEvents(element, name) {
|
||||
var form = $j(element.form);
|
||||
function exportEvents( element ) {
|
||||
var form = element.form;
|
||||
if ( 0 ) {
|
||||
var eids = new Array();
|
||||
for (var i = 0; i < form.elements.length; i++) {
|
||||
if (form.elements[i].name.indexOf(name) == 0) {
|
||||
for (var i = 0, len=form.elements.length; i < len; i++) {
|
||||
if (form.elements[i].name.indexOf('eids') == 0 ) {
|
||||
if ( form.elements[i].checked ) {
|
||||
eids[eids.length] = 'eids[]='+form.elements[i].value;
|
||||
}
|
||||
|
@ -113,11 +116,11 @@ function exportEvents(element, name) {
|
|||
form.submit();
|
||||
}
|
||||
|
||||
function viewEvents( element, name ) {
|
||||
function viewEvents( element ) {
|
||||
var form = element.form;
|
||||
var events = new Array();
|
||||
for (var i = 0; i < form.elements.length; i++) {
|
||||
if ( form.elements[i].name.indexOf(name) == 0) {
|
||||
for (var i = 0, len=form.elements.length; i < len; i++) {
|
||||
if ( form.elements[i].name.indexOf('eids') == 0 ) {
|
||||
if ( form.elements[i].checked ) {
|
||||
events[events.length] = form.elements[i].value;
|
||||
}
|
||||
|
@ -129,13 +132,13 @@ function viewEvents( element, name ) {
|
|||
}
|
||||
}
|
||||
|
||||
function archiveEvents( element, name ) {
|
||||
function archiveEvents(element) {
|
||||
var form = element.form;
|
||||
form.elements['action'].value = 'archive';
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function unarchiveEvents(element, name) {
|
||||
function unarchiveEvents(element) {
|
||||
if ( ! canEditEvents ) {
|
||||
alert("You do not have permission to delete events.");
|
||||
return;
|
||||
|
@ -151,10 +154,34 @@ if ( openFilterWindow ) {
|
|||
location.replace( '?view='+currentView+'&page='+thisPage+filterQuery );
|
||||
}
|
||||
|
||||
function thumbnail_onmouseover(event) {
|
||||
var img = event.target;
|
||||
img.src = img.getAttribute('stream_src');
|
||||
}
|
||||
function thumbnail_onmouseout(event) {
|
||||
var img = event.target;
|
||||
img.src = img.getAttribute('still_src');
|
||||
}
|
||||
|
||||
function initPage() {
|
||||
if (window.history.length == 1) {
|
||||
if ( window.history.length == 1 ) {
|
||||
$j('#controls').children().eq(0).html('');
|
||||
}
|
||||
$j('.colThumbnail img').each(function() {
|
||||
this.addEventListener('mouseover', thumbnail_onmouseover, false);
|
||||
this.addEventListener('mouseout', thumbnail_onmouseout, false);
|
||||
});
|
||||
$j('input[name=eids\\[\\]]').each(function() {
|
||||
this.addEventListener('click', configureButton, false);
|
||||
});
|
||||
document.getElementById("refreshLink").addEventListener("click", function onRefreshClick(evt) {
|
||||
evt.preventDefault();
|
||||
window.location.reload(true);
|
||||
});
|
||||
document.getElementById("backLink").addEventListener("click", function onBackClick(evt) {
|
||||
evt.preventDefault();
|
||||
window.history.back();
|
||||
});
|
||||
}
|
||||
|
||||
$j(document).ready(initPage);
|
||||
|
|
|
@ -59,6 +59,9 @@ function initPage() {
|
|||
if ( exportReady ) {
|
||||
startDownload.pass( exportFile ).delay( 1500 );
|
||||
}
|
||||
document.getElementById('exportButton').addEventListener('click', function onClick() {
|
||||
exportEvent(this.form);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener( 'DOMContentLoaded', initPage );
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
function selectFilter(element) {
|
||||
element.form.submit();
|
||||
}
|
||||
|
||||
function validateForm( form ) {
|
||||
var rows = $j(form).find('tbody').eq(0).find('tr');
|
||||
var obrCount = 0;
|
||||
|
@ -7,18 +11,18 @@ function validateForm( form ) {
|
|||
obrCount += parseInt(form.elements['filter[Query][terms][' + i + '][obr]'].value);
|
||||
cbrCount += parseInt(form.elements['filter[Query][terms][' + i + '][cbr]'].value);
|
||||
}
|
||||
if (form.elements['filter[Query][terms][' + i + '][val]'].value == '') {
|
||||
alert( errorValue );
|
||||
if ( form.elements['filter[Query][terms][' + i + '][val]'].value == '' ) {
|
||||
alert(errorValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (obrCount - cbrCount != 0) {
|
||||
alert( errorBrackets );
|
||||
if ( (obrCount - cbrCount) != 0 ) {
|
||||
alert(errorBrackets);
|
||||
return false;
|
||||
}
|
||||
var numbers_reg = /\D/;
|
||||
if ( numbers_reg.test( form.elements['filter[Query][limit]'].value ) ) {
|
||||
alert( "There appear to be non-numeric characters in your limit. Limit must be a positive integer value or empty." );
|
||||
if ( numbers_reg.test(form.elements['filter[Query][limit]'].value) ) {
|
||||
alert("There appear to be non-numeric characters in your limit. Limit must be a positive integer value or empty.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -88,9 +92,10 @@ function submitToExport(element) {
|
|||
|
||||
function executeFilter( element ) {
|
||||
var form = element.form;
|
||||
form.action = thisUrl + '?view=events';
|
||||
form.action = thisUrl + '?view=filter';
|
||||
form.elements['action'].value = 'execute';
|
||||
history.replaceState(null, null, '?view=filter&' + $j(form).serialize());
|
||||
form.submit();
|
||||
//history.replaceState(null, null, '?view=filter&' + $j(form).serialize());
|
||||
}
|
||||
|
||||
function saveFilter( element ) {
|
||||
|
@ -102,9 +107,9 @@ function saveFilter( element ) {
|
|||
// Submit is done by the button type="submit"
|
||||
}
|
||||
|
||||
function deleteFilter( element, name ) {
|
||||
if ( confirm( deleteSavedFilterString+" '"+name+"'?" ) ) {
|
||||
var form = element.form;
|
||||
function deleteFilter( element ) {
|
||||
var form = element.form;
|
||||
if ( confirm( deleteSavedFilterString+" '"+form.elements['filter[Name]'].value+"'?" ) ) {
|
||||
form.elements['action'].value = 'delete';
|
||||
form.submit();
|
||||
}
|
||||
|
@ -235,12 +240,12 @@ function stringFilter(term) {
|
|||
|
||||
function addTerm( element ) {
|
||||
var row = $j(element).closest('tr');
|
||||
row.find('select').chosen("destroy");
|
||||
row.find('select').chosen('destroy');
|
||||
var newRow = row.clone().insertAfter(row);
|
||||
row.find('select').chosen({width: "101%"});
|
||||
row.find('select').chosen({width: '101%'});
|
||||
newRow.find('select').each( function() { //reset new row to default
|
||||
this[0].selected = 'selected';
|
||||
}).chosen({width: "101%"});
|
||||
}).chosen({width: '101%'});
|
||||
newRow.find('input[type="text"]').val('');
|
||||
var rows = $j(row).parent().children();
|
||||
parseRows(rows);
|
||||
|
|
|
@ -30,4 +30,10 @@ function changeScale() {
|
|||
});
|
||||
}
|
||||
|
||||
if (scale == 'auto') $j(document).ready(changeScale);
|
||||
if (scale == 'auto') {
|
||||
$j(document).ready(changeScale);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function onDCL() {
|
||||
document.getElementById('scale').addEventListener('change', changeScale);
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
var scale = '<?php echo $scale ?>';
|
||||
var scale = '<?php echo validJsStr($scale); ?>';
|
||||
|
||||
var SCALE_BASE = <?php echo SCALE_BASE ?>;
|
||||
|
|
|
@ -64,7 +64,16 @@ function logResponse( respObj ) {
|
|||
if ( ( !minLogTime ) || ( log.TimeKey < minLogTime ) ) {
|
||||
minLogTime = log.TimeKey;
|
||||
}
|
||||
var row = logTable.push( [{content: log.DateTime, properties: {style: 'white-space: nowrap'}}, log.Component, log.Server, log.Pid, log.Code, log.Message, log.File, log.Line] );
|
||||
|
||||
// Manually create table cells by setting the text since `push` will set HTML which
|
||||
// can lead to XSS.
|
||||
var messageCell = new Element('td');
|
||||
messageCell.set('text', log.Message);
|
||||
|
||||
var fileCell = new Element('td');
|
||||
fileCell.set('text', log.File);
|
||||
|
||||
var row = logTable.push( [{content: log.DateTime, properties: {style: 'white-space: nowrap'}}, log.Component, log.Server, log.Pid, log.Code, messageCell, fileCell, log.Line] );
|
||||
|
||||
delete log.Message;
|
||||
row.tr.store( 'log', log );
|
||||
|
|
|
@ -133,9 +133,9 @@ function validateForm( form ) {
|
|||
|
||||
if ( errors.length ) {
|
||||
alert( errors.join( "\n" ) );
|
||||
return( false );
|
||||
return false;
|
||||
}
|
||||
return( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
function updateLinkedMonitors( element ) {
|
||||
|
|
|
@ -122,6 +122,11 @@ function getImageSource( monId, time ) {
|
|||
Event = events[Frame.EventId];
|
||||
|
||||
var storage = Storage[Event.StorageId];
|
||||
if ( ! storage ) {
|
||||
// Storage[0] is guaranteed to exist as we make sure it is there in montagereview.js.php
|
||||
console.log("No storage area for id " + Event.StorageId);
|
||||
storage = Storage[0];
|
||||
}
|
||||
// monitorServerId may be 0, which gives us the default Server entry
|
||||
var server = storage.ServerId ? Servers[storage.ServerId] : Servers[monitorServerId[monId]];
|
||||
return server.PathToIndex +
|
||||
|
@ -500,7 +505,8 @@ HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;
|
|||
|
||||
var mouseisdown=false;
|
||||
function mdown(event) {
|
||||
mouseisdown=true; mmove(event);
|
||||
mouseisdown=true;
|
||||
mmove(event);
|
||||
}
|
||||
function mup(event) {
|
||||
mouseisdown=false;
|
||||
|
@ -509,7 +515,8 @@ function mout(event) {
|
|||
mouseisdown=false;
|
||||
} // if we go outside treat it as release
|
||||
function tmove(event) {
|
||||
mouseisdown=true; mmove(event);
|
||||
mouseisdown=true;
|
||||
mmove(event);
|
||||
}
|
||||
|
||||
function mmove(event) {
|
||||
|
@ -835,13 +842,15 @@ function zoom(monId, scale) {
|
|||
}
|
||||
}
|
||||
|
||||
function clickMonitor(event, monId) {
|
||||
var monitor_element = $("Monitor"+monId.toString());
|
||||
var pos_x = event.offsetX ? (event.offsetX) : event.pageX - monitor_element.offsetLeft;
|
||||
var pos_y = event.offsetY ? (event.offsetY) : event.pageY - monitor_element.offsetTop;
|
||||
if ( pos_x < monitor_element.width/4 && pos_y < monitor_element.height/4 ) {
|
||||
function clickMonitor(event) {
|
||||
var element = event.target;
|
||||
//var monitor_element = $("Monitor"+monId.toString());
|
||||
var monId = element.getAttribute('monitor_id');
|
||||
var pos_x = event.offsetX ? (event.offsetX) : event.pageX - element.offsetLeft;
|
||||
var pos_y = event.offsetY ? (event.offsetY) : event.pageY - element.offsetTop;
|
||||
if ( pos_x < element.width/4 && pos_y < element.height/4 ) {
|
||||
zoom(monId, 1.15);
|
||||
} else if ( pos_x > monitor_element.width * 3/4 && pos_y < monitor_element.height/4 ) {
|
||||
} else if ( pos_x > element.width * 3/4 && pos_y < element.height/4 ) {
|
||||
zoom(monId, 1/1.15);
|
||||
} else {
|
||||
showOneMonitor(monId);
|
||||
|
@ -910,9 +919,25 @@ function initPage() {
|
|||
}
|
||||
if ( !liveMode ) {
|
||||
canvas = $("timeline");
|
||||
|
||||
canvas.addEventListener('mousemove', mmove, false);
|
||||
canvas.addEventListener('touchmove', tmove, false);
|
||||
canvas.addEventListener('mousedown', mdown, false);
|
||||
canvas.addEventListener('mouseup', mup, false);
|
||||
canvas.addEventListener('mouseout', mout, false);
|
||||
|
||||
ctx = canvas.getContext('2d');
|
||||
drawGraph();
|
||||
}
|
||||
for ( i=0, len=monitorPtr.length; i < len; i += 1 ) {
|
||||
var monitor_id = monitorPtr[i];
|
||||
monitor_canvas = $('Monitor'+monitor_id);
|
||||
if ( ! monitor_canvas ) {
|
||||
console.log("No canvas found for monitor " + monitor_id);
|
||||
continue;
|
||||
}
|
||||
monitor_canvas.addEventListener('click', clickMonitor, false);
|
||||
}
|
||||
setSpeed(speedIndex);
|
||||
//setFit(fitMode); // will redraw
|
||||
//setLive(liveMode); // will redraw
|
||||
|
|
|
@ -119,13 +119,21 @@ echo " };\n";
|
|||
} // end if initialmodeislive
|
||||
|
||||
echo "\nvar Storage = [];\n";
|
||||
$have_storage_zero = 0;
|
||||
foreach ( Storage::find() as $Storage ) {
|
||||
echo 'Storage[' . $Storage->Id() . '] = ' . json_encode($Storage). ";\n";
|
||||
echo 'Storage[' . $Storage->Id() . '] = ' . $Storage->to_json(). ";\n";
|
||||
if ( $Storage->Id() == 0 )
|
||||
$have_storage_zero = true;
|
||||
}
|
||||
if ( !$have_storage_zero ) {
|
||||
$Storage = new Storage();
|
||||
echo 'Storage[0] = ' . $Storage->to_json(). ";\n";
|
||||
}
|
||||
|
||||
echo "\nvar Servers = [];\n";
|
||||
// Fall back to get Server paths, etc when no using multi-server mode
|
||||
$Server = new Server();
|
||||
echo 'Servers[0] = new Server(' . json_encode($Server). ");\n";
|
||||
echo 'Servers[0] = new Server(' . $Server->to_json(). ");\n";
|
||||
foreach ( Server::find() as $Server ) {
|
||||
echo 'Servers[' . $Server->Id() . '] = new Server(' . $Server->to_json(). ");\n";
|
||||
}
|
||||
|
|
|
@ -12,13 +12,14 @@
|
|||
function () {
|
||||
// Append '?(GET query)' to URL if the GET query is not empty.
|
||||
var querySuffix = "<?php
|
||||
if (!empty($_POST["postLoginQuery"])) {
|
||||
parse_str($_POST["postLoginQuery"], $queryParams);
|
||||
echo "?" . http_build_query($queryParams);
|
||||
}
|
||||
if (!empty($_POST['postLoginQuery'])) {
|
||||
parse_str($_POST['postLoginQuery'], $queryParams);
|
||||
echo '?' . http_build_query($queryParams);
|
||||
}
|
||||
?>";
|
||||
|
||||
var newUrl = thisUrl + querySuffix;
|
||||
//var newUrl = thisUrl + querySuffix;
|
||||
var newUrl = '<?php echo $_SERVER['PHP_SELF'] ?>' + querySuffix;
|
||||
window.location.replace(newUrl);
|
||||
}
|
||||
).delay( 500 );
|
||||
|
|
|
@ -4,49 +4,48 @@ $j(document).ready(function() {
|
|||
runstate = $j(this).val();
|
||||
|
||||
if ( (runstate == 'stop') || (runstate == 'restart') || (runstate == 'start') || (runstate == 'default') ) {
|
||||
$j("#btnDelete").prop( "disabled", true );
|
||||
$j("#btnDelete").prop("disabled", true);
|
||||
} else {
|
||||
$j("#btnDelete").prop( "disabled", false );
|
||||
$j("#btnDelete").prop("disabled", false);
|
||||
}
|
||||
});
|
||||
|
||||
// Enable or disable the Save button when entering a new state
|
||||
$j("#newState").keyup(function() {
|
||||
length = $j(this).val().length;
|
||||
console.log(length);
|
||||
if (length < 1) {
|
||||
$j("#btnSave").prop( "disabled", true );
|
||||
if ( length < 1 ) {
|
||||
$j("#btnSave").prop("disabled", true);
|
||||
} else {
|
||||
$j("#btnSave").prop( "disabled", false );
|
||||
$j("#btnSave").prop("disabled", false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Delete a state
|
||||
$j("#btnDelete").click(function() {
|
||||
stateStuff( 'delete', $j("#runState").val( ));
|
||||
stateStuff('delete', $j("#runState").val());
|
||||
});
|
||||
|
||||
|
||||
// Save a new state
|
||||
$j("#btnSave").click(function() {
|
||||
stateStuff( 'save', undefined, $j("#newState").val() );
|
||||
stateStuff('save', undefined, $j("#newState").val());
|
||||
});
|
||||
|
||||
// Change state
|
||||
$j("#btnApply").click(function() {
|
||||
stateStuff( 'state', $j("#runState").val() );
|
||||
stateStuff('state', $j("#runState").val());
|
||||
});
|
||||
|
||||
function stateStuff( action, runState, newState ) {
|
||||
function stateStuff(action, runState, newState) {
|
||||
// the state action will redirect to console
|
||||
var formData = {
|
||||
'view': 'console',
|
||||
'view': 'state',
|
||||
'action': action,
|
||||
'apply': 1,
|
||||
'runState': runState,
|
||||
'newState': newState
|
||||
};
|
||||
console.log(formData);
|
||||
|
||||
$j("#pleasewait").toggleClass("hidden");
|
||||
|
||||
|
|
|
@ -734,11 +734,13 @@ function Polygon_calcArea( coords ) {
|
|||
var n_coords = coords.length;
|
||||
var float_area = 0.0;
|
||||
|
||||
for ( i = 0, j = n_coords-1; i < n_coords; j = i++ ) {
|
||||
var trap_area = ( ( coords[i].x - coords[j].x ) * ( coords[i].y + coords[j].y ) ) / 2;
|
||||
for ( i = 0; i < n_coords-1; i++ ) {
|
||||
var trap_area = (coords[i].x*coords[i+1].y - coords[i+1].x*coords[i].y) / 2;
|
||||
float_area += trap_area;
|
||||
//printf( "%.2f (%.2f)\n", float_area, trap_area );
|
||||
}
|
||||
float_area += (coords[n_coords-1].x*coords[0].y - coords[0].x*coords[n_coords-1].y) / 2;
|
||||
|
||||
return Math.round( Math.abs( float_area ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ xhtmlHeaders(__FILE__, translate('SystemLog') );
|
|||
</table>
|
||||
<button type="reset" data-on-click="resetLog"><?php echo translate('Reset') ?></button>
|
||||
</div>
|
||||
<form name="logForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="logForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<table id="logTable" class="major">
|
||||
<thead class="thead-highlight">
|
||||
|
|
|
@ -4,7 +4,7 @@ xhtmlHeaders(__FILE__, translate('Login') );
|
|||
<body>
|
||||
<?php echo getNavBarHTML(); ?>
|
||||
<div class="container">
|
||||
<form class="center-block" name="loginForm" id="loginForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form class="center-block" name="loginForm" id="loginForm" method="post" action="?">
|
||||
<input type="hidden" name="action" value="login"/>
|
||||
<input type="hidden" name="view" value="login"/>
|
||||
<input type="hidden" name="postLoginQuery" value="<?php echo htmlspecialchars($_SERVER['QUERY_STRING']) ?>">
|
||||
|
@ -16,13 +16,13 @@ xhtmlHeaders(__FILE__, translate('Login') );
|
|||
|
||||
<div id="loginform">
|
||||
|
||||
<h1><i class="material-icons md-36">account_circle</i> <?php echo ZM_WEB_TITLE . ' ' . translate('Login') ?></h1>
|
||||
<h1><i class="material-icons md-36">account_circle</i> <?php echo validHtmlStr(ZM_WEB_TITLE) . ' ' . translate('Login') ?></h1>
|
||||
|
||||
<label for="inputUsername" class="sr-only"><?php echo translate('Username') ?></label>
|
||||
<input type="text" id="inputUsername" name="username" class="form-control" placeholder="Username" required autofocus />
|
||||
<input type="text" id="inputUsername" name="username" class="form-control" placeholder="Username" required autofocus autocomplete="username"/>
|
||||
|
||||
<label for="inputPassword" class="sr-only"><?php echo translate('Password') ?></label>
|
||||
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" required />
|
||||
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" required autocomplete="current-password"/>
|
||||
|
||||
<?php
|
||||
if (defined('ZM_OPT_USE_GOOG_RECAPTCHA')
|
||||
|
|
|
@ -25,10 +25,10 @@ xhtmlHeaders(__FILE__, translate('Logout') );
|
|||
<body>
|
||||
<div id="page">
|
||||
<div id="header">
|
||||
<h1><?php echo ZM_WEB_TITLE . ' ' . translate('Logout') ?></h1>
|
||||
<h1><?php echo validHtmlStr(ZM_WEB_TITLE) . ' ' . translate('Logout') ?></h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="action" value="logout"/>
|
||||
<input type="hidden" name="view" value="logout"/>
|
||||
<p><?php echo sprintf( $CLANG['CurrentLogin'], $user['Username'] ) ?></p>
|
||||
|
|
|
@ -108,8 +108,8 @@ if ( ! $monitor ) {
|
|||
'EventPrefix' => 'Event-',
|
||||
'AnalysisFPSLimit' => '',
|
||||
'AnalysisUpdateDelay' => 0,
|
||||
'MaxFPS' => '30',
|
||||
'AlarmMaxFPS' => '30',
|
||||
'MaxFPS' => null,
|
||||
'AlarmMaxFPS' => null,
|
||||
'FPSReportInterval' => 100,
|
||||
'RefBlendPerc' => 6,
|
||||
'AlarmRefBlendPerc' => 6,
|
||||
|
@ -462,7 +462,7 @@ if ( canEdit( 'Monitors' ) ) {
|
|||
if ( isset ($_REQUEST['dupId'])) {
|
||||
?>
|
||||
<div class="alert alert-info">
|
||||
Configuration cloned from Monitor: <?php echo $clonedName ?>
|
||||
Configuration cloned from Monitor: <?php echo validHtmlStr($clonedName) ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
@ -517,13 +517,13 @@ foreach ( $tabs as $name=>$value ) {
|
|||
?>
|
||||
</ul>
|
||||
<div class="clear"></div>
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>" onsubmit="if(validateForm(this)){$j('#contentButtons').hide();return true;}else{return false;};">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?" onsubmit="if(validateForm(this)){$j('#contentButtons').hide();return true;}else{return false;};">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
|
||||
<input type="hidden" name="action" value="monitor"/>
|
||||
<input type="hidden" name="mid" value="<?php echo $monitor->Id()?>"/>
|
||||
<input type="hidden" name="newMonitor[LinkedMonitors]" value="<?php echo (null !== $monitor->LinkedMonitors())?$monitor->LinkedMonitors():'' ?>"/>
|
||||
<input type="hidden" name="origMethod" value="<?php echo ( null !== $monitor->Method())?$monitor->Method():'' ?>"/>
|
||||
<input type="hidden" name="newMonitor[LinkedMonitors]" value="<?php echo (null !== $monitor->LinkedMonitors())?validHtmlStr($monitor->LinkedMonitors()):'' ?>"/>
|
||||
<input type="hidden" name="origMethod" value="<?php echo ( null !== $monitor->Method())?validHtmlStr($monitor->Method()):'' ?>"/>
|
||||
<?php
|
||||
if ( $tab != 'general' ) {
|
||||
?>
|
||||
|
@ -724,7 +724,7 @@ switch ( $tab ) {
|
|||
foreach ( $monitors as $linked_monitor ) {
|
||||
if ( (!$monitor->Id() || ($monitor->Id()!= $linked_monitor['Id'])) && visibleMonitor( $linked_monitor['Id'] ) ) {
|
||||
?>
|
||||
<option value="<?php echo $linked_monitor['Id'] ?>"<?php if ( array_key_exists( $linked_monitor['Id'], $monitorIds ) ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($linked_monitor['Name']) ?></option>
|
||||
<option value="<?php echo validHtmlStr($linked_monitor['Id']); ?>"<?php if ( array_key_exists( $linked_monitor['Id'], $monitorIds ) ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($linked_monitor['Name']) ?></option>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
@ -835,7 +835,7 @@ echo htmlOptions(Group::get_dropdown_options( ), $monitor->GroupIds() );
|
|||
<input type="radio" name="newMonitor[V4LMultiBuffer]" id="newMonitor[V4LMultiBuffer]" value="" <?php echo ( $monitor->V4LMultiBuffer() ? 'checked="checked"' : '' ) ?>/>
|
||||
<label for="newMonitor[V4LMultiBuffer]">Use Config Value</label>
|
||||
</td></tr>
|
||||
<tr><td><?php echo translate('V4LCapturesPerFrame') ?></td><td><input type="number" name="newMonitor[V4LCapturesPerFrame]" value="<?php echo $monitor->V4LCapturesPerFrame()?>"/></td></tr>
|
||||
<tr><td><?php echo translate('V4LCapturesPerFrame') ?></td><td><input type="number" name="newMonitor[V4LCapturesPerFrame]" value="<?php echo validHtmlStr($monitor->V4LCapturesPerFrame()); ?>"/></td></tr>
|
||||
<?php
|
||||
|
||||
} else if ( $monitor->Type() == 'NVSocket' ) {
|
||||
|
@ -873,7 +873,7 @@ include('_monitor_source_nvsocket.php');
|
|||
<tr><td><?php echo translate('WebSiteUrl') ?></td><td><input type="text" name="newMonitor[Path]" value="<?php echo validHtmlStr($monitor->Path()) ?>" size="36"/></td></tr>
|
||||
<tr><td><?php echo translate('Width') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Width]" value="<?php echo validHtmlStr($monitor->Width()) ?>" size="4";"/></td></tr>
|
||||
<tr><td><?php echo translate('Height') ?> (<?php echo translate('Pixels') ?>)</td><td><input type="text" name="newMonitor[Height]" value="<?php echo validHtmlStr($monitor->Height()) ?>" size="4";"/></td></tr>
|
||||
<tr><td><?php echo 'Web Site Refresh (Optional)' ?></td><td><input type="number" name="newMonitor[Refresh]" value="<?php echo $monitor->Refresh()?>"/></td></tr>
|
||||
<tr><td><?php echo 'Web Site Refresh (Optional)' ?></td><td><input type="number" name="newMonitor[Refresh]" value="<?php echo validHtmlStr($monitor->Refresh()); ?>"/></td></tr>
|
||||
<?php
|
||||
} elseif ( $monitor->Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) {
|
||||
?>
|
||||
|
@ -897,11 +897,11 @@ if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) {
|
|||
}
|
||||
if ( $monitor->Type() == 'Local' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts_v4l2 as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<?php
|
||||
} else if ( $monitor->Type() != 'WebSite' ) {
|
||||
?>
|
||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('Deinterlacing') ?></td><td><select name="newMonitor[Deinterlacing]"><?php foreach ( $deinterlaceopts as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->Deinterlacing()) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -915,7 +915,7 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
}
|
||||
case 'storage' :
|
||||
?>
|
||||
<tr><td><?php echo translate('SaveJPEGs') ?></td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->SaveJPEGs() ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('SaveJPEGs') ?></td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->SaveJPEGs() ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('VideoWriter') ?></td><td>
|
||||
<?php
|
||||
$videowriteropts = array(
|
||||
|
@ -953,7 +953,7 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
<tr><td><?php echo translate('TimestampLabelFormat') ?></td><td><input type="text" name="newMonitor[LabelFormat]" value="<?php echo validHtmlStr($monitor->LabelFormat()) ?>" size="32"/></td></tr>
|
||||
<tr><td><?php echo translate('TimestampLabelX') ?></td><td><input type="text" name="newMonitor[LabelX]" value="<?php echo validHtmlStr($monitor->LabelX()) ?>" size="4"/></td></tr>
|
||||
<tr><td><?php echo translate('TimestampLabelY') ?></td><td><input type="text" name="newMonitor[LabelY]" value="<?php echo validHtmlStr($monitor->LabelY()) ?>" size="4"/></td></tr>
|
||||
<tr><td><?php echo translate('TimestampLabelSize') ?></td><td><select name="newMonitor[LabelSize]"><?php foreach ( $label_size as $name => $value ) { ?><option value="<?php echo $value ?>"<?php if ( $value == $monitor->LabelSize() ) { ?> selected="selected"<?php } ?>><?php echo $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?php echo translate('TimestampLabelSize') ?></td><td><select name="newMonitor[LabelSize]"><?php foreach ( $label_size as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->LabelSize() ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr>
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
|
@ -1021,7 +1021,7 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
<td><?php echo translate('SignalCheckColour') ?></td>
|
||||
<td>
|
||||
<input type="text" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour()) ?>" size="10" onchange="$('SignalCheckSwatch').setStyle('backgroundColor', this.value)"/>
|
||||
<span id="SignalCheckSwatch" class="swatch" style="background-color: <?php echo $monitor->SignalCheckColour()?>;"> </span>
|
||||
<span id="SignalCheckSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->SignalCheckColour()); ?>;"> </span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -1044,7 +1044,7 @@ if ( $monitor->Type() == 'Local' ) {
|
|||
</table>
|
||||
<div id="contentButtons">
|
||||
<button type="submit" value="Save"<?php echo canEdit('Monitors') ? '' : ' disabled="disabled"' ?>><?php echo translate('Save') ?></button>
|
||||
<button data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
|
||||
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -41,7 +41,7 @@ xhtmlHeaders(__FILE__, translate('MonitorPreset') );
|
|||
<h2><?php echo translate('MonitorPreset') ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="mid" value="<?php echo validNum($_REQUEST['mid']) ?>"/>
|
||||
<p>
|
||||
|
|
|
@ -322,7 +322,7 @@ xhtmlHeaders(__FILE__, translate('MonitorProbe') );
|
|||
<h2><?php echo translate('MonitorProbe') ?></h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="mid" value="<?php echo validNum($_REQUEST['mid']) ?>"/>
|
||||
<p>
|
||||
|
|
|
@ -48,7 +48,7 @@ xhtmlHeaders(__FILE__, translate('Function'));
|
|||
<div id="content">
|
||||
The following monitors will have these settings update when you click Save:<br/><br/>
|
||||
<?php echo implode('<br/>', array_map(function($m){return $m->Id().' ' .$m->Name();}, $monitors)); ?>
|
||||
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>" onsubmit="$j('#contentButtons').hide();return true;">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?" onsubmit="$j('#contentButtons').hide();return true;">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="action" value="save"/>
|
||||
<input type="hidden" name="object" value="Monitor"/>
|
||||
|
|
|
@ -144,11 +144,11 @@ if ( $showControl ) {
|
|||
}
|
||||
if ( $showZones ) {
|
||||
?>
|
||||
<a id="ShowZones" href="<?php echo $_SERVER['PHP_SELF'].'?view=montage&showZones=0'; ?>">Hide Zones</a>
|
||||
<a id="ShowZones" href="?view=montage&showZones=0">Hide Zones</a>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<a id="ShowZones" href="<?php echo $_SERVER['PHP_SELF'].'?view=montage&showZones=1'; ?>">Show Zones</a>
|
||||
<a id="ShowZones" href="?view=montage&showZones=1">Show Zones</a>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -176,7 +176,7 @@ if ( $showZones ) {
|
|||
</span>
|
||||
<span id="layoutControl">
|
||||
<label for="layout"><?php echo translate('Layout') ?>:</label>
|
||||
<?php echo htmlSelect('zmMontageLayout', $layoutsById, $layout_id, array('onchange'=>'selectLayout(this);', 'id'=>'zmMontageLayout')); ?>
|
||||
<?php echo htmlSelect('zmMontageLayout', $layoutsById, $layout_id, array('onchange'=>'selectLayout(this);')); ?>
|
||||
</span>
|
||||
<input type="hidden" name="Positions"/>
|
||||
<input type="button" id="EditLayout" value="<?php echo translate('EditLayout') ?>" data-on-click-this="edit_layout"/>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue