Update branch to track modern

This commit is contained in:
Chris Wiggins 2013-09-24 14:58:41 +12:00
commit 10e4ca848f
1394 changed files with 257288 additions and 93620 deletions

34
.travis.yml Normal file
View File

@ -0,0 +1,34 @@
language: cpp
notifications:
irc: "chat.freenode.net#zoneminder-dev"
env:
global:
- LD_LIBRARY_PATH="/usr/local/lib:/opt/libjpeg-turbo/lib:$LD_LIBRARY_PATH"
- 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 -I/usr/local/include"
compiler:
- gcc
before_install:
- sudo apt-get update -qq
- sudo apt-get upgrade -y
- sudo apt-get install -y apache2 mysql-server php5 php5-mysql build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libpcre3 libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm subversion automake autoconf libjpeg-turbo8-dev libjpeg-turbo8 apache2-mpm-prefork libapache2-mod-php5 php5-cli libtheora-dev libvorbis-dev libvpx-dev libx264-dev
install:
- git clone git://source.ffmpeg.org/ffmpeg.git
- cd ffmpeg
- ./configure --enable-shared --enable-swscale --enable-gpl --enable-libx264 --enable-libvpx --enable-libvorbis --enable-libtheora
- make -j `grep processor /proc/cpuinfo|wc -l`
- sudo make install
- sudo make install-libs
before_script:
- cd $TRAVIS_BUILD_DIR
- libtoolize --force
- aclocal
- autoheader
- automake --force-missing --add-missing
- autoconf
- mysql -e 'create database zoneminder;'
script:
- CXXFLAGS="$CXXFLAGS" ./configure --with-libarch=lib/$DEB_HOST_GNU_TYPE --disable-debug --host=$DEB_HOST_GNU_TYPE --build=$DEB_BUILD_GNU_TYPE --with-mysql=/usr --with-webdir=/var/www/zm --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-crashtrace=no --enable-mmap=yes ZM_SSL_LIB=openssl ZM_DB_USER=travis ZM_DB_PASS=
- make
after_success: mysql -u travis < db/zm_create.sql

View File

@ -9,7 +9,6 @@ sysconf_DATA = \
SUBDIRS = \ SUBDIRS = \
src \ src \
web \
scripts \ scripts \
db \ db \
misc misc

View File

@ -396,7 +396,7 @@ fi
AC_SUBST(PERL_MM_PARMS) AC_SUBST(PERL_MM_PARMS)
AC_SUBST(EXTRA_PERL_LIB) AC_SUBST(EXTRA_PERL_LIB)
AC_CONFIG_FILES([Makefile zm.conf zmconfgen.pl db/Makefile db/zm_create.sql misc/Makefile misc/apache.conf misc/logrotate.conf misc/syslog.conf scripts/Makefile scripts/zm scripts/zmaudit.pl scripts/zmcontrol.pl scripts/zmdc.pl scripts/zmfilter.pl scripts/zmpkg.pl scripts/zmtrack.pl scripts/zmtrigger.pl scripts/zmupdate.pl scripts/zmvideo.pl scripts/zmwatch.pl scripts/zmx10.pl scripts/zmdbbackup scripts/zmdbrestore scripts/zmeventdump scripts/zmlogrotate.conf scripts/ZoneMinder/lib/ZoneMinder/Base.pm scripts/ZoneMinder/lib/ZoneMinder/Config.pm scripts/ZoneMinder/lib/ZoneMinder/Memory.pm scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm src/Makefile src/zm_config.h web/Makefile web/ajax/Makefile web/css/Makefile web/graphics/Makefile web/includes/Makefile web/includes/config.php web/js/Makefile web/lang/Makefile web/skins/Makefile web/skins/classic/Makefile web/skins/classic/ajax/Makefile web/skins/classic/css/Makefile web/skins/classic/graphics/Makefile web/skins/classic/includes/Makefile web/skins/classic/js/Makefile web/skins/classic/lang/Makefile web/skins/classic/views/Makefile web/skins/classic/views/css/Makefile web/skins/classic/views/js/Makefile web/skins/mobile/Makefile web/skins/mobile/ajax/Makefile web/skins/mobile/css/Makefile web/skins/mobile/graphics/Makefile web/skins/mobile/includes/Makefile web/skins/mobile/lang/Makefile web/skins/mobile/views/Makefile web/skins/mobile/views/css/Makefile web/tools/Makefile web/tools/mootools/Makefile web/views/Makefile web/skins/xml/Makefile web/skins/xml/views/Makefile web/skins/xml/includes/Makefile]) AC_CONFIG_FILES([Makefile zm.conf zmconfgen.pl db/Makefile db/zm_create.sql misc/Makefile misc/apache.conf misc/logrotate.conf misc/syslog.conf scripts/Makefile scripts/zm scripts/zmaudit.pl scripts/zmcontrol.pl scripts/zmdc.pl scripts/zmfilter.pl scripts/zmpkg.pl scripts/zmtrack.pl scripts/zmtrigger.pl scripts/zmupdate.pl scripts/zmvideo.pl scripts/zmwatch.pl scripts/zmx10.pl scripts/zmdbbackup scripts/zmdbrestore scripts/zmeventdump scripts/zmlogrotate.conf scripts/ZoneMinder/lib/ZoneMinder/Base.pm scripts/ZoneMinder/lib/ZoneMinder/Config.pm scripts/ZoneMinder/lib/ZoneMinder/Memory.pm scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm src/Makefile src/zm_config.h])
# Create the definitions for compilation and defaults for the database # Create the definitions for compilation and defaults for the database
AC_CONFIG_COMMANDS([src/zm_config_defines.h],[perl ./zmconfgen.pl]) AC_CONFIG_COMMANDS([src/zm_config_defines.h],[perl ./zmconfgen.pl])

View File

@ -239,5 +239,5 @@ else
Info( "Video file $video_file already exists for event $event->{Id}\n" ); Info( "Video file $video_file already exists for event $event->{Id}\n" );
} }
#print( STDOUT $event->{MonitorId}.'/'.$event->{Id}.'/'.$video_file."\n" ); #print( STDOUT $event->{MonitorId}.'/'.$event->{Id}.'/'.$video_file."\n" );
print( STDOUT $video_file."\n" ); print( STDOUT $event_path . '/' . $video_file ."\n" );
exit( 0 ); exit( 0 );

13
web/.editorconfig Normal file
View File

@ -0,0 +1,13 @@
; This file is for unifying the coding style for different editors and IDEs.
; More information at http://editorconfig.org
root = true
[*]
indent_style = tab
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.bat]
end_of_line = crlf

22
web/.gitignore vendored Normal file
View File

@ -0,0 +1,22 @@
# User specific & automatically generated files #
#################################################
/app/Config/database.php
/app/tmp
/lib/Cake/Console/Templates/skel/tmp/
/plugins
/vendors
/build
/dist
/tags
/app/webroot/events
# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db

5
web/.htaccess Normal file
View File

@ -0,0 +1,5 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>

116
web/.travis.yml Normal file
View File

@ -0,0 +1,116 @@
language: php
php:
- 5.2
- 5.3
- 5.4
env:
- DB=mysql
- DB=pgsql
- DB=sqlite
matrix:
include:
- php: 5.4
env:
- PHPCS=1
before_script:
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi"
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test2;'; fi"
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test3;'; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE SCHEMA test2;' -U postgres -d cakephp_test; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE SCHEMA test3;' -U postgres -d cakephp_test; fi"
- chmod -R 777 ./app/tmp
- sudo apt-get install lighttpd
- pear channel-discover pear.cakephp.org
- pear install --alldeps cakephp/CakePHP_CodeSniffer
- phpenv rehash
- set +H
- echo "<?php
class DATABASE_CONFIG {
private \$identities = array(
'mysql' => array(
'datasource' => 'Database/Mysql',
'host' => '0.0.0.0',
'login' => 'travis'
),
'pgsql' => array(
'datasource' => 'Database/Postgres',
'host' => '127.0.0.1',
'login' => 'postgres',
'database' => 'cakephp_test',
'schema' => array(
'default' => 'public',
'test' => 'public',
'test2' => 'test2',
'test_database_three' => 'test3'
)
),
'sqlite' => array(
'datasource' => 'Database/Sqlite',
'database' => array(
'default' => ':memory:',
'test' => ':memory:',
'test2' => '/tmp/cakephp_test2.db',
'test_database_three' => '/tmp/cakephp_test3.db'
),
)
);
public \$default = array(
'persistent' => false,
'host' => '',
'login' => '',
'password' => '',
'database' => 'cakephp_test',
'prefix' => ''
);
public \$test = array(
'persistent' => false,
'host' => '',
'login' => '',
'password' => '',
'database' => 'cakephp_test',
'prefix' => ''
);
public \$test2 = array(
'persistent' => false,
'host' => '',
'login' => '',
'password' => '',
'database' => 'cakephp_test2',
'prefix' => ''
);
public \$test_database_three = array(
'persistent' => false,
'host' => '',
'login' => '',
'password' => '',
'database' => 'cakephp_test3',
'prefix' => ''
);
public function __construct() {
\$db = 'mysql';
if (!empty(\$_SERVER['DB'])) {
\$db = \$_SERVER['DB'];
}
foreach (array('default', 'test', 'test2', 'test_database_three') as \$source) {
\$config = array_merge(\$this->{\$source}, \$this->identities[\$db]);
if (is_array(\$config['database'])) {
\$config['database'] = \$config['database'][\$source];
}
if (!empty(\$config['schema']) && is_array(\$config['schema'])) {
\$config['schema'] = \$config['schema'][\$source];
}
\$this->{\$source} = \$config;
}
}
}" > app/Config/database.php
script:
- sh -c "if [ '$PHPCS' != '1' ]; then ./lib/Cake/Console/cake test core AllTests --stderr; else phpcs -p --extensions=php --standard=CakePHP ./lib/Cake; fi"
notifications:
email: false

View File

@ -1,35 +0,0 @@
AUTOMAKE_OPTIONS = gnu
# This should be set to your web directory
webdir = @WEB_PREFIX@
# And these to the user and group of your webserver
webuser = @WEB_USER@
webgroup = @WEB_GROUP@
SUBDIRS = \
ajax \
css \
graphics \
includes \
js \
lang \
skins \
tools \
views
dist_web_DATA = \
index.php
# Yes, you are correct. This is a HACK!
install-data-hook:
( cd $(DESTDIR)$(webdir); chown $(webuser):$(webgroup) $(dist_web_DATA) )
( cd $(DESTDIR)$(webdir); chown -R $(webuser):$(webgroup) $(SUBDIRS) )
@-( cd $(DESTDIR)$(webdir); if ! test -e events; then mkdir events; fi; chown $(webuser):$(webgroup) events; chmod u+w events )
@-( cd $(DESTDIR)$(webdir); if ! test -e images; then mkdir images; fi; chown $(webuser):$(webgroup) images; chmod u+w images )
@-( cd $(DESTDIR)$(webdir); if ! test -e sounds; then mkdir sounds; fi; chown $(webuser):$(webgroup) sounds; chmod u+w sounds )
@-( cd $(DESTDIR)$(webdir); if ! test -e tools; then mkdir tools; fi; chown $(webuser):$(webgroup) tools; chmod u+w tools )
@-( cd $(DESTDIR)$(webdir); if ! test -e temp; then mkdir temp; fi; chown $(webuser):$(webgroup) temp; chmod u+w temp )
uninstall-hook:
@-( cd $(DESTDIR)$(webdir); rm -rf $(SUBDIRS) )
@-( cd $(DESTDIR)$(webdir); rm -rf events images sounds tools temp )

View File

@ -1,12 +0,0 @@
AUTOMAKE_OPTIONS = gnu
webdir = @WEB_PREFIX@/ajax
dist_web_DATA = \
alarm.php \
control.php \
event.php \
log.php \
status.php \
stream.php \
zone.php

View File

@ -1,436 +0,0 @@
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = web/ajax
DIST_COMMON = $(dist_web_DATA) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(webdir)"
DATA = $(dist_web_DATA)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_CXXFLAGS = @AM_CXXFLAGS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BINDIR = @BINDIR@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CGI_PREFIX = @CGI_PREFIX@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_MMAP = @ENABLE_MMAP@
EXEEXT = @EXEEXT@
EXTRA_LIBS = @EXTRA_LIBS@
EXTRA_PERL_LIB = @EXTRA_PERL_LIB@
FFMPEG_CFLAGS = @FFMPEG_CFLAGS@
FFMPEG_LIBS = @FFMPEG_LIBS@
FFMPEG_PREFIX = @FFMPEG_PREFIX@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBDIR = @LIBDIR@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIB_ARCH = @LIB_ARCH@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_PREFIX = @MYSQL_PREFIX@
OBJEXT = @OBJEXT@
OPT_FFMPEG = @OPT_FFMPEG@
OPT_NETPBM = @OPT_NETPBM@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_BUILD = @PATH_BUILD@
PATH_FFMPEG = @PATH_FFMPEG@
PATH_NETPBM = @PATH_NETPBM@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PERL_MM_PARMS = @PERL_MM_PARMS@
POW_LIB = @POW_LIB@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SYSCONFDIR = @SYSCONFDIR@
TIME_BUILD = @TIME_BUILD@
VERSION = @VERSION@
WEB_GROUP = @WEB_GROUP@
WEB_HOST = @WEB_HOST@
WEB_PREFIX = @WEB_PREFIX@
WEB_USER = @WEB_USER@
ZM_CONFIG = @ZM_CONFIG@
ZM_DB_HOST = @ZM_DB_HOST@
ZM_DB_NAME = @ZM_DB_NAME@
ZM_DB_PASS = @ZM_DB_PASS@
ZM_DB_USER = @ZM_DB_USER@
ZM_HAS_GNUTLS = @ZM_HAS_GNUTLS@
ZM_HAS_GNUTLS_OPENSSL = @ZM_HAS_GNUTLS_OPENSSL@
ZM_HAS_V4L = @ZM_HAS_V4L@
ZM_HAS_V4L1 = @ZM_HAS_V4L1@
ZM_HAS_V4L2 = @ZM_HAS_V4L2@
ZM_LOGDIR = @ZM_LOGDIR@
ZM_MYSQL_ENGINE = @ZM_MYSQL_ENGINE@
ZM_PCRE = @ZM_PCRE@
ZM_PID = @ZM_PID@
ZM_RUNDIR = @ZM_RUNDIR@
ZM_SSL_LIB = @ZM_SSL_LIB@
ZM_TMPDIR = @ZM_TMPDIR@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = gnu
webdir = @WEB_PREFIX@/ajax
dist_web_DATA = \
alarm.php \
control.php \
event.php \
log.php \
status.php \
stream.php \
zone.php
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu web/ajax/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu web/ajax/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-dist_webDATA: $(dist_web_DATA)
@$(NORMAL_INSTALL)
test -z "$(webdir)" || $(MKDIR_P) "$(DESTDIR)$(webdir)"
@list='$(dist_web_DATA)'; test -n "$(webdir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(webdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(webdir)" || exit $$?; \
done
uninstall-dist_webDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_web_DATA)'; test -n "$(webdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(webdir)'; $(am__uninstall_files_from_dir)
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(DATA)
installdirs:
for dir in "$(DESTDIR)$(webdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-dist_webDATA
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-dist_webDATA
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-dist_webDATA install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am uninstall uninstall-am uninstall-dist_webDATA
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,42 +0,0 @@
<?php
define( "MSG_TIMEOUT", 2.0 );
define( "MSG_DATA_SIZE", 4+256 );
if ( canEdit( 'Monitors' ) )
{
$zmuCommand = getZmuCommand( " -m ".validInt($_REQUEST['id']) );
switch ( validJsStr($_REQUEST['command']) )
{
case "disableAlarms" :
{
$zmuCommand .= " -n";
break;
}
case "enableAlarms" :
{
$zmuCommand .= " -c";
break;
}
case "forceAlarm" :
{
$zmuCommand .= " -a";
break;
}
case "cancelForcedAlarm" :
{
$zmuCommand .= " -c";
break;
}
default :
{
ajaxError( "Unexpected command '".validJsStr($_REQUEST['command'])."'" );
}
}
ajaxResponse( exec( escapeshellcmd( $zmuCommand ) ) );
}
ajaxError( 'Unrecognised action or insufficient permissions' );
?>

View File

@ -1,64 +0,0 @@
<?php
require_once( 'includes/control_functions.php' );
// Monitor control actions, require a monitor id and control view permissions for that monitor
if ( empty($_REQUEST['id']) )
ajaxError( "No monitor id supplied" );
if ( canView( 'Control', $_REQUEST['id'] ) )
{
$monitor = dbFetchOne( "select C.*,M.* from Monitors as M inner join Controls as C on (M.ControlId = C.Id ) where M.Id = '".dbEscape($_REQUEST['id'])."'" );
$ctrlCommand = buildControlCommand( $monitor );
if ( $ctrlCommand )
{
$socket = socket_create( AF_UNIX, SOCK_STREAM, 0 );
if ( !$socket )
ajaxError( "socket_create() failed: ".socket_strerror(socket_last_error()) );
$sock_file = ZM_PATH_SOCKS.'/zmcontrol-'.$monitor['Id'].'.sock';
if ( @socket_connect( $socket, $sock_file ) )
{
$options = array();
foreach ( explode( " ", $ctrlCommand ) as $option )
{
if ( preg_match( '/--([^=]+)(?:=(.+))?/', $option, $matches ) )
{
$options[$matches[1]] = !empty($matches[2])?$matches[2]:1;
}
}
$option_string = jsonEncode( $options );
if ( !socket_write( $socket, $option_string ) )
ajaxError( "socket_write() failed: ".socket_strerror(socket_last_error()) );
ajaxResponse( 'Used socket' );
//socket_close( $socket );
}
else
{
$ctrlCommand .= " --id=".$monitor['Id'];
// Can't connect so use script
$ctrlStatus = '';
$ctrlOutput = array();
exec( escapeshellcmd( $ctrlCommand ), $ctrlOutput, $ctrlStatus );
if ( $ctrlStatus )
ajaxError( $ctrlCommand.'=>'.join( ' // ', $ctrlOutput ) );
ajaxResponse( 'Used script' );
}
}
else
{
ajaxError( "No command received" );
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );
function ajaxCleanup()
{
global $socket;
if ( !empty( $socket ) )
@socket_close( $socket );
}
?>

View File

@ -1,124 +0,0 @@
<?php
if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) )
{
ajaxError( "No event id(s) supplied" );
}
if ( canView( 'Events' ) )
{
switch ( $_REQUEST['action'] )
{
case "video" :
{
if ( empty($_REQUEST['videoFormat']) )
{
ajaxError( "Video Generation Failure, no format given" );
}
elseif ( empty($_REQUEST['rate']) )
{
ajaxError( "Video Generation Failure, no rate given" );
}
elseif ( empty($_REQUEST['scale']) )
{
ajaxError( "Video Generation Failure, no scale given" );
}
else
{
$sql = "select E.*,M.Name as MonitorName,M.DefaultRate,M.DefaultScale from Events as E inner join Monitors as M on E.MonitorId = M.Id where E.Id = ".dbEscape($_REQUEST['id']).monitorLimitSql();
if ( !($event = dbFetchOne( $sql )) )
ajaxError( "Video Generation Failure, can't load event" );
else
if ( $videoFile = createVideo( $event, $_REQUEST['videoFormat'], $_REQUEST['rate'], $_REQUEST['scale'], !empty($_REQUEST['overwrite']) ) )
ajaxResponse( array( 'response'=>$videoFile ) );
else
ajaxError( "Video Generation Failed" );
}
$ok = true;
break;
}
case 'deleteVideo' :
{
unlink( $videoFiles[$_REQUEST['id']] );
unset( $videoFiles[$_REQUEST['id']] );
ajaxResponse();
break;
}
case "export" :
{
require_once( ZM_SKIN_PATH.'/includes/export_functions.php' );
if ( !empty($_REQUEST['exportDetail']) )
$exportDetail = $_SESSION['export']['detail'] = $_REQUEST['exportDetail'];
else
$exportDetail = false;
if ( !empty($_REQUEST['exportFrames']) )
$exportFrames = $_SESSION['export']['frames'] = $_REQUEST['exportFrames'];
else
$exportFrames = false;
if ( !empty($_REQUEST['exportImages']) )
$exportImages = $_SESSION['export']['images'] = $_REQUEST['exportImages'];
else
$exportImages = false;
if ( !empty($_REQUEST['exportVideo']) )
$exportVideo = $_SESSION['export']['video'] = $_REQUEST['exportVideo'];
else
$exportVideo = false;
if ( !empty($_REQUEST['exportMisc']) )
$exportMisc = $_SESSION['export']['misc'] = $_REQUEST['exportMisc'];
else
$exportMisc = false;
if ( !empty($_REQUEST['exportFormat']) )
$exportFormat = $_SESSION['export']['format'] = $_REQUEST['exportFormat'];
else
$exportFormat = '';
$exportIds = !empty($_REQUEST['eids'])?$_REQUEST['eids']:$_REQUEST['id'];
if ( $exportFile = exportEvents( $exportIds, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat ) )
ajaxResponse( array( 'exportFile'=>$exportFile ) );
else
ajaxError( "Export Failed" );
break;
}
}
}
if ( canEdit( 'Events' ) )
{
switch ( $_REQUEST['action'] )
{
case "rename" :
{
if ( !empty($_REQUEST['eventName']) )
dbQuery( "update Events set Name = '".dbEscape($_REQUEST['eventName'])."' where Id = '".dbEscape($_REQUEST['id'])."'" );
else
ajaxError( "No new event name supplied" );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
break;
}
case "eventdetail" :
{
dbQuery( "update Events set Cause = '".dbEscape($_REQUEST['newEvent']['Cause'])."', Notes = '".dbEscape($_REQUEST['newEvent']['Notes'])."' where Id = '".dbEscape($_REQUEST['id'])."'" );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
break;
}
case "archive" :
case "unarchive" :
{
$archiveVal = ($_REQUEST['action'] == "archive")?1:0;
dbQuery( "update Events set Archived = ".$archiveVal." where Id = '".dbEscape($_REQUEST['id'])."'" );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>false ) );
break;
}
case "delete" :
{
deleteEvent( dbEscape($_REQUEST['id']) );
ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true ) );
break;
}
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );
?>

View File

@ -1,363 +0,0 @@
<?php
switch ( $_REQUEST['task'] )
{
case 'create' :
{
// Silently ignore bogus requests
if ( !empty($_POST['level']) && !empty($_POST['message']) )
{
logInit( array( 'id' => "web_js" ) );
$string = $_POST['message'];
$file = preg_replace( '/\w+:\/\/\w+\//', '', $_POST['file'] );
if ( !empty( $_POST['line'] ) )
$line = $_POST['line'];
else
$line = NULL;
$levels = array_flip(Logger::$codes);
if ( !isset($levels[$_POST['level']]) )
Panic( "Unexpected logger level '".$_POST['level']."'" );
$level = $levels[$_POST['level']];
Logger::fetch()->logPrint( $level, $string, $file, $line );
}
ajaxResponse();
break;
}
case 'query' :
{
if ( !canView( 'System' ) )
ajaxError( 'Insufficient permissions to view log entries' );
$minTime = isset($_POST['minTime'])?$_POST['minTime']:NULL;
$maxTime = isset($_POST['maxTime'])?$_POST['maxTime']:NULL;
$limit = isset($_POST['limit'])?$_POST['limit']:1000;
$filter = isset($_POST['filter'])?$_POST['filter']:array();
$sortField = isset($_POST['sortField'])?$_POST['sortField']:'TimeKey';
$sortOrder = isset($_POST['sortOrder'])?$_POST['sortOrder']:'desc';
$filterFields = array( 'Component', 'Pid', 'Level', 'File', 'Line' );
//$filterSql = $filter?' where
$countSql = "select count(*) as Total from Logs";
$total = dbFetchOne( $countSql, 'Total' );
$sql = "select * from Logs";
$where = array();
if ( $minTime )
$where[] = "TimeKey > ".dbEscape($minTime);
elseif ( $maxTime )
$where[] = "TimeKey < ".dbEscape($maxTime);
foreach ( $filter as $field=>$value )
if ( $field == 'Level' )
$where[] = dbEscape($field)." <= ".dbEscape($value);
else
$where[] = dbEscape($field)." = '".dbEscape($value)."'";
if ( count($where) )
$sql.= " where ".join( " and ", $where );
$sql .= " order by ".dbEscape($sortField)." ".dbEscape($sortOrder)." limit ".dbEscape($limit);
$logs = array();
foreach ( dbFetchAll( $sql ) as $log )
{
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
$logs[] = $log;
}
$options = array();
$where = array();
foreach( $filter as $field=>$value )
if ( $field == 'Level' )
$where[$field] = dbEscape($field)." <= ".dbEscape($value);
else
$where[$field] = dbEscape($field)." = '".dbEscape($value)."'";
foreach( $filterFields as $field )
{
$sql = "select distinct $field from Logs where not isnull($field)";
$fieldWhere = array_diff_key( $where, array( $field=>true ) );
if ( count($fieldWhere) )
$sql.= " and ".join( " and ", $fieldWhere );
$sql.= " order by $field asc";
if ( $field == 'Level' )
{
foreach( dbFetchAll( $sql, $field ) as $value )
if ( $value <= Logger::INFO )
$options[$field][$value] = Logger::$codes[$value];
else
$options[$field][$value] = "DB".$value;
}
else
{
foreach( dbFetchAll( $sql, $field ) as $value )
if ( $value != '' )
$options[$field][] = $value;
}
}
if ( count($filter) )
{
$sql = "select count(*) as Available from Logs where ".join( " and ", $where );
$available = dbFetchOne( $sql, 'Available' );
}
ajaxResponse( array(
'updated' => preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG ),
'total' => $total,
'available' => isset($available)?$available:$total,
'logs' => $logs,
'state' => logState(),
'options' => $options
) );
break;
}
case 'export' :
{
if ( !canView( 'System' ) )
ajaxError( 'Insufficient permissions to export logs' );
$minTime = isset($_POST['minTime'])?$_POST['minTime']:NULL;
$maxTime = isset($_POST['maxTime'])?$_POST['maxTime']:NULL;
if ( !is_null($minTime) && !is_null($maxTime) && $minTime > $maxTime )
{
$tempTime = $minTime;
$minTime = $maxTime;
$maxTime = $tempTime;
}
//$limit = isset($_POST['limit'])?$_POST['limit']:1000;
$filter = isset($_POST['filter'])?$_POST['filter']:array();
$sortField = isset($_POST['sortField'])?$_POST['sortField']:'TimeKey';
$sortOrder = isset($_POST['sortOrder'])?$_POST['sortOrder']:'asc';
$sql = "select * from Logs";
$where = array();
if ( $minTime )
{
preg_match( '/(.+)(\.\d+)/', $minTime, $matches );
$minTime = strtotime($matches[1]).$matches[2];
$where[] = "TimeKey >= ".$minTime;
}
if ( $maxTime )
{
preg_match( '/(.+)(\.\d+)/', $maxTime, $matches );
$maxTime = strtotime($matches[1]).$matches[2];
$where[] = "TimeKey <= ".$maxTime;
}
foreach ( $filter as $field=>$value )
if ( $value != '' )
if ( $field == 'Level' )
$where[] = dbEscape($field)." <= ".dbEscape($value);
else
$where[] = dbEscape($field)." = '".dbEscape($value)."'";
if ( count($where) )
$sql.= " where ".join( " and ", $where );
$sql .= " order by ".dbEscape($sortField)." ".dbEscape($sortOrder);
//$sql .= " limit ".dbEscape($limit);
$format = isset($_POST['format'])?$_POST['format']:'text';
switch( $format )
{
case 'text' :
$exportExt = "txt";
break;
case 'tsv' :
$exportExt = "tsv";
break;
case 'html' :
$exportExt = "html";
break;
case 'xml' :
$exportExt = "xml";
break;
default :
Fatal( "Unrecognised log export format '$format'" );
}
$exportKey = substr(md5(rand()),0,8);
$exportFile = "zm-log.$exportExt";
$exportPath = "temp/zm-log-$exportKey.$exportExt";
if ( !($exportFP = fopen( $exportPath, "w" )) )
Fatal( "Unable to open log export file $exportFile" );
$logs = array();
foreach ( dbFetchAll( $sql ) as $log )
{
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
$logs[] = $log;
}
switch( $format )
{
case 'text' :
{
foreach ( $logs as $log )
{
if ( $log['Line'] )
fprintf( $exportFP, "%s %s[%d].%s-%s/%d [%s]\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Line'], $log['Message'] );
else
fprintf( $exportFP, "%s %s[%d].%s-%s [%s]\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Message'] );
}
break;
}
case 'tsv' :
{
fprintf( $exportFP, $SLANG['DateTime']."\t".$SLANG['Component']."\t".$SLANG['Pid']."\t".$SLANG['Level']."\t".$SLANG['Message']."\t".$SLANG['File']."\t".$SLANG['Line']."\n" );
foreach ( $logs as $log )
{
fprintf( $exportFP, "%s\t%s\t%d\t%s\t%s\t%s\t%s\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
}
break;
}
case 'html' :
{
fwrite( $exportFP,
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>'.$SLANG['ZoneMinderLog'].'</title>
<style type="text/css">
body, h3, p, table, td {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
table {
border-collapse: collapse;
width: 100%;
}
th {
font-weight: bold;
}
th, td {
border: 1px solid #888888;
padding: 1px 2px;
}
tr.log-fat td {
background-color:#ffcccc;
font-weight: bold;
font-style: italic;
}
tr.log-err td {
background-color:#ffcccc;
}
tr.log-war td {
background-color: #ffe4b5;
}
tr.log-dbg td {
color: #666666;
font-style: italic;
}
</style>
</head>
<body>
<h3>'.$SLANG['ZoneMinderLog'].'</h3>
<p>'.htmlspecialchars(preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG )).'</p>
<p>'.count($logs).' '.$SLANG['Logs'].'</p>
<table>
<tbody>
<tr><th>'.$SLANG['DateTime'].'</th><th>'.$SLANG['Component'].'</th><th>'.$SLANG['Pid'].'</th><th>'.$SLANG['Level'].'</th><th>'.$SLANG['Message'].'</th><th>'.$SLANG['File'].'</th><th>'.$SLANG['Line'].'</th></tr>
' );
foreach ( $logs as $log )
{
$classLevel = $log['Level'];
if ( $classLevel < Logger::FATAL )
$classLevel = Logger::FATAL;
elseif ( $classLevel > Logger::DEBUG )
$classLevel = Logger::DEBUG;
$logClass = 'log-'.strtolower(Logger::$codes[$classLevel]);
fprintf( $exportFP, " <tr class=\"%s\"><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $logClass, $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
}
fwrite( $exportFP,
' </tbody>
</table>
</body>
</html>' );
break;
}
case 'xml' :
{
fwrite( $exportFP,
'<?xml version="1.0" encoding="utf-8"?>
<logexport title="'.$SLANG['ZoneMinderLog'].'" date="'.htmlspecialchars(preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG )).'">
<selector>'.$_POST['selector'].'</selector>' );
foreach ( $filter as $field=>$value )
if ( $value != '' )
fwrite( $exportFP,
' <filter>
<'.strtolower($field).'>'.htmlspecialchars($value).'</'.strtolower($field).'>
</filter>' );
fwrite( $exportFP,
' <columns>
<column field="datetime">'.$SLANG['DateTime'].'</column><column field="component">'.$SLANG['Component'].'</column><column field="pid">'.$SLANG['Pid'].'</column><column field="level">'.$SLANG['Level'].'</column><column field="message">'.$SLANG['Message'].'</column><column field="file">'.$SLANG['File'].'</column><column field="line">'.$SLANG['Line'].'</column>
</columns>
<logs count="'.count($logs).'">
' );
foreach ( $logs as $log )
{
fprintf( $exportFP,
" <log>
<datetime>%s</datetime>
<component>%s</component>
<pid>%d</pid>
<level>%s</level>
<message><![CDATA[%s]]></message>
<file>%s</file>
<line>%d</line>
</log>\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], utf8_decode( $log['Message'] ), $log['File'], $log['Line'] );
}
fwrite( $exportFP,
' </logs>
</logexport>' );
break;
}
$exportExt = "xml";
break;
}
fclose( $exportFP );
ajaxResponse( array(
'key' => $exportKey,
'format' => $format,
) );
break;
}
case 'download' :
{
if ( !canView( 'System' ) )
ajaxError( 'Insufficient permissions to download logs' );
if ( empty($_REQUEST['key']) )
Fatal( "No log export key given" );
$exportKey = $_REQUEST['key'];
if ( empty($_REQUEST['format']) )
Fatal( "No log export format given" );
$format = $_REQUEST['format'];
switch( $format )
{
case 'text' :
$exportExt = "txt";
break;
case 'tsv' :
$exportExt = "tsv";
break;
case 'html' :
$exportExt = "html";
break;
case 'xml' :
$exportExt = "xml";
break;
default :
Fatal( "Unrecognised log export format '$format'" );
}
$exportFile = "zm-log.$exportExt";
$exportPath = "temp/zm-log-$exportKey.$exportExt";
header( "Pragma: public" );
header( "Expires: 0" );
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
header( "Cache-Control: private", false ); // required by certain browsers
header( "Content-Description: File Transfer" );
header( 'Content-Disposition: attachment; filename="'.$exportFile.'"' );
header( "Content-Transfer-Encoding: binary" );
header( "Content-Type: application/force-download" );
header( "Content-Length: ".filesize($exportPath) );
readfile( $exportPath );
exit( 0 );
break;
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );
?>

View File

@ -1,413 +0,0 @@
<?php
$statusData = array(
"system" => array(
"permission" => "System",
"table" => "Monitors",
"limit" => 1,
"elements" => array(
"MonitorCount" => array( "sql" => "count(*)" ),
"ActiveMonitorCount" => array( "sql" => "count(if(Function != 'None',1,NULL))" ),
"State" => array( "func" => "daemonCheck()?".$SLANG['Running'].":".$SLANG['Stopped'] ),
"Load" => array( "func" => "getLoad()" ),
"Disk" => array( "func" => "getDiskPercent()" ),
),
),
"monitor" => array(
"permission" => "Monitors",
"table" => "Monitors",
"limit" => 1,
"selector" => "Monitors.Id",
"elements" => array(
"Id" => array( "sql" => "Monitors.Id" ),
"Name" => array( "sql" => "Monitors.Name" ),
"Type" => true,
"Function" => true,
"Enabled" => true,
"LinkedMonitors" => true,
"Triggers" => true,
"Device" => true,
"Channel" => true,
"Format" => true,
"Host" => true,
"Port" => true,
"Path" => true,
"Width" => array( "sql" => "Monitors.Width" ),
"Height" => array( "sql" => "Monitors.Height" ),
"Palette" => true,
"Orientation" => true,
"Brightness" => true,
"Contrast" => true,
"Hue" => true,
"Colour" => true,
"EventPrefix" => true,
"LabelFormat" => true,
"LabelX" => true,
"LabelY" => true,
"ImageBufferCount" => true,
"WarmupCount" => true,
"PreEventCount" => true,
"PostEventCount" => true,
"AlarmFrameCount" => true,
"SectionLength" => true,
"FrameSkip" => true,
"MaxFPS" => true,
"AlarmMaxFPS" => true,
"FPSReportInterval" => true,
"RefBlendPerc" => true,
"Controllable" => true,
"ControlId" => true,
"ControlDevice" => true,
"ControlAddress" => true,
"AutoStopTimeout" => true,
"TrackMotion" => true,
"TrackDelay" => true,
"ReturnLocation" => true,
"ReturnDelay" => true,
"DefaultView" => true,
"DefaultRate" => true,
"DefaultScale" => true,
"WebColour" => true,
"Sequence" => true,
"MinEventId" => array( "sql" => "min(Events.Id)", "table" => "Events", "join" => "Events.MonitorId = Monitors.Id", "group" => "Events.MonitorId" ),
"MaxEventId" => array( "sql" => "max(Events.Id)", "table" => "Events", "join" => "Events.MonitorId = Monitors.Id", "group" => "Events.MonitorId" ),
"TotalEvents" => array( "sql" => "count(Events.Id)", "table" => "Events", "join" => "Events.MonitorId = Monitors.Id", "group" => "Events.MonitorId" ),
"Status" => array( "zmu" => "-m ".escapeshellarg($_REQUEST['id'][0])." -s" ),
"FrameRate" => array( "zmu" => "-m ".escapeshellarg($_REQUEST['id'][0])." -f" ),
),
),
"events" => array(
"permission" => "Events",
"table" => "Events",
"selector" => "Events.MonitorId",
"elements" => array(
"Id" => true,
"Name" => true,
"Cause" => true,
"Notes" => true,
"StartTime" => true,
"StartTimeShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ),
"EndTime" => true,
"Width" => true,
"Height" => true,
"Length" => true,
"Frames" => true,
"AlarmFrames" => true,
"TotScore" => true,
"AvgScore" => true,
"MaxScore" => true,
),
),
"event" => array(
"permission" => "Events",
"table" => "Events",
"limit" => 1,
"selector" => "Events.Id",
"elements" => array(
"Id" => array( "sql" => "Events.Id" ),
"MonitorId" => true,
"Name" => true,
"Cause" => true,
"StartTime" => true,
"StartTimeShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ),
"EndTime" => true,
"Width" => true,
"Height" => true,
"Length" => true,
"Frames" => true,
"AlarmFrames" => true,
"TotScore" => true,
"AvgScore" => true,
"MaxScore" => true,
"Archived" => true,
"Videoed" => true,
"Uploaded" => true,
"Emailed" => true,
"Messaged" => true,
"Executed" => true,
"Notes" => true,
"MinFrameId" => array( "sql" => "min(Frames.FrameId)", "table" => "Frames", "join" => "Events.Id = Frames.EventId", "group" => "Frames.EventId" ),
"MaxFrameId" => array( "sql" => "max(Frames.FrameId)", "table" => "Frames", "join" => "Events.Id = Frames.EventId", "group" => "Frames.EventId" ),
"MinFrameDelta" => array( "sql" => "min(Frames.Delta)", "table" => "Frames", "join" => "Events.Id = Frames.EventId", "group" => "Frames.EventId" ),
"MaxFrameDelta" => array( "sql" => "max(Frames.Delta)", "table" => "Frames", "join" => "Events.Id = Frames.EventId", "group" => "Frames.EventId" ),
//"Path" => array( "postFunc" => "getEventPath" ),
),
),
"frame" => array(
"permission" => "Events",
"table" => "Frames",
"limit" => 1,
"selector" => array( array( "table" => "Events", "join" => "Events.Id = Frames.EventId", "selector"=>"Events.Id" ), "Frames.FrameId" ),
"elements" => array(
//"Id" => array( "sql" => "Frames.FrameId" ),
"FrameId" => true,
"EventId" => true,
"Type" => true,
"TimeStamp" => true,
"TimeStampShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ),
"Delta" => true,
"Score" => true,
//"Image" => array( "postFunc" => "getFrameImage" ),
),
),
"frameimage" => array(
"permission" => "Events",
"func" => "getFrameImage()"
),
"nearframe" => array(
"permission" => "Events",
"func" => "getNearFrame()"
),
"nearevents" => array(
"permission" => "Events",
"func" => "getNearEvents()"
)
);
function collectData()
{
global $statusData;
$entitySpec = &$statusData[strtolower(validJsStr($_REQUEST['entity']))];
#print_r( $entitySpec );
if ( !canView( $entitySpec['permission'] ) )
ajaxError( 'Unrecognised action or insufficient permissions' );
if ( !empty($entitySpec['func']) )
{
$data = eval( "return( ".$entitySpec['func']." );" );
}
else
{
$data = array();
$postFuncs = array();
$fieldSql = array();
$joinSql = array();
$groupSql = array();
$elements = &$entitySpec['elements'];
$lc_elements = array_change_key_case( $elements );
$id = false;
if ( isset($_REQUEST['id']) )
if ( !is_array($_REQUEST['id']) )
$id = array( validJsStr($_REQUEST['id']) );
else
$id = array_values( $_REQUEST['id'] );
if ( !isset($_REQUEST['element']) )
$_REQUEST['element'] = array_keys( $elements );
else if ( !is_array($_REQUEST['element']) )
$_REQUEST['element'] = array( validJsStr($_REQUEST['element']) );
if ( isset($entitySpec['selector']) )
{
if ( !is_array($entitySpec['selector']) )
$entitySpec['selector'] = array( $entitySpec['selector'] );
foreach( $entitySpec['selector'] as $selector )
if ( is_array( $selector ) && isset($selector['table']) && isset($selector['join']) )
$joinSql[] = "left join ".$selector['table']." on ".$selector['join'];
}
foreach ( $_REQUEST['element'] as $element )
{
if ( !($elementData = $lc_elements[strtolower($element)]) )
ajaxError( "Bad ".validJsStr($_REQUEST['entity'])." element ".$element );
if ( isset($elementData['func']) )
$data[$element] = eval( "return( ".$elementData['func']." );" );
else if ( isset($elementData['postFunc']) )
$postFuncs[$element] = $elementData['postFunc'];
else if ( isset($elementData['zmu']) )
$data[$element] = exec( escapeshellcmd( getZmuCommand( " ".$elementData['zmu'] ) ) );
else
{
if ( isset($elementData['sql']) )
$fieldSql[] = $elementData['sql']." as ".$element;
else
$fieldSql[] = $element;
if ( isset($elementData['table']) && isset($elementData['join']) )
{
$joinSql[] = "left join ".$elementData['table']." on ".$elementData['join'];
}
if ( isset($elementData['group']) )
{
$groupSql[] = $elementData['group'];
}
}
}
if ( count($fieldSql) )
{
$sql = "select ".join( ", ", $fieldSql )." from ".$entitySpec['table'];
if ( $joinSql )
$sql .= " ".join( " ", array_unique( $joinSql ) );
if ( $id && !empty($entitySpec['selector']) )
{
$index = 0;
$where = array();
foreach( $entitySpec['selector'] as $selector )
{
if ( is_array( $selector ) )
$where[] = $selector['selector']." = ".dbEscape($id[$index]);
else
$where[] = $selector." = ".dbEscape($id[$index]);
$index++;
}
$sql .= " where ".join( " and ", $where );
}
if ( $groupSql )
$sql .= " group by ".join( ",", array_unique( $groupSql ) );
if ( !empty($_REQUEST['sort']) )
$sql .= " order by ".dbEscape($_REQUEST['sort']);
if ( !empty($entitySpec['limit']) )
$limit = $entitySpec['limit'];
elseif ( !empty($_REQUEST['count']) )
$limit = dbEscape($_REQUEST['count']);
if ( !empty( $limit ) )
$sql .= " limit ".$limit;
if ( isset($limit) && $limit == 1 )
{
if ( $sqlData = dbFetchOne( $sql ) )
{
foreach ( $postFuncs as $element=>$func )
$sqlData[$element] = eval( 'return( '.$func.'( $sqlData ) );' );
$data = array_merge( $data, $sqlData );
}
}
else
{
$count = 0;
foreach( dbFetchAll( $sql ) as $sqlData )
{
foreach ( $postFuncs as $element=>$func )
$sqlData[$element] = eval( 'return( '.$func.'( $sqlData ) );' );
$data[] = $sqlData;
if ( isset($limi) && ++$count >= $limit )
break;
}
}
}
}
#print_r( $data );
return( $data );
}
$data = collectData();
if ( !isset($_REQUEST['layout']) )
{
$_REQUEST['layout'] = "json";
}
switch( $_REQUEST['layout'] )
{
case 'xml NOT CURRENTLY SUPPORTED' :
{
header("Content-type: application/xml" );
echo( '<?xml version="1.0" encoding="iso-8859-1"?>'."\n" );
echo "<".strtolower($_REQUEST['entity']).">\n";
foreach ( $data as $key=>$value )
{
$key = strtolower( $key );
echo "<$key>".htmlentities($value)."</$key>\n";
}
echo "</".strtolower($_REQUEST['entity']).">\n";
break;
}
case 'json' :
{
$response = array( strtolower(validJsStr($_REQUEST['entity'])) => $data );
if ( isset($_REQUEST['loopback']) )
$response['loopback'] = validJsStr($_REQUEST['loopback']);
ajaxResponse( $response );
break;
}
case 'text' :
{
header("Content-type: text/plain" );
echo join( " ", array_values( $data ) );
break;
}
}
function getFrameImage()
{
$eventId = dbEscape($_REQUEST['id'][0]);
$frameId = dbEscape($_REQUEST['id'][1]);
$sql = "select * from Frames where EventId = '".$eventId."' and FrameId = '".$frameId."'";
if ( !($frame = dbFetchOne( $sql )) )
{
$frame = array();
$frame['EventId'] = $eventId;
$frame['FrameId'] = $frameId;
$frame['Type'] = "Virtual";
}
$event = dbFetchOne( "select * from Events where Id = '".$frame['EventId']."'" );
$frame['Image'] = getImageSrc( $event, $frame, SCALE_BASE );
return( $frame );
}
function getNearFrame()
{
$eventId = dbEscape($_REQUEST['id'][0]);
$frameId = dbEscape($_REQUEST['id'][1]);
$sql = "select FrameId from Frames where EventId = '".$eventId."' and FrameId <= '".$frameId."' order by FrameId desc limit 1";
if ( !$nearFrameId = dbFetchOne( $sql, 'FrameId' ) )
{
$sql = "select * from Frames where EventId = '".$eventId."' and FrameId > '".$frameId."' order by FrameId asc limit 1";
if ( !$nearFrameId = dbFetchOne( $sql, 'FrameId' ) )
{
return( array() );
}
}
$_REQUEST['entity'] = "frame";
$_REQUEST['id'][1] = $nearFrameId;
return( collectData() );
}
function getNearEvents()
{
global $user, $sortColumn, $sortOrder;
$eventId = dbEscape($_REQUEST['id']);
$event = dbFetchOne( "select * from Events where Id = '".$eventId."'" );
parseFilter( $_REQUEST['filter'] );
parseSort();
if ( $user['MonitorIds'] )
$midSql = " and MonitorId in (".join( ",", preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) ).")";
else
$midSql = '';
$sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where ".dbEscape($sortColumn)." ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn ".($sortOrder=='asc'?'desc':'asc');
$result = dbQuery( $sql );
while ( $id = dbFetchNext( $result, 'Id' ) )
{
if ( $id == $eventId )
{
$prevId = dbFetchNext( $result, 'Id' );
break;
}
}
$sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'>=':'<=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn $sortOrder";
$result = dbQuery( $sql );
while ( $id = dbFetchNext( $result, 'Id' ) )
{
if ( $id == $eventId )
{
$nextId = dbFetchNext( $result, 'Id' );
break;
}
}
$result = array( 'EventId'=>$eventId );
$result['PrevEventId'] = empty($prevId)?0:$prevId;
$result['NextEventId'] = empty($nextId)?0:$nextId;
return( $result );
}
?>

View File

@ -1,135 +0,0 @@
<?php
define( "MSG_TIMEOUT", ZM_WEB_AJAX_TIMEOUT );
define( "MSG_DATA_SIZE", 4+256 );
if ( !($_REQUEST['connkey'] && $_REQUEST['command']) )
{
ajaxError( "Unexpected received message type '$type'" );
}
if ( !($socket = @socket_create( AF_UNIX, SOCK_DGRAM, 0 )) )
{
ajaxError( "socket_create() failed: ".socket_strerror(socket_last_error()) );
}
$locSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf("%06d",$_REQUEST['connkey']).'w.sock';
if ( !@socket_bind( $socket, $locSockFile ) )
{
ajaxError( "socket_bind( $locSockFile ) failed: ".socket_strerror(socket_last_error()) );
}
switch ( $_REQUEST['command'] )
{
case CMD_VARPLAY :
Debug( "Varplaying to ".$_REQUEST['rate'] );
$msg = pack( "lcn", MSG_CMD, $_REQUEST['command'], $_REQUEST['rate']+32768 );
break;
case CMD_ZOOMIN :
Debug( "Zooming to ".$_REQUEST['x'].",".$_REQUEST['y'] );
$msg = pack( "lcnn", MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] );
break;
case CMD_PAN :
Debug( "Panning to ".$_REQUEST['x'].",".$_REQUEST['y'] );
$msg = pack( "lcnn", MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] );
break;
case CMD_SCALE :
Debug( "Scaling to ".$_REQUEST['scale'] );
$msg = pack( "lcn", MSG_CMD, $_REQUEST['command'], $_REQUEST['scale'] );
break;
case CMD_SEEK :
Debug( "Seeking to ".$_REQUEST['offset'] );
$msg = pack( "lcN", MSG_CMD, $_REQUEST['command'], $_REQUEST['offset'] );
break;
default :
$msg = pack( "lc", MSG_CMD, $_REQUEST['command'] );
break;
}
$remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf("%06d",$_REQUEST['connkey']).'s.sock';
$max_socket_tries = 3;
while ( !file_exists($remSockFile) && $max_socket_tries-- ) //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
sleep(1);
if ( !@socket_sendto( $socket, $msg, strlen($msg), 0, $remSockFile ) )
{
ajaxError( "socket_sendto( $remSockFile ) failed: ".socket_strerror(socket_last_error()) );
}
$rSockets = array( $socket );
$wSockets = NULL;
$eSockets = NULL;
$numSockets = @socket_select( $rSockets, $wSockets, $eSockets, intval(MSG_TIMEOUT/1000), (MSG_TIMEOUT%1000)*1000 );
if ( $numSockets === false )
{
ajaxError( "socket_select failed: ".socket_strerror(socket_last_error()) );
}
else if ( $numSockets == 0 )
{
ajaxError( "Timed out waiting for msg" );
}
else if ( $numSockets > 0 )
{
if ( count($rSockets) != 1 )
ajaxError( "Bogus return from select, ".count($rSockets)." sockets available" );
}
switch( $nbytes = @socket_recvfrom( $socket, $msg, MSG_DATA_SIZE, 0, $remSockFile ) )
{
case -1 :
{
ajaxError( "socket_recvfrom( $remSockFile ) failed: ".socket_strerror(socket_last_error()) );
break;
}
case 0 :
{
ajaxError( "No data to read from socket" );
break;
}
default :
{
if ( $nbytes != MSG_DATA_SIZE )
ajaxError( "Got unexpected message size, got $nbytes, expected ".MSG_DATA_SIZE );
break;
}
}
$data = unpack( "ltype", $msg );
switch ( $data['type'] )
{
case MSG_DATA_WATCH :
{
$data = unpack( "ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced", $msg );
$data['fps'] = sprintf( "%.2f", $data['fps'] );
$data['rate'] /= RATE_BASE;
$data['delay'] = sprintf( "%.2f", $data['delay'] );
$data['zoom'] = sprintf( "%.1f", $data['zoom']/SCALE_BASE );
ajaxResponse( array( 'status'=>$data ) );
break;
}
case MSG_DATA_EVENT :
{
$data = unpack( "ltype/ievent/iprogress/irate/izoom/Cpaused", $msg );
//$data['progress'] = sprintf( "%.2f", $data['progress'] );
$data['rate'] /= RATE_BASE;
$data['zoom'] = sprintf( "%.1f", $data['zoom']/SCALE_BASE );
ajaxResponse( array( 'status'=>$data ) );
break;
}
default :
{
ajaxError( "Unexpected received message type '$type'" );
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );
function ajaxCleanup()
{
global $socket, $locSockFile;
if ( !empty( $socket ) )
@socket_close( $socket );
if ( !empty( $locSockFile ) )
@unlink( $locSockFile );
}
?>

View File

@ -1,45 +0,0 @@
<?php
if ( empty($_REQUEST['mid']) )
{
ajaxError( 'No monitor id supplied' );
}
elseif ( !isset($_REQUEST['zid']) )
{
ajaxError( 'No zone id(s) supplied' );
}
if ( canView( 'Monitors' ) )
{
switch ( $_REQUEST['action'] )
{
case "zoneImage" :
{
$wd = getcwd();
chdir( ZM_DIR_IMAGES );
$hiColor = "0x00ff00";
$command = getZmuCommand( " -m ".$_REQUEST['mid']." -z" );
if ( !isset($_REQUEST['zid']) )
$_REQUEST['zid'] = 0;
$command .= "'".$_REQUEST['zid'].' '.$hiColor.' '.$_REQUEST['coords']."'";
$status = exec( escapeshellcmd($command) );
chdir( $wd );
$monitor = dbFetchOne( "select * from Monitors where Id = '".dbEscape($_REQUEST['mid'])."'" );
$points = coordsToPoints( $_REQUEST['coords'] );
ajaxResponse( array(
'zoneImage' => ZM_DIR_IMAGES.'/Zones'.$monitor['Id'].'.jpg?'.time(),
'selfIntersecting' => isSelfIntersecting( $points ),
'area' => getPolyArea( $points )
) );
break;
}
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );
?>

5
web/app/.htaccess Normal file
View File

@ -0,0 +1,5 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>

View File

@ -0,0 +1,73 @@
<?php
/**
* This is Acl Schema file
*
* Use it to configure database for ACL
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config.Schema
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/*
*
* Using the Schema command line utility
* cake schema run create DbAcl
*
*/
class DbAclSchema extends CakeSchema {
public $name = 'DbAcl';
public function before($event = array()) {
return true;
}
public function after($event = array()) {
}
public $acos = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'model' => array('type' => 'string', 'null' => true),
'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'alias' => array('type' => 'string', 'null' => true),
'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
);
public $aros = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'model' => array('type' => 'string', 'null' => true),
'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'alias' => array('type' => 'string', 'null' => true),
'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
);
public $aros_acos = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
'aro_id' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
'aco_id' => array('type' => 'integer', 'null' => false, 'length' => 10),
'_create' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
'_read' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
'_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
'_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1))
);
}

View File

@ -0,0 +1,41 @@
# $Id$
#
# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
#
# Licensed under The MIT License
# For full copyright and license information, please see the LICENSE.txt
# Redistributions of files must retain the above copyright notice.
# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE acos (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER(10) DEFAULT NULL,
model VARCHAR(255) DEFAULT '',
foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
alias VARCHAR(255) DEFAULT '',
lft INTEGER(10) DEFAULT NULL,
rght INTEGER(10) DEFAULT NULL,
PRIMARY KEY (id)
);
CREATE TABLE aros_acos (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
aro_id INTEGER(10) UNSIGNED NOT NULL,
aco_id INTEGER(10) UNSIGNED NOT NULL,
_create CHAR(2) NOT NULL DEFAULT 0,
_read CHAR(2) NOT NULL DEFAULT 0,
_update CHAR(2) NOT NULL DEFAULT 0,
_delete CHAR(2) NOT NULL DEFAULT 0,
PRIMARY KEY(id)
);
CREATE TABLE aros (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER(10) DEFAULT NULL,
model VARCHAR(255) DEFAULT '',
foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
alias VARCHAR(255) DEFAULT '',
lft INTEGER(10) DEFAULT NULL,
rght INTEGER(10) DEFAULT NULL,
PRIMARY KEY (id)
);

View File

@ -0,0 +1,52 @@
<?php
/**
* This is i18n Schema file
*
* Use it to configure database for i18n
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config.Schema
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
*
* Using the Schema command line utility
*
* Use it to configure database for i18n
*
* cake schema run create i18n
*/
class I18nSchema extends CakeSchema {
public $name = 'i18n';
public function before($event = array()) {
return true;
}
public function after($event = array()) {
}
public $i18n = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
'locale' => array('type' => 'string', 'null' => false, 'length' => 6, 'key' => 'index'),
'model' => array('type' => 'string', 'null' => false, 'key' => 'index'),
'foreign_key' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
'field' => array('type' => 'string', 'null' => false, 'key' => 'index'),
'content' => array('type' => 'text', 'null' => true, 'default' => null),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'locale' => array('column' => 'locale', 'unique' => 0), 'model' => array('column' => 'model', 'unique' => 0), 'row_id' => array('column' => 'foreign_key', 'unique' => 0), 'field' => array('column' => 'field', 'unique' => 0))
);
}

View File

@ -0,0 +1,27 @@
# $Id$
#
# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
#
# Licensed under The MIT License
# For full copyright and license information, please see the LICENSE.txt
# Redistributions of files must retain the above copyright notice.
# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE i18n (
id int(10) NOT NULL auto_increment,
locale varchar(6) NOT NULL,
model varchar(255) NOT NULL,
foreign_key int(10) NOT NULL,
field varchar(255) NOT NULL,
content mediumtext,
PRIMARY KEY (id),
# UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
# INDEX I18N_LOCALE_ROW(locale, model, foreign_key),
# INDEX I18N_LOCALE_MODEL(locale, model),
# INDEX I18N_FIELD(model, foreign_key, field),
# INDEX I18N_ROW(model, foreign_key),
INDEX locale (locale),
INDEX model (model),
INDEX row_id (foreign_key),
INDEX field (field)
);

View File

@ -0,0 +1,47 @@
<?php
/**
* This is Sessions Schema file
*
* Use it to configure database for Sessions
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config.Schema
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/*
*
* Using the Schema command line utility
* cake schema run create Sessions
*
*/
class SessionsSchema extends CakeSchema {
public $name = 'Sessions';
public function before($event = array()) {
return true;
}
public function after($event = array()) {
}
public $cake_sessions = array(
'id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
'data' => array('type' => 'text', 'null' => true, 'default' => null),
'expires' => array('type' => 'integer', 'null' => true, 'default' => null),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
);
}

View File

@ -0,0 +1,17 @@
# $Id$
#
# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
# 1785 E. Sahara Avenue, Suite 490-204
# Las Vegas, Nevada 89104
#
# Licensed under The MIT License
# For full copyright and license information, please see the LICENSE.txt
# Redistributions of files must retain the above copyright notice.
# MIT License (http://www.opensource.org/licenses/mit-license.php)
CREATE TABLE cake_sessions (
id varchar(255) NOT NULL default '',
data text,
expires int(11) default NULL,
PRIMARY KEY (id)
);

View File

@ -0,0 +1,68 @@
;<?php exit() ?>
;/**
; * ACL Configuration
; *
; *
; * PHP 5
; *
; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
; * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
; *
; * Licensed under The MIT License
; * Redistributions of files must retain the above copyright notice.
; *
; * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
; * @link http://cakephp.org CakePHP(tm) Project
; * @package app.Config
; * @since CakePHP(tm) v 0.10.0.1076
; * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
; */
; acl.ini.php - Cake ACL Configuration
; ---------------------------------------------------------------------
; Use this file to specify user permissions.
; aco = access control object (something in your application)
; aro = access request object (something requesting access)
;
; User records are added as follows:
;
; [uid]
; groups = group1, group2, group3
; allow = aco1, aco2, aco3
; deny = aco4, aco5, aco6
;
; Group records are added in a similar manner:
;
; [gid]
; allow = aco1, aco2, aco3
; deny = aco4, aco5, aco6
;
; The allow, deny, and groups sections are all optional.
; NOTE: groups names *cannot* ever be the same as usernames!
;
; ACL permissions are checked in the following order:
; 1. Check for user denies (and DENY if specified)
; 2. Check for user allows (and ALLOW if specified)
; 3. Gather user's groups
; 4. Check group denies (and DENY if specified)
; 5. Check group allows (and ALLOW if specified)
; 6. If no aro, aco, or group information is found, DENY
;
; ---------------------------------------------------------------------
;-------------------------------------
;Users
;-------------------------------------
[username-goes-here]
groups = group1, group2
deny = aco1, aco2
allow = aco3, aco4
;-------------------------------------
;Groups
;-------------------------------------
[groupname-goes-here]
deny = aco5, aco6
allow = aco7, aco8

135
web/app/Config/acl.php Normal file
View File

@ -0,0 +1,135 @@
<?php
/**
* This is the PHP base ACL configuration file.
*
* Use it to configure access control of your Cake application.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 2.1
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Example
* -------
*
* Assumptions:
*
* 1. In your application you created a User model with the following properties:
* username, group_id, password, email, firstname, lastname and so on.
* 2. You configured AuthComponent to authorize actions via
* $this->Auth->authorize = array('Actions' => array('actionPath' => 'controllers/'),...)
*
* Now, when a user (i.e. jeff) authenticates successfully and requests a controller action (i.e. /invoices/delete)
* that is not allowed by default (e.g. via $this->Auth->allow('edit') in the Invoices controller) then AuthComponent
* will ask the configured ACL interface if access is granted. Under the assumptions 1. and 2. this will be
* done via a call to Acl->check() with
*
* array('User' => array('username' => 'jeff', 'group_id' => 4, ...))
*
* as ARO and
*
* '/controllers/invoices/delete'
*
* as ACO.
*
* If the configured map looks like
*
* $config['map'] = array(
* 'User' => 'User/username',
* 'Role' => 'User/group_id',
* );
*
* then PhpAcl will lookup if we defined a role like User/jeff. If that role is not found, PhpAcl will try to
* find a definition for Role/4. If the definition isn't found then a default role (Role/default) will be used to
* check rules for the given ACO. The search can be expanded by defining aliases in the alias configuration.
* E.g. if you want to use a more readable name than Role/4 in your definitions you can define an alias like
*
* $config['alias'] = array(
* 'Role/4' => 'Role/editor',
* );
*
* In the roles configuration you can define roles on the lhs and inherited roles on the rhs:
*
* $config['roles'] = array(
* 'Role/admin' => null,
* 'Role/accountant' => null,
* 'Role/editor' => null,
* 'Role/manager' => 'Role/editor, Role/accountant',
* 'User/jeff' => 'Role/manager',
* );
*
* In this example manager inherits all rules from editor and accountant. Role/admin doesn't inherit from any role.
* Lets define some rules:
*
* $config['rules'] = array(
* 'allow' => array(
* '*' => 'Role/admin',
* 'controllers/users/(dashboard|profile)' => 'Role/default',
* 'controllers/invoices/*' => 'Role/accountant',
* 'controllers/articles/*' => 'Role/editor',
* 'controllers/users/*' => 'Role/manager',
* 'controllers/invoices/delete' => 'Role/manager',
* ),
* 'deny' => array(
* 'controllers/invoices/delete' => 'Role/accountant, User/jeff',
* 'controllers/articles/(delete|publish)' => 'Role/editor',
* ),
* );
*
* Ok, so as jeff inherits from Role/manager he's matched every rule that references User/jeff, Role/manager,
* Role/editor, Role/accountant and Role/default. However, for jeff, rules for User/jeff are more specific than
* rules for Role/manager, rules for Role/manager are more specific than rules for Role/editor and so on.
* This is important when allow and deny rules match for a role. E.g. Role/accountant is allowed
* controllers/invoices/* but at the same time controllers/invoices/delete is denied. But there is a more
* specific rule defined for Role/manager which is allowed controllers/invoices/delete. However, the most specific
* rule denies access to the delete action explicitly for User/jeff, so he'll be denied access to the resource.
*
* If we would remove the role definition for User/jeff, then jeff would be granted access as he would be resolved
* to Role/manager and Role/manager has an allow rule.
*/
/**
* The role map defines how to resolve the user record from your application
* to the roles you defined in the roles configuration.
*/
$config['map'] = array(
'User' => 'User/username',
'Role' => 'User/group_id',
);
/**
* define aliases to map your model information to
* the roles defined in your role configuration.
*/
$config['alias'] = array(
'Role/4' => 'Role/editor',
);
/**
* role configuration
*/
$config['roles'] = array(
'Role/admin' => null,
);
/**
* rule configuration
*/
$config['rules'] = array(
'allow' => array(
'*' => 'Role/admin',
),
'deny' => array(),
);

View File

@ -0,0 +1,110 @@
<?php
/**
* This file is loaded automatically by the app/webroot/index.php file after core.php
*
* This file should load/create any application wide configuration settings, such as
* Caching, Logging, loading additional configuration files.
*
* You should also use this file to include any files that provide global functions/constants
* that your application uses.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 0.10.8.2117
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
// Setup a 'default' cache configuration for use in the application.
Cache::config('default', array('engine' => 'File'));
CakePlugin::loadAll();
/**
* The settings below can be used to set additional paths to models, views and controllers.
*
* App::build(array(
* 'Model' => array('/path/to/models', '/next/path/to/models'),
* 'Model/Behavior' => array('/path/to/behaviors', '/next/path/to/behaviors'),
* 'Model/Datasource' => array('/path/to/datasources', '/next/path/to/datasources'),
* 'Model/Datasource/Database' => array('/path/to/databases', '/next/path/to/database'),
* 'Model/Datasource/Session' => array('/path/to/sessions', '/next/path/to/sessions'),
* 'Controller' => array('/path/to/controllers', '/next/path/to/controllers'),
* 'Controller/Component' => array('/path/to/components', '/next/path/to/components'),
* 'Controller/Component/Auth' => array('/path/to/auths', '/next/path/to/auths'),
* 'Controller/Component/Acl' => array('/path/to/acls', '/next/path/to/acls'),
* 'View' => array('/path/to/views', '/next/path/to/views'),
* 'View/Helper' => array('/path/to/helpers', '/next/path/to/helpers'),
* 'Console' => array('/path/to/consoles', '/next/path/to/consoles'),
* 'Console/Command' => array('/path/to/commands', '/next/path/to/commands'),
* 'Console/Command/Task' => array('/path/to/tasks', '/next/path/to/tasks'),
* 'Lib' => array('/path/to/libs', '/next/path/to/libs'),
* 'Locale' => array('/path/to/locales', '/next/path/to/locales'),
* 'Vendor' => array('/path/to/vendors', '/next/path/to/vendors'),
* 'Plugin' => array('/path/to/plugins', '/next/path/to/plugins'),
* ));
*
*/
/**
* Custom Inflector rules, can be set to correctly pluralize or singularize table, model, controller names or whatever other
* string is passed to the inflection functions
*
* Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
* Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
*
*/
/**
* Plugins need to be loaded manually, you can either load them one by one or all of them in a single call
* Uncomment one of the lines below, as you need. make sure you read the documentation on CakePlugin to use more
* advanced ways of loading plugins
*
* CakePlugin::loadAll(); // Loads all plugins at once
* CakePlugin::load('DebugKit'); //Loads a single plugin named DebugKit
*
*/
/**
* You can attach event listeners to the request lifecycle as Dispatcher Filter . By Default CakePHP bundles two filters:
*
* - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins
* - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers
*
* Feel free to remove or add filters as you see fit for your application. A few examples:
*
* Configure::write('Dispatcher.filters', array(
* 'MyCacheFilter', // will use MyCacheFilter class from the Routing/Filter package in your app.
* 'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin.
* array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch
* array('callable' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch
*
* ));
*/
Configure::write('Dispatcher.filters', array(
'AssetDispatcher',
'CacheDispatcher'
));
/**
* Configures default file logging options
*/
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
'engine' => 'FileLog',
'types' => array('notice', 'info', 'debug'),
'file' => 'debug',
));
CakeLog::config('error', array(
'engine' => 'FileLog',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'error',
));

348
web/app/Config/core.php Normal file
View File

@ -0,0 +1,348 @@
<?php
/**
* This is core configuration file.
*
* Use it to configure core behavior of Cake.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* CakePHP Debug Level:
*
* Production Mode:
* 0: No error messages, errors, or warnings shown. Flash messages redirect.
*
* Development Mode:
* 1: Errors and warnings shown, model caches refreshed, flash messages halted.
* 2: As in 1, but also with full debug messages and SQL output.
*
* In production mode, flash messages redirect after a time interval.
* In development mode, you need to click the flash message to continue.
*/
Configure::write('debug', 2);
/**
* Configure the Error handler used to handle errors for your application. By default
* ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0
* and log errors with CakeLog when debug = 0.
*
* Options:
*
* - `handler` - callback - The callback to handle errors. You can set this to any callable type,
* including anonymous functions.
* Make sure you add App::uses('MyHandler', 'Error'); when using a custom handler class
* - `level` - int - The level of errors you are interested in capturing.
* - `trace` - boolean - Include stack traces for errors in log files.
*
* @see ErrorHandler for more information on error handling and configuration.
*/
Configure::write('Error', array(
'handler' => 'ErrorHandler::handleError',
'level' => E_ALL & ~E_DEPRECATED,
'trace' => true
));
/**
* Configure the Exception handler used for uncaught exceptions. By default,
* ErrorHandler::handleException() is used. It will display a HTML page for the exception, and
* while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0,
* framework errors will be coerced into generic HTTP errors.
*
* Options:
*
* - `handler` - callback - The callback to handle exceptions. You can set this to any callback type,
* including anonymous functions.
* Make sure you add App::uses('MyHandler', 'Error'); when using a custom handler class
* - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you
* should place the file for that class in app/Lib/Error. This class needs to implement a render method.
* - `log` - boolean - Should Exceptions be logged?
*
* @see ErrorHandler for more information on exception handling and configuration.
*/
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'ExceptionRenderer',
'log' => true
));
/**
* Application wide charset encoding
*/
Configure::write('App.encoding', 'UTF-8');
/**
* To configure CakePHP *not* to use mod_rewrite and to
* use CakePHP pretty URLs, remove these .htaccess
* files:
*
* /.htaccess
* /app/.htaccess
* /app/webroot/.htaccess
*
* And uncomment the App.baseUrl below. But keep in mind
* that plugin assets such as images, CSS and Javascript files
* will not work without url rewriting!
* To work around this issue you should either symlink or copy
* the plugin assets into you app's webroot directory. This is
* recommended even when you are using mod_rewrite. Handling static
* assets through the Dispatcher is incredibly inefficient and
* included primarily as a development convenience - and
* thus not recommended for production applications.
*/
//Configure::write('App.baseUrl', env('SCRIPT_NAME'));
/**
* Uncomment the define below to use CakePHP prefix routes.
*
* The value of the define determines the names of the routes
* and their associated controller actions:
*
* Set to an array of prefixes you want to use in your application. Use for
* admin or other prefixed routes.
*
* Routing.prefixes = array('admin', 'manager');
*
* Enables:
* `admin_index()` and `/admin/controller/index`
* `manager_index()` and `/manager/controller/index`
*
*/
//Configure::write('Routing.prefixes', array('admin'));
/**
* Turn off all caching application-wide.
*
*/
//Configure::write('Cache.disable', true);
/**
* Enable cache checking.
*
* If set to true, for view caching you must still use the controller
* public $cacheAction inside your controllers to define caching settings.
* You can either set it controller-wide by setting public $cacheAction = true,
* or in each action using $this->cacheAction = true.
*
*/
//Configure::write('Cache.check', true);
/**
* Enable cache view prefixes.
*
* If set it will be prepended to the cache name for view file caching. This is
* helpful if you deploy the same application via multiple subdomains and languages,
* for instance. Each version can then have its own view cache namespace.
* Note: The final cache file name will then be `prefix_cachefilename`.
*/
//Configure::write('Cache.viewPrefix', 'prefix');
/**
* Session configuration.
*
* Contains an array of settings to use for session configuration. The defaults key is
* used to define a default preset to use for sessions, any settings declared here will override
* the settings of the default config.
*
* ## Options
*
* - `Session.cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'
* - `Session.timeout` - The number of minutes you want sessions to live for. This timeout is handled by CakePHP
* - `Session.cookieTimeout` - The number of minutes you want session cookies to live for.
* - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the
* value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX
* - `Session.defaults` - The default configuration set to use as a basis for your session.
* There are four builtins: php, cake, cache, database.
* - `Session.handler` - Can be used to enable a custom session handler. Expects an array of callables,
* that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler`
* to the ini array.
* - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and
* sessionids that change frequently. See CakeSession::$requestCountdown.
* - `Session.ini` - An associative array of additional ini values to set.
*
* The built in defaults are:
*
* - 'php' - Uses settings defined in your php.ini.
* - 'cake' - Saves session files in CakePHP's /tmp directory.
* - 'database' - Uses CakePHP's database sessions.
* - 'cache' - Use the Cache class to save sessions.
*
* To define a custom session handler, save it at /app/Model/Datasource/Session/<name>.php.
* Make sure the class implements `CakeSessionHandlerInterface` and set Session.handler to <name>
*
* To use database sessions, run the app/Config/Schema/sessions.php schema using
* the cake shell command: cake schema create Sessions
*
*/
Configure::write('Session', array(
'defaults' => 'php'
));
/**
* A random string used in security hashing methods.
*/
Configure::write('Security.salt', 'asdklflLKAD89349034klljkaLKADFasdf4348934klxci');
/**
* A random numeric string (digits only) used to encrypt/decrypt strings.
*/
Configure::write('Security.cipherSeed', '902349817681234590765905768091236');
/**
* Apply timestamps with the last modified time to static assets (js, css, images).
* Will append a query string parameter containing the time the file was modified. This is
* useful for invalidating browser caches.
*
* Set to `true` to apply timestamps when debug > 0. Set to 'force' to always enable
* timestamping regardless of debug value.
*/
//Configure::write('Asset.timestamp', true);
/**
* Compress CSS output by removing comments, whitespace, repeating tags, etc.
* This requires a/var/cache directory to be writable by the web server for caching.
* and /vendors/csspp/csspp.php
*
* To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use HtmlHelper::css().
*/
//Configure::write('Asset.filter.css', 'css.php');
/**
* Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the
* output, and setting the config below to the name of the script.
*
* To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JavaScriptHelper::link().
*/
//Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');
/**
* The class name and database used in CakePHP's
* access control lists.
*/
Configure::write('Acl.classname', 'DbAcl');
Configure::write('Acl.database', 'default');
/**
* Uncomment this line and correct your server timezone to fix
* any date & time related errors.
*/
//date_default_timezone_set('UTC');
/**
*
* Cache Engine Configuration
* Default settings provided below
*
* File storage engine.
*
* Cache::config('default', array(
* 'engine' => 'File', //[required]
* 'duration' => 3600, //[optional]
* 'probability' => 100, //[optional]
* 'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
* 'prefix' => 'cake_', //[optional] prefix every cache file with this string
* 'lock' => false, //[optional] use file locking
* 'serialize' => true, [optional]
* ));
*
* APC (http://pecl.php.net/package/APC)
*
* Cache::config('default', array(
* 'engine' => 'Apc', //[required]
* 'duration' => 3600, //[optional]
* 'probability' => 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* ));
*
* Xcache (http://xcache.lighttpd.net/)
*
* Cache::config('default', array(
* 'engine' => 'Xcache', //[required]
* 'duration' => 3600, //[optional]
* 'probability' => 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* 'user' => 'user', //user from xcache.admin.user settings
* 'password' => 'password', //plaintext password (xcache.admin.pass)
* ));
*
* Memcache (http://www.danga.com/memcached/)
*
* Cache::config('default', array(
* 'engine' => 'Memcache', //[required]
* 'duration' => 3600, //[optional]
* 'probability' => 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* 'servers' => array(
* '127.0.0.1:11211' // localhost, default port 11211
* ), //[optional]
* 'persistent' => true, // [optional] set this to false for non-persistent connections
* 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
* ));
*
* Wincache (http://php.net/wincache)
*
* Cache::config('default', array(
* 'engine' => 'Wincache', //[required]
* 'duration' => 3600, //[optional]
* 'probability' => 100, //[optional]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
* ));
*/
/**
* Configure the cache handlers that CakePHP will use for internal
* metadata like class maps, and model schema.
*
* By default File is used, but for improved performance you should use APC.
*
* Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
* Please check the comments in bootstrap.php for more info on the cache engines available
* and their settings.
*/
$engine = 'File';
// In development mode, caches should expire quickly.
$duration = '+999 days';
if (Configure::read('debug') > 0) {
$duration = '+10 seconds';
}
// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
$prefix = 'myapp_';
/**
* Configure the cache used for general framework caching. Path information,
* object listings, and translation cache files are stored with this configuration.
*/
Cache::config('_cake_core_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_core_',
'path' => CACHE . 'persistent' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));
/**
* Configure the cache for model and datasource caches. This cache configuration
* is used to store schema descriptions, and table listings in connections.
*/
Cache::config('_cake_model_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_model_',
'path' => CACHE . 'models' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));

View File

@ -0,0 +1,79 @@
<?php
/**
* This is core configuration file.
*
* Use it to configure core behaviour of Cake.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*
* Database configuration class.
* You can specify multiple configurations for production, development and testing.
*
* datasource => The name of a supported datasource; valid options are as follows:
* Database/Mysql - MySQL 4 & 5,
* Database/Sqlite - SQLite (PHP5 only),
* Database/Postgres - PostgreSQL 7 and higher,
* Database/Sqlserver - Microsoft SQL Server 2005 and higher
*
* You can add custom database datasources (or override existing datasources) by adding the
* appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php',
*
*
* persistent => true / false
* Determines whether or not the database should use a persistent connection
*
* host =>
* the host you connect to the database. To add a socket or port number, use 'port' => #
*
* prefix =>
* Uses the given prefix for all the tables in this database. This setting can be overridden
* on a per-table basis with the Model::$tablePrefix property.
*
* schema =>
* For Postgres/Sqlserver specifies which schema you would like to use the tables in. Postgres defaults to 'public'. For Sqlserver, it defaults to empty and use
* the connected user's default schema (typically 'dbo').
*
* encoding =>
* For MySQL, Postgres specifies the character encoding to use when connecting to the
* database. Uses database default not specified.
*
* unix_socket =>
* For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port`
*/
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'zm',
'password' => 'zm',
'database' => 'zm',
'prefix' => '',
//'encoding' => 'utf8',
);
public $test = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'user',
'password' => 'password',
'database' => 'test_database_name',
'prefix' => '',
//'encoding' => 'utf8',
);
}

View File

@ -0,0 +1,92 @@
<?php
/**
* This is email configuration file.
*
* Use it to configure email transports of Cake.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*
* Email configuration class.
* You can specify multiple configurations for production, development and testing.
*
* transport => The name of a supported transport; valid options are as follows:
* Mail - Send using PHP mail function
* Smtp - Send using SMTP
* Debug - Do not send the email, just return the result
*
* You can add custom transports (or override existing transports) by adding the
* appropriate file to app/Network/Email. Transports should be named 'YourTransport.php',
* where 'Your' is the name of the transport.
*
* from =>
* The origin email. See CakeEmail::from() about the valid values
*
*/
class EmailConfig {
public $default = array(
'transport' => 'Mail',
'from' => 'you@localhost',
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
public $smtp = array(
'transport' => 'Smtp',
'from' => array('site@localhost' => 'My Site'),
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => 'user',
'password' => 'secret',
'client' => null,
'log' => false,
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
public $fast = array(
'from' => 'you@localhost',
'sender' => null,
'to' => null,
'cc' => null,
'bcc' => null,
'replyTo' => null,
'readReceipt' => null,
'returnPath' => null,
'messageId' => true,
'subject' => null,
'message' => null,
'headers' => null,
'viewRender' => null,
'template' => false,
'layout' => false,
'viewVars' => null,
'attachments' => null,
'emailFormat' => null,
'transport' => 'Smtp',
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => 'user',
'password' => 'secret',
'client' => null,
'log' => true,
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
}

45
web/app/Config/routes.php Normal file
View File

@ -0,0 +1,45 @@
<?php
/**
* Routes configuration
*
* In this file, you set up routes to your controllers and their actions.
* Routes are very important mechanism that allows you to freely connect
* different urls to chosen controllers and their actions (functions).
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* Here, we are connecting '/' (base path) to controller called 'Pages',
* its action called 'display', and we pass a param to select the view file
* to use (in this case, /app/View/Pages/home.ctp)...
*/
Router::connect('/', array('controller' => 'Monitors', 'action' => 'index'));
/**
* ...and connect the rest of 'Pages' controller's urls.
*/
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
/**
* Load all plugin routes. See the CakePlugin documentation on
* how to customize the loading of plugin routes.
*/
CakePlugin::routes();
/**
* Load the CakePHP default routes. Only remove this if you do not want to use
* the built-in default routes.
*/
require CAKE . 'Config' . DS . 'routes.php';

View File

@ -0,0 +1,32 @@
<?php
/**
* AppShell file
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Shell', 'Console');
/**
* Application Shell
*
* Add your application-wide methods in the class below, your shells
* will inherit them.
*
* @package app.Console.Command
*/
class AppShell extends Shell {
}

42
web/app/Console/cake Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
################################################################################
#
# Bake is a shell script for running CakePHP bake script
# PHP 5
#
# CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
#
# Licensed under The MIT License
# For full copyright and license information, please see the LICENSE.txt
# Redistributions of files must retain the above copyright notice.
#
# @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
# @link http://cakephp.org CakePHP(tm) Project
# @package app.Console
# @since CakePHP(tm) v 1.2.0.5012
# @license MIT License (http://www.opensource.org/licenses/mit-license.php)
#
################################################################################
# Canonicalize by following every symlink of the given name recursively
canonicalize() {
NAME="$1"
if [ -f "$NAME" ]
then
DIR=$(dirname -- "$NAME")
NAME=$(cd -P "$DIR" && pwd -P)/$(basename -- "$NAME")
fi
while [ -h "$NAME" ]; do
DIR=$(dirname -- "$NAME")
SYM=$(readlink "$NAME")
NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
done
echo "$NAME"
}
CONSOLE=$(dirname -- "$(canonicalize "$0")")
APP=$(dirname "$CONSOLE")
exec php -q "$CONSOLE"/cake.php -working "$APP" "$@"
exit

32
web/app/Console/cake.bat Normal file
View File

@ -0,0 +1,32 @@
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: Bake is a shell script for running CakePHP bake script
:: PHP 5
::
:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
:: Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
::
:: Licensed under The MIT License
:: Redistributions of files must retain the above copyright notice.
::
:: @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
:: @link http://cakephp.org CakePHP(tm) Project
:: @package app.Console
:: @since CakePHP(tm) v 2.0
:: @license MIT License (http://www.opensource.org/licenses/mit-license.php)
::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: In order for this script to work as intended, the cake\console\ folder must be in your PATH
@echo.
@echo off
SET app=%0
SET lib=%~dp0
php -q "%lib%cake.php" -working "%CD% " %*
echo.
exit /B %ERRORLEVEL%

37
web/app/Console/cake.php Normal file
View File

@ -0,0 +1,37 @@
#!/usr/bin/php -q
<?php
/**
* Command-line code generation utility to automate programmer chores.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Console
* @since CakePHP(tm) v 2.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
$ds = DIRECTORY_SEPARATOR;
$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
if (function_exists('ini_set')) {
$root = dirname(dirname(dirname(__FILE__)));
// the following line differs from its sibling
// /lib/Cake/Console/Templates/skel/Console/cake.php
ini_set('include_path', $root . $ds . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
}
if (!include($dispatcher)) {
trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
}
unset($paths, $path, $dispatcher, $root, $ds);
return ShellDispatcher::run($argv);

View File

@ -0,0 +1,110 @@
<?php
/**
* Application level Controller
*
* This file is application-wide controller file. You can put all
* application-wide controller-related methods here.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Controller
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Controller', 'Controller');
/**
* Application Controller
*
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*
* @package app.Controller
* @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
*/
class AppController extends Controller {
public $helpers = array(
'Session',
'Js',
'Html' => array('className' => 'BoostCake.BoostCakeHtml'),
'Form' => array('className' => 'BoostCake.BoostCakeForm'),
'Paginator' => array('className' => 'BoostCake.BoostCakePaginator'),
);
public $components = array('Cookie', 'Session', 'RequestHandler');
public function beforeFilter() {
parent::beforeFilter();
$this->loadModel('Config');
$this->loadModel('AppModel');
$this->Cookie->name = 'ZoneMinder';
$configFile = "/usr/local/etc/zm.conf";
$lines = file($configFile);
foreach ($lines as $linenum => $line) {
if ( preg_match( '/^\s*([^=\s]+)\s*=\s*(.+?)\s*$/', $line, $matches )) {
Configure::write($matches[1], $matches[2]);
}
}
$options = $this->Config->find('list', array('fields' => array('Name', 'Value')));
foreach ($options as $key => $value) {
Configure::write($key, $value);
}
Configure::write('SCALE_BASE', 100);
if ($this->AppModel->daemonStatus()) {
$this->set('daemonStatusHtml', ('<span class="alert alert-success">Running</span>'));
} else {
$this->set('daemonStatusHtml', ('<span class="alert alert-danger">Stopped</span>'));
}
$this->set('daemonStatus', $this->AppModel->daemonStatus());
if (Configure::read('ZM_DYN_LAST_VERSION') > Configure::read('ZM_VERSION')) {
$zmVersion = '<span class="label label-info">' . Configure::read('ZM_VERSION') . '</span>';
} else {
$zmVersion = '<span class="label label-success">' . Configure::read('ZM_VERSION') . '</span>';
}
$this->set('systemLoad', $this->AppModel->getSystemLoad());
$this->set('diskSpace', $this->AppModel->getDiskSpace());
$this->set('zmVersion', $zmVersion);
}
public function beforeRender() {
parent::beforeRender();
if (!$this->Cookie->read('zmBandwidth')) {
$this->Cookie->write('zmBandwidth', 'low', false);
}
$this->set('zmBandwidth', $this->Cookie->read('zmBandwidth'));
}
function extractNamedParams($mandatory, $optional = array()) {
$params = $this->params['named'];
if(empty($params)) {
return false;
}
$mandatory = array_flip($mandatory);
$all_named_keys = array_merge($mandatory, $optional);
$valid = array_intersect_key($params, $all_named_keys);
$output = array_merge($optional, $valid);
$diff = array_diff_key($all_named_keys, $output);
if (empty($diff)) {
return $output;
} else {
return false;
}
}
}

View File

@ -0,0 +1,20 @@
<?php
class BandwidthController extends AppController {
public function index() {
if (!empty($this->request->data)) {
$bandwidth = $this->request->data['Bandwidth']['Bandwidth'];
$this->Cookie->write('zmBandwidth', $bandwidth, false);
$this->set('bandwidth', $bandwidth);
if ($this->Cookie->read('zmBandwidth') == $bandwidth) {
$this->Session->setFlash('Successfully updated bandwidth');
} else {
$this->Session->setFlash('Failed to update bandwidth');
}
} else {
$this->set('bandwidth', $this->Cookie->read('zmBandwidth'));
}
}
}
?>

View File

@ -0,0 +1,40 @@
<?php
class ConfigController extends AppController {
public function index() {
// Get a list of categories
$categories = $this->Config->find('all', array('fields' => array('Category'), 'group' => array('Category'), 'conditions' => array('Category !=' => 'hidden')));
$this->set('categories', $categories);
// Build an array of categories with each child option under that category
$options = array();
foreach ($categories as $category) {
$name = $category['Config']['Category'];
$configs = $this->Config->findAllByCategory($name,
array('Name', 'Id', 'Value', 'Prompt', 'Type', 'Category', 'Hint'), 'Type');
$options[$name] = $configs;
}
// Pass the completed array to the view
$this->set('options', $options);
if (!empty($this->request->data)) {
$data = array();
foreach ($this->request->data['Config'] as $key => $value) {
foreach ($value as $fieldName => $fieldValue) {
$arr = array('Config' => array('Name' => $fieldName, 'Value' => $fieldValue));
array_push($data, $arr);
}
}
if($this->Config->saveMany($data)) {
$this->Session->setFlash('Your config has been updated.');
} else {
$this->Session->setFlash('Your config has not been updated.');
}
}
}
}
?>

View File

@ -0,0 +1,91 @@
<?php
class EventsController extends AppController {
public $helpers = array('Paginator');
public $components = array('Paginator');
public function index() {
$this->loadModel('Monitor');
$this->loadModel('Frame');
$conditions = array();
$this->set('thumb_width', Configure::read('ZM_WEB_LIST_THUMB_WIDTH'));
$named = $this->extractNamedParams(
array('MonitorId', 'StartTime' )
);
if ($named) {
foreach ($named as $key => $value) {
switch ($key) {
case "StartTime":
$StartTime = array("$key BETWEEN FROM_UNIXTIME($value[0]) and FROM_UNIXTIME($value[1])");
array_push($conditions, $StartTime);
break;
case "MonitorId":
$$key = array($key => $value);
array_push($conditions, $$key);
break;
}
}
};
$this->paginate = array(
'fields' => array('Event.Name', 'Event.Length', 'Event.MonitorId', 'Event.Id', 'Monitor.Name', 'Event.MaxScore', 'Event.Width', 'Event.Height', 'Event.StartTime', 'Event.TotScore', 'Event.AvgScore', 'Event.Cause', 'Event.AlarmFrames', 'TIMESTAMPDIFF (SECOND, Event.StartTime, Event.EndTime) AS Duration' ),
'limit' => Configure::read('ZM_WEB_EVENTS_PER_PAGE'),
'order' => array( 'Event.Id' => 'asc'),
'conditions' => $conditions
);
$data = $this->paginate('Event');
$this->set('events', $data);
$this->set('monitors', $this->Monitor->find('all', array('fields' => array('Monitor.Name') )));
foreach ($data as $key => $value) {
$thumbData[$key] = $this->Frame->createListThumbnail($value['Event']);
$this->set('thumbData', $thumbData);
}
}
public function view($id = null) {
$this->layout = 'popup';
if (!$id) {
throw new NotFoundException(__('Invalid event'));
}
$event = $this->Event->findById($id);
if (!$event) {
throw new NotFoundException(__('Invalid event'));
}
$this->set('event', $event);
if (!strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
$videoFormat = 'webm';
} else {
$videoFormat = 'mp4';
}
$this->set('videoSrc', $this->Event->createVideo( $id, $videoFormat, 100, 100 ));
}
public function delete($id) {
if ($this->request->is('get')) {
throw new MethodNotAllowedException();
}
if ($this->Event->delete($id)) {
return $this->redirect(array('action' => 'index'));
}
}
public function deleteSelected() {
foreach($this->data['Events'] as $key => $value) {
$this->Event->delete($value);
}
$this->redirect($this->referer());
}
}
?>

View File

@ -0,0 +1,9 @@
<?php
class FiltersController extends AppController {
public function index() {
$this->set('filters', $this->Filter->find('all'));
}
}
?>

View File

@ -0,0 +1,30 @@
<?php
class LogsController extends AppController {
public function index() {
$conditions = array();
$named = $this->extractNamedParams(
array('Component')
);
if ($named) {
foreach ($named as $key => $value) {
switch ($key) {
case "Component":
$Component = array($key => $value);
array_push($conditions, $Component);
break;
}
}
};
$this->set('loglines', $this->Log->find('all', array(
'limit' => 100,
'order' => array('TimeKey' => 'desc'),
'conditions' => $conditions
)));
$this->set('components', $this->Log->find('all', array(
'fields' => array('DISTINCT Component')
)));
}
}
?>

View File

@ -0,0 +1,185 @@
<?php
class MonitorsController extends AppController {
public $helpers = array('LiveStream', 'Js'=>array('Jquery'));
public function index() {
$zmBandwidth = $this->Cookie->read('zmBandwidth');
$this->set('width', Configure::read('ZM_WEB_LIST_THUMB_WIDTH'));
$monitoroptions = array('fields' => array('Name', 'Id', 'Function', 'Enabled', 'Sequence', 'Function', 'Width'), 'order' => 'Sequence ASC', 'recursive' => -1);
$this->set('monitors', $this->Monitor->find('all', $monitoroptions));
$monitors = $this->Monitor->find('all', array('recursive' => -1, 'fields' => array('Id', 'StreamReplayBuffer')));
foreach ($monitors as $monitor => $mon) {
$streamSrc[$mon['Monitor']['Id']] = $this->Monitor->getStreamSrc($mon['Monitor']['Id'], $zmBandwidth, $monitor['Monitor']['StreamReplayBuffer']);
}
$this->set('streamSrc', $streamSrc);
}
public function view($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid monitor'));
}
$monitor = $this->Monitor->findById($id);
if (!$monitor) {
throw new NotFoundException(__('Invalid monitor'));
}
$this->set('monitor', $monitor);
$zmBandwidth = $this->Cookie->read('zmBandwidth');
$buffer = $monitor['Monitor']['StreamReplayBuffer'];
$this->set('streamSrc', $this->Monitor->getStreamSrc($id, $zmBandwidth, $buffer));
}
public function edit($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid monitor'));
}
$monitor = $this->Monitor->findById($id);
if (!$monitor) {
throw new NotFoundException(__('Invalid monitor'));
}
$this->set('monitor', $monitor['Monitor']);
$typeoptions = array(
'Local' => 'Local',
'Remote' => 'Remote',
'File' => 'File',
'Ffmpeg' => 'Ffmpeg'
);
$this->set('typeoptions', $typeoptions);
$functionoptions = array(
'Modect' => 'Modect',
'Monitor' => 'Monitor',
'Record' => 'Record',
'None' => 'None',
'Nodect' => 'Nodect',
'Mocord' => 'Mocord'
);
$this->set('functionoptions', $functionoptions);
$protocoloptions = array(
'rtsp' => 'RTSP',
'http' => 'HTTP'
);
$this->set('protocoloptions', $protocoloptions);
$methodoptions = array(
'simple' => 'Simple',
'regexp' => 'Regexp'
);
$this->set('methodoptions', $methodoptions);
$optionsColours = array(
1 => '8 bit grayscale',
3 => '24 bit color',
4 => '32 bit color'
);
$this->set('optionsColours', $optionsColours);
$channeloptions = array();
for ($i=1; $i<32; $i++) {
array_push($channeloptions, $i);
}
$this->set('channeloptions', $channeloptions);
$formatoptions = array(
255 => "PAL",
45056 => "NTSC",
1 => "PAL B",
2 => "PAL B1",
4 => "PAL G",
8 => "PAL H",
16 => "PAL I",
32 => "PAL D",
64 => "PAL D1",
128 => "PAL K",
256 => "PAL M",
512 => "PAL N",
1024 => "PAL Nc",
2048 => "PAL 60",
4096 => "NTSC M",
8192 => "NTSC M JP",
16384 => "NTSC 443",
32768 => "NTSC M KR",
65536 => "SECAM B",
131072 => "SECAM D",
262144 => "SECAM G",
524288 => "SECAM H",
1048576 => "SECAM K",
2097152 => "SECAM K1",
4194304 => "SECAM L",
8388608 => "SECAM LC",
16777216 => "ATSC 8 VSB",
33554432 => "ATSC 16 VSB"
);
$this->set('formatoptions', $formatoptions);
$optionsPalette = array(
0 => 'Auto',
1497715271 => 'Gray',
877807426 => 'BGR32',
876758866 => 'RGB32',
861030210 => 'BGR24',
859981650 => 'RGB24',
1448695129 => '*YUYV',
1195724874 => '*JPEG',
1196444237 => '*MJPEG',
875836498 => '*RGB444',
1329743698 => '*RGB555',
1346520914 => '*RGB565',
1345466932 => '*YUV422P',
1345401140 => '*YUV411P',
875836505 => '*YUV444',
961959257 => '*YUV410',
842093913 => '*YUV420'
);
$this->set('optionsPalette', $optionsPalette);
$optionsMethod = array(
'v4l2' => 'Video For Linux 2'
);
$this->set('optionsMethod', $optionsMethod);
$this->set('linkedMonitors', $this->Monitor->find('list', array('fields' => array('Id', 'Name'))));
if ($this->request->is('put') || $this->request->is('post')) {
$this->Monitor->id = $id;
if ($this->Monitor->save($this->request->data)) {
$this->Session->setFlash('Your monitor has been updated.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to update your monitor.');
}
}
if (!$this->request->data) {
$this->request->data = $monitor;
}
}
public function add() {
if ($this->request->is('post')) {
$this->Monitor->create();
if ($this->Monitor->save($this->request->data)) {
$this->Session->setFlash('Your monitor has been created.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to create your monitor.');
}
}
}
public function reorder() {
foreach ($this->data['Monitor'] as $key => $value) {
$this->Monitor->id = $value;
$this->Monitor->saveField('Sequence', $key+1);
}
exit();
}
}
?>

View File

@ -0,0 +1,75 @@
<?php
/**
* Static content controller.
*
* This file will render views from views/pages/
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Controller
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('AppController', 'Controller');
/**
* Static content controller
*
* Override this controller by placing a copy in controllers directory of an application
*
* @package app.Controller
* @link http://book.cakephp.org/2.0/en/controllers/pages-controller.html
*/
class PagesController extends AppController {
/**
* Controller name
*
* @var string
*/
public $name = 'Pages';
/**
* This controller does not use a model
*
* @var array
*/
public $uses = array();
/**
* Displays a view
*
* @param mixed What page to display
* @return void
*/
public function display() {
$path = func_get_args();
$count = count($path);
if (!$count) {
$this->redirect('/');
}
$page = $subpage = $title_for_layout = null;
if (!empty($path[0])) {
$page = $path[0];
}
if (!empty($path[1])) {
$subpage = $path[1];
}
if (!empty($path[$count - 1])) {
$title_for_layout = Inflector::humanize($path[$count - 1]);
}
$this->set(compact('page', 'subpage', 'title_for_layout'));
$this->render(implode('/', $path));
}
}

View File

@ -0,0 +1,18 @@
<?php
class VersionController extends AppController {
public function index() {
$this->set('zmDynLastVersion', Configure::read('ZM_DYN_LAST_VERSION'));
$this->set('zmDynDBVersion', Configure::read('ZM_DYN_DB_VERSION'));
}
public function isUpdateAvailable() {
if (Configure::read('ZM_DYN_LAST_VERSION') > Configure::read('ZM_DYN_DB_VERSION')) {
echo 'true';
} else {
echo 'false';
}
die();
}
}
?>

View File

@ -0,0 +1,10 @@
<?php
class ZonesController extends AppController {
public function index() {
$this->set('zones', $this->Zone->find('all'));
}
}
?>

0
web/app/Lib/empty Normal file
View File

View File

175
web/app/Model/AppModel.php Normal file
View File

@ -0,0 +1,175 @@
<?php
/**
* Application model for Cake.
*
* This file is application-wide model file. You can put all
* application-wide model-related methods here.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Model
* @since CakePHP(tm) v 0.2.9
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
App::uses('Model', 'Model');
/**
* Application model for Cake.
*
* Add your application-wide methods in the class below, your models
* will inherit them.
*
* @package app.Model
*/
class AppModel extends Model {
public function daemonStatus() {
$zm_path_bin = Configure::read('ZM_PATH_BIN');
$string = $zm_path_bin."/zmdc.pl status";
$daemon_status = shell_exec ( $string );
return !strstr($daemon_status, "Unable to connect to server");
}
function daemonControl( $command ) {
$string = Configure::read('ZM_PATH_BIN')."/zmdc.pl $command";
$string .= " 2>/dev/null >&- <&- >/dev/null";
$return = exec( $string );
return $return;
}
function getSystemLoad()
{
$uptime = shell_exec( 'uptime' );
$load = '';
if ( preg_match( '/load average: ([\d.]+)/', $uptime, $matches ) )
$load = $matches[1];
return( $load );
}
function getDiskSpace()
{
$df = shell_exec( 'df ' . Configure::read('ZM_PATH_WEB') . '/' . Configure::read('ZM_DIR_EVENTS') );
$space = -1;
if ( preg_match( '/\s(\d+)%/ms', $df, $matches ) )
$space = $matches[1];
return( $space );
}
public function reScale( $dimension, $dummy) {
$scale_base = Configure::read('SCALE_BASE');
for ( $i = 1; $i < func_num_args(); $i++ ) {
$scale = func_get_arg( $i );
if ( !empty($scale) && $scale != $scale_base ) {
$dimension = (int)(($dimension*$scale)/$scale_base);
}
}
return( $dimension );
}
public function getEventPath( $event ){
if (Configure::read('ZM_USE_DEEP_STORAGE')) {
$eventPath = $event['MonitorId'].'/'.strftime("%y/%m/%d/%H/%M/%S", strtotime($event['StartTime']));
} else {
$eventPath = $event['MonitorId'].'/'.$event['Id'];
}
return($eventPath);
}
public function getImageSrc( $event, $frame, $captureOnly=false, $overwrite=false) {
$scale = Configure::read('SCALE_BASE');
$eventPath = $this->getEventPath($event);
$zm_event_image_digits = Configure::read('ZM_EVENT_IMAGE_DIGITS');
$zm_dir_images = Configure::read('ZM_DIR_IMAGES');
$zm_dir_events = Configure::read('ZM_DIR_EVENTS');
$zm_web_scale_thumbs = Configure::read('ZM_WEB_SCALE_THUMBS');
if (!is_array($frame)) {
$frame = array('FrameId' => $frame, 'Type' => '');
}
// This is the path to the capture image
$captImage = sprintf("%0".$zm_event_image_digits."d-capture.jpg", $frame['FrameId']);
$captPath = $eventPath.'/'.$captImage;
$thumbCaptPath = $zm_dir_images.'/'.$event['Id'].'-'.$captImage;
// This is the path to the analysis image
$analImage = sprintf("%0".$zm_event_image_digits."d-analyse.jpg", $frame['FrameId']);
$analPath = $eventPath.'/'.$analImage;
$analFile = $zm_dir_events.'/'.$analPath;
$thumbAnalPath = $zm_dir_images.'/'.$event['Id'].'-'.$captImage;
$alarmFrame = $frame['Type'] == 'Alarm';
$hasAnalImage = $alarmFrame && file_exists( $analFile ) && filesize( $analFile );
$isAnalImage = $hasAnalImage && !$captureOnly;
if (!$zm_web_scale_thumbs || $scale >= $scale_base || !function_exists('imagecreatefromjpeg')) {
$imagePath = $thumbPath = $isAnalImage ? $analPath : $captPath;
$imageFile = $zm_dir_events.'/'.$imagePath;
$thumbFile = $zm_dir_events.'/'.$thumbPath;
} else {
if (version_compare(phpversion(), "4.3.10", ">=") ) {
$fraction = sprintf( "%.3F", $scale/$scale_base );
} else {
$fraction = sprintf( "%.3f", $scale/$scale_base );
}
$scale = (int)round( $scale );
$thumbCaptPath = preg_replace( "/\.jpg$/", "-$scale.jpg", $thumbCaptPath );
$thumbAnalPath = preg_replace( "/\.jpg$/", "-$scale.jpg", $thumbAnalPath );
if ( $isAnalImage ) {
$imagePath = $analPath;
$thumbPath = $thumbAnalPath;
} else {
$imagePath = $captPath;
$thumbPath = $thumbCaptPath;
}
$imageFile = $zm_dir_events."/".$imagePath;
$thumbFile = $thumbPath;
if ( $overwrite || !file_exists( $thumbFile ) || !filesize( $thumbFile ) ) {
// Get new dimentions
list( $imageWidth, $imageHeight ) = getimagesize( $imageFile );
$thumbWidth = $imageWidth * $fraction;
$thumbHeight = $imageHeight * $fraction;
// Resample
$thumbImage = imagecreatetruecolor( $thumbWidth, $thumbHeight );
$image = imagecreatefromjpeg( $imageFile );
imagecopyresampled( $thumbImage, $image, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imageWidth, $imageHeight );
if ( !imagejpeg( $thumbImage, $thumbFile ) ) {
Error( "Can't create thumbnail '$thumbPath'" );
}
}
}
$imageData = array(
'eventPath' => $eventPath,
'imagePath' => $imagePath,
'thumbPath' => $thumbPath,
'imageFile' => $imageFile,
'thumbFile' => $thumbFile,
'imageClass' => $alarmFrame?"alarm":"normal",
'isAnalImage' => $isAnalImage,
'hasAnalImage' => $hasAnalImage
);
return($imageData);
}
}

View File

@ -0,0 +1,5 @@
<?php
class Bandwidth extends AppModel {
public $useTable = false;
}
?>

View File

20
web/app/Model/Config.php Normal file
View File

@ -0,0 +1,20 @@
<?php
class Config extends AppModel {
public $useTable = 'Config';
public $primaryKey = 'Name';
public function getWebOption($name, $zmBandwidth) {
$name_begin = substr($name, 0, 7);
$name_end = substr($name, 6);
$bandwidth_short = strtoupper($zmBandwidth[0]);
$option = $name_begin . $bandwidth_short . $name_end;
$ZM_OPTIONS = $this->find('first', array(
'fields' => array('Value'),
'conditions' => array('Category' => $zmBandwidth.'band', 'Name' => $option)
));
return($ZM_OPTIONS['Config']['Value']);
}
}
?>

View File

37
web/app/Model/Event.php Normal file
View File

@ -0,0 +1,37 @@
<?php
class Event extends AppModel {
public $useTable = 'Events';
public $primaryKey = 'Id';
public $belongsTo = array(
'Monitor' => array(
'className' => 'Monitor',
'foreignKey' => 'MonitorId'
)
);
public $hasMany = array(
'Frame' => array(
'className' => 'Frame',
'foreignKey' => 'FrameId',
'dependent' => true
)
);
function createVideo( $event, $format, $rate, $scale, $overwrite=false ) {
$command = Configure::read('ZM_PATH_BIN')."/zmvideo.pl -e ".$event." -f ".$format." -r ".sprintf( "%.2F", ($rate/100) );
if ( preg_match( '/\d+x\d+/', $scale ) )
$command .= " -S ".$scale;
else
if ( version_compare( phpversion(), "4.3.10", ">=") )
$command .= " -s ".sprintf( "%.2F", ($scale/100) );
else
$command .= " -s ".sprintf( "%.2f", ($scale/100) );
if ( $overwrite )
$command .= " -o";
$result = exec( escapeshellcmd( $command ), $output, $status );
$videoSrc = str_replace(Configure::read('ZM_PATH_WEB'), '', $result);
return( $status?"":rtrim($videoSrc) );
}
}
?>

6
web/app/Model/Filter.php Normal file
View File

@ -0,0 +1,6 @@
<?php
class Filter extends AppModel {
public $useTable = 'Filters';
public $primaryKey = 'Name';
}
?>

54
web/app/Model/Frame.php Normal file
View File

@ -0,0 +1,54 @@
<?php
class Frame extends AppModel {
public $useTable = 'Frames';
public $primaryKey = 'FrameId';
public $belongsTo = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'EventId'
)
);
public function createListThumbnail( $event, $overwrite=false) {
$frame = $this->find('first', array(
'conditions' => array(
'EventId' => $event['Id'],
'Score' => $event['MaxScore']
),
'order' => 'FrameId'
));
if (!($frame)) {
return ("Whoa now! Could not locate a frame for this event.");
}
$frameId = $frame['Frame']['FrameId'];
$thumbWidth = Configure::read('ZM_WEB_LIST_THUMB_WIDTH');
$thumbHeight = Configure::read('ZM_WEB_LIST_THUMB_HEIGHT');
$scale = Configure::read('SCALE_BASE');
// Should we scale the thumbnail based on the width or height of the image?
// By default, ZM_WEB_LIST_THUMB_WIDTH is set, ZM_WEB_LIST_THUMB_HEIGHT is not.
if ($thumbWidth) {
$scale = ($scale*$thumbWidth)/$event['Width'];
$thumbHeight = $this->reScale($event['Height'], $scale);
} elseif ($thumbHeight) {
$scale = ($scale*$thumbHeight)/$event['Height'];
$thumbWidth = $this->reScale($event['Width'], $scale);
} else {
return ("No thumbnail width or height specified, please check in Options->Web");
}
// Get the path to the image on the filesystem
$imageData = $this->getImageSrc( $event, $frame['Frame'], $scale, false, $overwrite );
$thumbData = $frame;
$thumbData['Path'] = $imageData['thumbPath'];
$thumbData['Width'] = (int)$thumbWidth;
$thumbData['Height'] = (int)$thumbHeight;
return ($thumbData);
}
}
?>

6
web/app/Model/Log.php Normal file
View File

@ -0,0 +1,6 @@
<?php
class Log extends AppModel {
public $useTable = 'Logs';
public $primaryKey = 'TimeKey';
}
?>

34
web/app/Model/Monitor.php Normal file
View File

@ -0,0 +1,34 @@
<?php
class Monitor extends AppModel {
public $useTable = 'Monitors';
public $primaryKey = 'Id';
public $hasMany = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'MonitorId',
'fields' => 'Event.Id'
),
'Zone' => array(
'className' => 'Zone',
'foreignKey' => 'MonitorId',
'fields' => 'Zone.Id'
)
);
public function getStreamSrc($id = null, $zmBandwidth, $buffer) {
$ZM_MPEG_LIVE_FORMAT = Configure::read('ZM_MPEG_LIVE_FORMAT');
$ZM_WEB_STREAM_METHOD = ClassRegistry::init('Config')->getWebOption('ZM_WEB_STREAM_METHOD', $zmBandwidth);
$ZM_WEB_VIDEO_BITRATE = ClassRegistry::init('Config')->getWebOption('ZM_WEB_VIDEO_BITRATE', $zmBandwidth);
$ZM_WEB_VIDEO_MAXFPS = ClassRegistry::init('Config')->getWebOption('ZM_WEB_VIDEO_MAXFPS', $zmBandwidth);
$ZM_MPEG_LIVE_FORMAT = $ZM_MPEG_LIVE_FORMAT;
if ($ZM_WEB_STREAM_METHOD == 'mpeg' && $ZM_MPEG_LIVE_FORMAT) {
return "/cgi-bin/nph-zms?mode=mpeg&scale=100&maxfps=$ZM_WEB_VIDEO_MAXFPS&bitrate=$ZM_WEB_VIDEO_BITRATE&format=$ZM_MPEG_LIVE_FORMAT&monitor=$id";
} else {
return "/cgi-bin/nph-zms?mode=jpeg&scale=100&maxfps=$ZM_WEB_VIDEO_MAXFPS&buffer=$buffer&monitor=$id";
}
}
}
?>

View File

@ -0,0 +1,5 @@
<?php
class Version extends AppModel {
public $useTable = false;
}
?>

11
web/app/Model/Zone.php Normal file
View File

@ -0,0 +1,11 @@
<?php
class Zone extends AppModel {
public $useTable = 'Zones';
public $primaryKey = 'Id';
public $belongsTo = array(
'Monitor' => array(
'className' => 'Monitor',
'foreignKey' => 'MonitorId')
);
}
?>

View File

@ -0,0 +1,32 @@
language: php
php:
- 5.3
- 5.4
env:
- CAKE_VERSION=master
- CAKE_VERSION=2.5
before_script:
- sh -c "mysql -e 'CREATE DATABASE cakephp_test;'"
- git clone git://github.com/cakephp/cakephp ../cakephp && cd ../cakephp && git checkout $CAKE_VERSION
- cp -R ../cakephp-plugin-boost_cake plugins/BoostCake
- chmod -R 777 ../cakephp/app/tmp
- echo "<?php
class DATABASE_CONFIG {
public \$test = array(
'datasource' => 'Database/Mysql',
'database' => 'cakephp_test',
'host' => '0.0.0.0',
'login' => 'travis'
'host' => '',
'persistent' => false,
);
}" > ../cakephp/app/Config/database.php
script:
- ./lib/Cake/Console/cake test BoostCake AllTests --stderr
notifications:
email: false

View File

@ -0,0 +1,59 @@
<?php
App::uses('AppController', 'Controller');
class BoostCakeController extends AppController {
public $uses = array('BoostCake.BoostCake');
public $components = array('Session');
public $helpers = array(
'Html' => array('className' => 'BoostCake.BoostCakeHtml'),
'Form' => array('className' => 'BoostCake.BoostCakeForm'),
'Paginator' => array('className' => 'BoostCake.BoostCakePaginator'),
);
public function beforeFilter() {
if (Configure::read('debug') < 1) {
throw new MethodNotAllowedException(__('Debug setting does not allow access to this url.'));
}
parent::beforeFilter();
}
public function index() {
}
public function bootstrap2() {
$this->Session->setFlash(__('Alert notice message testing...'), 'alert', array(
'plugin' => 'BoostCake',
), 'notice');
$this->Session->setFlash(__('Alert success message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-success'
), 'success');
$this->Session->setFlash(__('Alert error message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-error'
), 'error');
}
public function bootstrap3() {
$this->Session->setFlash(__('Alert success message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-success'
), 'success');
$this->Session->setFlash(__('Alert info message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-info'
), 'info');
$this->Session->setFlash(__('Alert warning message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-warning'
), 'warning');
$this->Session->setFlash(__('Alert danger message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-danger'
), 'danger');
}
}

View File

@ -0,0 +1,22 @@
<?php
App::uses('AppModel', 'Model');
class BoostCake extends AppModel {
public $useTable = false;
protected $_schema = array(
'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '10'),
'text' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'password' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'price' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '10'),
'textarea' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'checkbox' => array('type' => 'boolean', 'null' => false, 'default' => false),
'remember' => array('type' => 'boolean', 'null' => false, 'default' => false),
'select' => array('type' => 'integer', 'length' => '10', 'null' => true),
'radio' => array('type' => 'integer', 'length' => '10', 'null' => true),
'datetime' => array('type' => 'datetime')
);
}

View File

@ -0,0 +1,55 @@
# BoostCake
[![Build Status](https://travis-ci.org/slywalker/cakephp-plugin-boost_cake.png)](https://travis-ci.org/slywalker/cakephp-plugin-boost_cake)
[![Total Downloads](https://poser.pugx.org/slywalker/boost_cake/d/total.png)](https://packagist.org/packages/slywalker/boost_cake)
[![Latest Stable Version](https://poser.pugx.org/slywalker/boost_cake/v/stable.png)](https://packagist.org/packages/slywalker/boost_cake)
BoostCake is a plugin for CakePHP using Bootstrap
* [Bootstrap(2.3.2)](http://getbootstrap.com/2.3.2/)
* [Bootstrap(3.0.0)](http://getbootstrap.com/)
## Requirements
* CakePHP >= 2.3
* Bootstrap >= 2.3 (3.0 support)
## Installation
Ensure require is present in composer.json. This will install the plugin into Plugin/BoostCake:
{
"require": {
"slywalker/boost_cake": "*"
}
}
### Enable plugin
You need to enable the plugin your app/Config/bootstrap.php file:
`CakePlugin::load('BoostCake');`
If you are already using `CakePlugin::loadAll();`, then this is not necessary.
## Documentation
[BoostCake - Bootstrap Plugin for CakePHP](http://slywalker.github.io/cakephp-plugin-boost_cake/)
## Development Policy
More Simple! Simple! Simple!
* Develop only those that method's $options in FormHelper unable to solve.
* Don't develop ajax/js helper
If you want to simplify the options, you can develop WrapBoostCake plugin.
### What this plugin solves
* Replaces the `label` of checkboxes and radios
* Adds a wrapping `div` to inputs
* Adds content before and after `input`
* Adds error class in outer `div`
* Changes pagination tags
* Changes SessionHelper::flash()`s template

View File

@ -0,0 +1,11 @@
<?php
class AllTest extends CakeTestSuite {
public static function suite() {
$suite = new CakeTestSuite('All tests');
$path = dirname(__FILE__);
$suite->addTestDirectory($path . DS . 'View' . DS . 'Helper');
return $suite;
}
}

View File

@ -0,0 +1,317 @@
<?php
App::uses('BoostCakeFormHelper', 'BoostCake.View/Helper');
App::uses('View', 'View');
class Contact extends CakeTestModel {
/**
* useTable property
*
* @var bool false
*/
public $useTable = false;
/**
* Default schema
*
* @var array
*/
protected $_schema = array(
'id' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => '8'),
'name' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'email' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'phone' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'password' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null),
'age' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => null)
);
}
class BoostCakeFormHelperTest extends CakeTestCase {
public function setUp() {
parent::setUp();
$this->View = new View();
$this->Form = new BoostCakeFormHelper($this->View);
ClassRegistry::addObject('Contact', new Contact());
}
public function tearDown() {
unset($this->View);
unset($this->Form);
}
public function testInput() {
$result = $this->Form->input('name');
$this->assertTags($result, array(
array('div' => array()),
'label' => array('for' => 'name'),
'Name',
'/label',
array('div' => array('class' => 'input text')),
array('input' => array('name' => 'data[name]', 'type' => 'text', 'id' => 'name')),
'/div',
'/div'
));
$result = $this->Form->input('name', array(
'div' => 'row',
'wrapInput' => 'col col-lg-10',
'label' => array(
'class' => 'col col-lg-2 control-label'
)
));
$this->assertTags($result, array(
array('div' => array('class' => 'row')),
'label' => array('for' => 'name', 'class' => 'col col-lg-2 control-label'),
'Name',
'/label',
array('div' => array('class' => 'col col-lg-10')),
array('input' => array('name' => 'data[name]', 'type' => 'text', 'id' => 'name')),
'/div',
'/div'
));
$result = $this->Form->input('name', array('div' => false));
$this->assertTags($result, array(
'label' => array('for' => 'name'),
'Name',
'/label',
array('div' => array('class' => 'input text')),
array('input' => array('name' => 'data[name]', 'type' => 'text', 'id' => 'name')),
'/div'
));
$result = $this->Form->input('name', array('wrapInput' => false));
$this->assertTags($result, array(
array('div' => array()),
'label' => array('for' => 'name'),
'Name',
'/label',
array('input' => array('name' => 'data[name]', 'type' => 'text', 'id' => 'name')),
'/div'
));
$result = $this->Form->input('name', array(
'div' => false,
'wrapInput' => false
));
$this->assertTags($result, array(
'label' => array('for' => 'name'),
'Name',
'/label',
array('input' => array('name' => 'data[name]', 'type' => 'text', 'id' => 'name'))
));
}
public function testBeforeInputAfterInput() {
$result = $this->Form->input('name', array(
'beforeInput' => 'Before Input',
'afterInput' => 'After Input',
));
$this->assertTags($result, array(
array('div' => array()),
'label' => array('for' => 'name'),
'Name',
'/label',
array('div' => array('class' => 'input text')),
'Before Input',
array('input' => array('name' => 'data[name]', 'type' => 'text', 'id' => 'name')),
'After Input',
'/div',
'/div'
));
}
public function testCheckbox() {
$result = $this->Form->input('name', array('type' => 'checkbox'));
$this->assertTags($result, array(
array('div' => array()),
array('div' => array('class' => 'input checkbox')),
array('div' => array('class' => 'checkbox')),
array('input' => array('type' => 'hidden', 'name' => 'data[name]', 'id' => 'name_', 'value' => '0')),
'label' => array('for' => 'name'),
array('input' => array('name' => 'data[name]', 'type' => 'checkbox', 'value' => '1', 'id' => 'name')),
' Name',
'/label',
'/div',
'/div',
'/div'
));
$result = $this->Form->input('name', array(
'type' => 'checkbox',
'before' => '<label>Name</label>',
'label' => false
));
$this->assertTags($result, array(
array('div' => array()),
array('label' => array()),
'Name',
'/label',
array('div' => array('class' => 'input checkbox')),
array('div' => array('class' => 'checkbox')),
array('input' => array('type' => 'hidden', 'name' => 'data[name]', 'id' => 'name_', 'value' => '0')),
array('input' => array('name' => 'data[name]', 'type' => 'checkbox', 'value' => '1', 'id' => 'name')),
'/div',
'/div',
'/div'
));
$result = $this->Form->input('name', array(
'type' => 'checkbox',
'checkboxDiv' => false
));
$this->assertTags($result, array(
array('div' => array()),
array('div' => array('class' => 'input checkbox')),
array('input' => array('type' => 'hidden', 'name' => 'data[name]', 'id' => 'name_', 'value' => '0')),
'label' => array('for' => 'name'),
array('input' => array('name' => 'data[name]', 'type' => 'checkbox', 'value' => '1', 'id' => 'name')),
' Name',
'/label',
'/div',
'/div'
));
}
public function testSelectMultipleCheckbox() {
$result = $this->Form->select('name',
array(
1 => 'one',
2 => 'two',
3 => 'three'
),
array(
'multiple' => 'checkbox',
'class' => 'checkbox-inline'
)
);
$this->assertTags($result, array(
array('input' => array('type' => 'hidden', 'name' => 'data[name]', 'value' => '', 'id' => 'name')),
array('label' => array('for' => 'Name1', 'class' => 'checkbox-inline')),
array('input' => array('type' => 'checkbox', 'name' => 'data[name][]', 'value' => '1', 'id' => 'Name1')),
' one',
'/label',
array('label' => array('for' => 'Name2', 'class' => 'checkbox-inline')),
array('input' => array('type' => 'checkbox', 'name' => 'data[name][]', 'value' => '2', 'id' => 'Name2')),
' two',
'/label',
array('label' => array('for' => 'Name3', 'class' => 'checkbox-inline')),
array('input' => array('type' => 'checkbox', 'name' => 'data[name][]', 'value' => '3', 'id' => 'Name3')),
' three',
'/label'
));
$result = $this->Form->select('name',
array(
1 => 'bill',
'Smith' => array(
2 => 'fred',
3 => 'fred jr.'
)
),
array(
'multiple' => 'checkbox',
'class' => 'checkbox-inline'
)
);
$this->assertTags($result, array(
array('input' => array('type' => 'hidden', 'name' => 'data[name]', 'value' => '', 'id' => 'name')),
array('label' => array('for' => 'Name1', 'class' => 'checkbox-inline')),
array('input' => array('type' => 'checkbox', 'name' => 'data[name][]', 'value' => '1', 'id' => 'Name1')),
' bill',
'/label',
'fieldset' => array(),
'legend' => array(),
'Smith',
'/legend',
array('label' => array('for' => 'Name2', 'class' => 'checkbox-inline')),
array('input' => array('type' => 'checkbox', 'name' => 'data[name][]', 'value' => '2', 'id' => 'Name2')),
' fred',
'/label',
array('label' => array('for' => 'Name3', 'class' => 'checkbox-inline')),
array('input' => array('type' => 'checkbox', 'name' => 'data[name][]', 'value' => '3', 'id' => 'Name3')),
' fred jr.',
'/label',
'/fieldset'
));
}
public function testErrorMessage() {
$Contact = ClassRegistry::getObject('Contact');
$Contact->validationErrors['password'] = array('Please provide a password');
$result = $this->Form->input('Contact.password', array(
'div' => 'row',
'label' => array(
'class' => 'col col-lg-2 control-label'
),
'class' => 'input-with-feedback'
));
$this->assertTags($result, array(
array('div' => array('class' => 'row has-error error')),
'label' => array('for' => 'ContactPassword', 'class' => 'col col-lg-2 control-label'),
'Password',
'/label',
array('div' => array('class' => 'input password')),
'input' => array(
'type' => 'password', 'name' => 'data[Contact][password]',
'id' => 'ContactPassword', 'class' => 'input-with-feedback form-error'
),
array('span' => array('class' => 'help-block text-danger')),
'Please provide a password',
'/span',
'/div',
'/div'
));
$result = $this->Form->input('Contact.password', array(
'div' => 'row',
'label' => array(
'class' => 'col col-lg-2 control-label'
),
'class' => 'input-with-feedback',
'errorMessage' => false
));
$this->assertTags($result, array(
array('div' => array('class' => 'row has-error error')),
'label' => array('for' => 'ContactPassword', 'class' => 'col col-lg-2 control-label'),
'Password',
'/label',
array('div' => array('class' => 'input password')),
'input' => array(
'type' => 'password', 'name' => 'data[Contact][password]',
'id' => 'ContactPassword', 'class' => 'input-with-feedback form-error'
),
'/div',
'/div'
));
}
public function testPostLink() {
$result = $this->Form->postLink('Delete', '/posts/delete/1', array(
'block' => 'form'
));
$this->assertTags($result, array(
'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
'Delete',
'/a'
));
$result = $this->View->fetch('form');
$this->assertTags($result, array(
'form' => array(
'method' => 'post', 'action' => '/posts/delete/1',
'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
),
'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
'/form'
));
}
}

View File

@ -0,0 +1,51 @@
<?php
App::uses('BoostCakeHtmlHelper', 'BoostCake.View/Helper');
App::uses('View', 'View');
class BoostCakeHtmlHelperTest extends CakeTestCase {
public function setUp() {
parent::setUp();
$View = new View();
$this->Html = new BoostCakeHtmlHelper($View);
}
public function tearDown() {
unset($this->Html);
}
public function testUseTag() {
$result = $this->Html->useTag(
'radio', 'one', 'two', array('three' => 'four'), '<label for="one">label</label>'
);
$this->assertTags($result, array(
'label' => array('class' => 'radio', 'for' => 'one'),
'input' => array('type' => 'radio', 'name' => 'one', 'id' => 'two', 'three' => 'four'),
' label',
'/label'
));
$result = $this->Html->useTag(
'radio', 'one', 'two', array('class' => 'radio-inline', 'three' => 'four'), '<label for="one">label</label>'
);
$this->assertTags($result, array(
'label' => array('class' => 'radio-inline', 'for' => 'one'),
'input' => array('type' => 'radio', 'name' => 'one', 'id' => 'two', 'three' => 'four'),
' label',
'/label'
));
}
public function testImage() {
$result = $this->Html->image('', array('data-src' => 'holder.js/24x24'));
$this->assertTags($result, array(
'img' => array('src' => '/', 'data-src' => 'holder.js/24x24', 'alt' => '')
));
$result = $this->Html->image('some.jpg', array('data-src' => 'holder.js/24x24'));
$this->assertTags($result, array(
'img' => array('src' => '/img/some.jpg', 'alt' => '')
));
}
}

View File

@ -0,0 +1,452 @@
<?php
App::uses('View', 'View');
App::uses('Helper', 'View');
App::uses('BoostCakePaginatorHelper', 'BoostCake.View/Helper');
/**
* BootstrapPaginatorHelper Test Case
*
*/
class BoostCakePaginatorHelperTest extends CakeTestCase {
/**
* setUp method
*
* @return void
*/
public function setUp() {
parent::setUp();
$View = new View();
$this->Paginator = new BoostCakePaginatorHelper($View);
}
/**
* tearDown method
*
* @return void
*/
public function tearDown() {
unset($this->Paginator);
parent::tearDown();
}
/**
* testPaginationEmpty
*
* @return void
*/
public function testPaginationEmpty() {
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 1,
'current' => 0,
'count' => 0,
'prevPage' => false,
'nextPage' => false,
'pageCount' => 1,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$numbers = $this->Paginator->pagination(array('model' => 'Post'));
$this->assertSame('', $numbers);
}
/**
* testPaginationTwoModel
*
* @return void
*/
public function testPaginationTwoModel() {
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 1,
'current' => 0,
'count' => 0,
'prevPage' => false,
'nextPage' => false,
'pageCount' => 1,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$this->Paginator->request->params['paging']['Article'] = array(
'page' => 1,
'current' => 0,
'count' => 40,
'prevPage' => false,
'nextPage' => true,
'pageCount' => 2,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$result = $this->Paginator->pagination(array(
'model' => 'Article',
'div' => 'pagination'
));
$version = (float)Configure::version();
$pageOne = '/index/page:1';
if ($version >= 2.4) {
$pageOne = '/';
}
$this->assertTags($result, array(
'div' => array('class' => 'pagination'),
'ul' => array(),
array('li' => array('class' => 'disabled')),
array('a' => array('href' => $pageOne)),
'&lt;',
'/a',
'/li',
array('li' => array('class' => 'current disabled')),
array('a' => array('href' => '#')),
'1',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:2')),
'2',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:2', 'rel' => 'next')),
'&gt;',
'/a',
'/li',
'/ul',
'/div'
));
}
/**
* testPaginationTwo
*
* @return void
*/
public function testPaginationTwo() {
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 1,
'current' => 0,
'count' => 40,
'prevPage' => false,
'nextPage' => true,
'pageCount' => 2,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$result = $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination'
));
$version = (float)Configure::version();
$pageOne = '/index/page:1';
if ($version >= 2.4) {
$pageOne = '/';
}
$this->assertTags($result, array(
'div' => array('class' => 'pagination'),
'ul' => array(),
array('li' => array('class' => 'disabled')),
array('a' => array('href' => $pageOne)),
'&lt;',
'/a',
'/li',
array('li' => array('class' => 'current disabled')),
array('a' => array('href' => '#')),
'1',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:2')),
'2',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:2', 'rel' => 'next')),
'&gt;',
'/a',
'/li',
'/ul',
'/div'
));
$result = $this->Paginator->pagination(array(
'model' => 'Post',
'ul' => 'pagination'
));
$version = (float)Configure::version();
$pageOne = '/index/page:1';
if ($version >= 2.4) {
$pageOne = '/';
}
$this->assertTags($result, array(
'ul' => array('class' => 'pagination'),
array('li' => array('class' => 'disabled')),
array('a' => array('href' => $pageOne)),
'&lt;',
'/a',
'/li',
array('li' => array('class' => 'current disabled')),
array('a' => array('href' => '#')),
'1',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:2')),
'2',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:2', 'rel' => 'next')),
'&gt;',
'/a',
'/li',
'/ul'
));
}
/**
* testNumbersEmpty
*
* @return void
*/
public function testNumbersEmpty() {
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 1,
'current' => 0,
'count' => 0,
'prevPage' => false,
'nextPage' => false,
'pageCount' => 1,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$numbers = $this->Paginator->numbers(array('model' => 'Post'));
$this->assertSame('', $numbers);
}
/**
* testNumbersSimple
*
* @return void
*/
public function testNumbersSimple() {
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 1,
'current' => 20,
'count' => 100,
'prevPage' => false,
'nextPage' => true,
'pageCount' => 5,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$result = $this->Paginator->numbers(array('model' => 'Post'));
$this->assertTags($result, array(
array('li' => array('class' => 'current disabled')),
array('a' => array('href' => '#')),
'1',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:2')),
'2',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:3')),
'3',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:4')),
'4',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:5')),
'5',
'/a',
'/li'
));
}
/**
* testNumbersElipsis
*
* @return void
*/
public function testNumbersElipsis() {
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 10,
'current' => 20,
'count' => 1000,
'prevPage' => true,
'nextPage' => true,
'pageCount' => 200,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$result = $this->Paginator->numbers(array(
'model' => 'Post',
'modulus' => 8,
'first' => 1,
'last' => 1,
));
$version = (float)Configure::version();
$pageOne = '/index/page:1';
if ($version >= 2.4) {
$pageOne = '/';
}
$this->assertTags($result, array(
array('li' => array()),
array('a' => array('href' => $pageOne)),
'1',
'/a',
'/li',
array('li' => array('class' => 'disabled')),
array('a' => array('href' => '#')),
'…',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:6')),
'6',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:7')),
'7',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:8')),
'8',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:9')),
'9',
'/a',
'/li',
array('li' => array('class' => 'current disabled')),
array('a' => array('href' => '#')),
'10',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:11')),
'11',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:12')),
'12',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:13')),
'13',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:14')),
'14',
'/a',
'/li',
array('li' => array('class' => 'disabled')),
array('a' => array('href' => '#')),
'…',
'/a',
'/li',
array('li' => array()),
array('a' => array('href' => '/index/page:200')),
'200',
'/a',
'/li',
));
}
/**
* testPager
*
* @return void
*/
public function testPager() {
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 10,
'current' => 20,
'count' => 1000,
'prevPage' => true,
'nextPage' => true,
'pageCount' => 200,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
$result = $this->Paginator->pager();
$this->assertTags($result, array(
'ul' => array('class' => 'pager'),
array('li' => array('class' => 'previous')),
array('a' => array('href' => '/index/page:9', 'rel' => 'prev')),
'Previous',
'/a',
'/li',
array('li' => array('class' => 'next')),
array('a' => array('href' => '/index/page:11', 'rel' => 'next')),
'Next',
'/a',
'/li',
'/ul'
));
}
}

View File

@ -0,0 +1,609 @@
<?php $this->layout = 'bootstrap2'; ?>
<?php $this->set('title_for_layout', 'Bootstrap2 examples'); ?>
<div class="row">
<div class="span3">
<ul class="nav nav-tabs nav-stacked affix">
<li><a href="#forms"><i class="icon-chevron-right pull-right"></i> Forms</a></li>
<li><a href="#pagination"><i class="icon-chevron-right pull-right"></i> Pagination</a></li>
<li><a href="#alerts"><i class="icon-chevron-right pull-right"></i> Alerts</a></li>
</ul>
</div>
<div class="span9">
<h1>BoostCake Examples <small>Bootstrap Version 2.3.2</small></h1>
<section id="forms">
<div class="page-header">
<h2>Forms</h2>
</div>
<h3>Default styles</h3>
<p>Individual form controls receive styling, but without any required base class on the <code>&lt;form&gt;</code> or large changes in markup. Results in stacked, left-aligned labels on top of form controls.</p>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'wrapInput' => false
),
'class' => 'well'
)); ?>
<fieldset>
<legend>Legend</legend>
<?php echo $this->Form->input('text', array(
'label' => 'Label name',
'placeholder' => 'Type something…',
'after' => '<span class="help-block">Example block-level help text here.</span>'
)); ?>
<?php echo $this->Form->input('checkbox', array(
'label' => 'Check me out'
)); ?>
<?php echo $this->Form->submit('Submit', array(
'div' => false,
'class' => 'btn'
)); ?>
</fieldset>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'wrapInput' => false
),
'class' => 'well'
)); ?>
<fieldset>
<legend>Legend</legend>
<?php echo \$this->Form->input('text', array(
'label' => 'Label name',
'placeholder' => 'Type something…',
'after' => '<span class=\"help-block\">Example block-level help text here.</span>'
)); ?>
<?php echo \$this->Form->input('checkbox', array(
'label' => 'Check me out'
)); ?>
<?php echo \$this->Form->submit('Submit', array(
'div' => false,
'class' => 'btn'
)); ?>
</fieldset>
<?php echo \$this->Form->end(); ?>");
?></pre>
<hr>
<h3>Search form</h3>
<p>Add <code>.form-search</code> to the form and <code>.search-query</code> to the <code>&lt;input&gt;</code> for an extra-rounded text input.</p>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'wrapInput' => false
),
'class' => 'well form-search'
)); ?>
<?php echo $this->Form->input('text', array(
'label' => false,
'class' => 'input-medium search-query',
)); ?>
<?php echo $this->Form->submit('Search', array(
'div' => false,
'class' => 'btn'
)); ?>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'wrapInput' => false
),
'class' => 'well form-search'
)); ?>
<?php echo \$this->Form->input('text', array(
'label' => false,
'class' => 'input-medium search-query',
)); ?>
<?php echo \$this->Form->submit('Search', array(
'div' => false,
'class' => 'btn'
)); ?>
<?php echo \$this->Form->end(); ?>");
?></pre>
<hr>
<h3>Inline form</h3>
<p>Add <code>.form-inline</code> for left-aligned labels and inline-block controls for a compact layout.</p>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'label' => false,
'wrapInput' => false
),
'class' => 'well form-inline'
)); ?>
<?php echo $this->Form->input('email', array(
'class' => 'input-small',
'placeholder' => 'Email'
)); ?>
<?php echo $this->Form->input('password', array(
'class' => 'input-small',
'placeholder' => 'Password'
)); ?>
<?php echo $this->Form->input('remember', array(
'label' => array(
'text' => 'Remember me',
'class' => 'checkbox'
),
'checkboxDiv' => false
)); ?>
<?php echo $this->Form->submit('Sign in', array(
'div' => false,
'class' => 'btn'
)); ?>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'label' => false,
'wrapInput' => false
),
'class' => 'well form-inline'
)); ?>
<?php echo \$this->Form->input('email', array(
'class' => 'input-small',
'placeholder' => 'Email'
)); ?>
<?php echo \$this->Form->input('password', array(
'class' => 'input-small',
'placeholder' => 'Password'
)); ?>
<?php echo \$this->Form->input('remember', array(
'label' => array(
'text' => 'Remember me',
'class' => 'checkbox'
),
'checkboxDiv' => false
)); ?>
<?php echo \$this->Form->submit('Sign in', array(
'div' => false,
'class' => 'btn'
)); ?>
<?php echo \$this->Form->end(); ?>");
?></pre>
<hr>
<h3>Horizontal form</h3>
<p>
Right align labels and float them to the left to make them appear on the same line as controls.
Requires the most markup changes from a default form:
</p>
<ul>
<li>Add <code>.form-horizontal</code> to the form</li>
<li>Wrap labels and controls in <code>.control-group</code></li>
<li>Add <code>.control-label</code> to the label</li>
<li>Wrap any associated controls in <code>.controls</code> for proper alignment</li>
</ul>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'control-group',
'label' => array(
'class' => 'control-label'
),
'wrapInput' => 'controls'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo $this->Form->input('email', array(
'placeholder' => 'Email'
)); ?>
<?php echo $this->Form->input('password', array(
'placeholder' => 'Password'
)); ?>
<?php echo $this->Form->input('remember', array(
'label' => 'Remember me',
'afterInput' => $this->Form->submit('Sign in', array(
'class' => 'btn'
))
)); ?>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'control-group',
'label' => array(
'class' => 'control-label'
),
'wrapInput' => 'controls'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo \$this->Form->input('email', array(
'placeholder' => 'Email'
)); ?>
<?php echo \$this->Form->input('password', array(
'placeholder' => 'Password'
)); ?>
<?php echo \$this->Form->input('remember', array(
'label' => 'Remember me',
'afterInput' => \$this->Form->submit('Sign in', array(
'class' => 'btn'
))
)); ?>
<?php echo \$this->Form->end(); ?>");
?></pre>
<hr>
<h3>Other form example</h3>
<?php
$BoostCake = ClassRegistry::getObject('BoostCake');
$BoostCake->validationErrors['password'] = array('Please provide a password');
?>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'control-group',
'label' => array(
'class' => 'control-label'
),
'wrapInput' => 'controls'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo $this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options'
),
'empty' => '選択してください',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
),
)); ?>
<?php echo $this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options Checkbox'
),
'class' => 'checkbox inline',
'multiple' => 'checkbox',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
)
)); ?>
<?php echo $this->Form->input('radio', array(
'type' => 'radio',
'before' => '<label class="control-label">Radio</label>',
'legend' => false,
'options' => array(
1 => 'Option one is this and that—be sure to include why it\'s great',
2 => 'Option two can be something else and selecting it will deselect option one'
)
)); ?>
<?php echo $this->Form->input('username', array(
'placeholder' => 'Username',
'div' => 'control-group input-prepend',
'label' => array(
'text' => 'Prepend',
),
'wrapInput' => 'controls',
'beforeInput' => '<span class="add-on">@</span>'
)); ?>
<?php echo $this->Form->input('price', array(
'div' => 'control-group input-append',
'label' => array(
'text' => 'Append',
),
'wrapInput' => 'controls',
'afterInput' => '<span class="add-on">.00</span>'
)); ?>
<?php echo $this->Form->input('password', array(
'label' => array(
'text' => 'Show Error Message'
),
'placeholder' => 'Password'
)); ?>
<?php echo $this->Form->input('password', array(
'label' => array(
'text' => 'Hide Error Message'
),
'placeholder' => 'Password',
'errorMessage' => false
)); ?>
<?php echo $this->Form->input('checkbox', array(
'label' => array('class' => null),
'afterInput' => '<span class="help-block">Checkbox Bootstrap Style</span>'
)); ?>
<?php echo $this->Form->input('checkbox', array(
'div' => false,
'label' => false,
'before' => '<label class="control-label">Checkbox</label>',
'wrapInput' => 'controls',
'afterInput' => '<span class="help-block">Checkbox CakePHP Style</span>'
)); ?>
<div class="form-actions">
<?php echo $this->Form->submit('Save changes', array(
'div' => false,
'class' => 'btn btn-primary'
)); ?>
<button type="button" class="btn">Cancel</button>
</div>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'control-group',
'label' => array(
'class' => 'control-label'
),
'wrapInput' => 'controls'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo \$this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options'
),
'empty' => '選択してください',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
),
)); ?>
<?php echo \$this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options Checkbox'
),
'class' => 'checkbox inline',
'multiple' => 'checkbox',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
)
)); ?>
<?php echo \$this->Form->input('radio', array(
'type' => 'radio',
'before' => '<label class=\"control-label\">Radio</label>',
'legend' => false,
'options' => array(
1 => 'Option one is this and that—be sure to include why it\'s great',
2 => 'Option two can be something else and selecting it will deselect option one'
)
)); ?>
<?php echo \$this->Form->input('username', array(
'placeholder' => 'Username',
'div' => 'control-group input-prepend',
'label' => array(
'text' => 'Prepend',
),
'wrapInput' => 'controls',
'beforeInput' => '<span class=\"add-on\">@</span>'
)); ?>
<?php echo \$this->Form->input('price', array(
'div' => 'control-group input-append',
'label' => array(
'text' => 'Append',
),
'wrapInput' => 'controls',
'afterInput' => '<span class=\"add-on\">.00</span>'
)); ?>
<?php echo \$this->Form->input('password', array(
'label' => array(
'text' => 'Show Error Message'
),
'placeholder' => 'Password'
)); ?>
<?php echo \$this->Form->input('password', array(
'label' => array(
'text' => 'Hide Error Message'
),
'placeholder' => 'Password',
'errorMessage' => false
)); ?>
<?php echo \$this->Form->input('checkbox', array(
'label' => array('class' => null),
'afterInput' => '<span class=\"help-block\">Checkbox Bootstrap Style</span>'
)); ?>
<?php echo \$this->Form->input('checkbox', array(
'div' => false,
'label' => false,
'before' => '<label class=\"control-label\">Checkbox</label>',
'wrapInput' => 'controls',
'afterInput' => '<span class=\"help-block\">Checkbox CakePHP Style</span>'
)); ?>
<div class=\"form-actions\">
<?php echo \$this->Form->submit('Save changes', array(
'div' => false,
'class' => 'btn btn-primary'
)); ?>
<button type=\"button\" class=\"btn\">Cancel</button>
</div>
<?php echo \$this->Form->end(); ?>");
?></pre>
</section>
<section id="pagination">
<div class="page-header">
<h2>Pagination</h2>
</div>
<h3>Standard pagination</h3>
<p>
Simple pagination inspired by Rdio, great for apps and search results.
The large block is hard to miss, easily scalable, and provides large click areas.
</p>
<?php
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 10,
'current' => 20,
'count' => 1000,
'prevPage' => true,
'nextPage' => true,
'pageCount' => 200,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination'
)); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Paginator->pagination(array('div' => 'pagination')); ?>");
?></pre>
<h3>Sizes</h3>
<p>
Fancy larger or smaller pagination? Add .pagination-large,
<code>.pagination-small</code>, or <code>.pagination-mini</code> for additional sizes.
</p>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination pagination-large'
)); ?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination'
)); ?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination pagination-small'
)); ?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination pagination-mini'
)); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Paginator->pagination(array(
'div' => 'pagination pagination-large'
)); ?>
<?php echo \$this->Paginator->pagination(array(
'div' => 'pagination'
)); ?>
<?php echo \$this->Paginator->pagination(array(
'div' => 'pagination pagination-small'
)); ?>
<?php echo \$this->Paginator->pagination(array(
'div' => 'pagination pagination-mini'
)); ?>");
?></pre>
<h3>Alignment</h3>
<p>
Add one of two optional classes to change the alignment of pagination links:
<code>.pagination-centered</code> and <code>.pagination-right</code>.
</p>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination pagination-centered'
)); ?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'div' => 'pagination pagination-right'
)); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Paginator->pagination(array(
'div' => 'pagination pagination-centered'
)); ?>
<?php echo \$this->Paginator->pagination(array(
'div' => 'pagination pagination-right'
)); ?>");
?></pre>
<h3>Pager</h3>
<p>
Quick previous and next links for simple pagination implementations with light markup and styles.
It's great for simple sites like blogs or magazines.
</p>
<?php echo $this->Paginator->pager(array(
'model' => 'Post',
)); ?>
<?php echo $this->Paginator->pager(array(
'model' => 'Post',
'prev' => '← Older',
'next' => 'Newer →'
)); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Paginator->pager(); ?>
<?php echo \$this->Paginator->pager(array(
'prev' => '← Older',
'next' => 'Newer →'
)); ?>");
?></pre>
</section>
<section id="alerts">
<div class="page-header">
<h2>Alerts</h2>
</div>
<?php echo $this->Session->flash('notice'); ?>
<?php echo $this->Session->flash('success'); ?>
<?php echo $this->Session->flash('error'); ?>
<pre class="prettyprint"><?php
echo h("<?php
// View
echo \$this->Session->flash();
// Controller
\$this->Session->setFlash(__('Alert notice message testing...'), 'alert', array(
'plugin' => 'BoostCake',
));
\$this->Session->setFlash(__('Alert success message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-success'
));
\$this->Session->setFlash(__('Alert error message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-error'
));
?>");
?></pre>
</section>
</div>
</div>

View File

@ -0,0 +1,560 @@
<?php $this->layout = 'bootstrap3'; ?>
<?php $this->set('title_for_layout', 'Bootstrap3 examples'); ?>
<div class="row">
<div class="col col-md-3">
<ul class="nav nav-pills nav-stacked affix">
<li><a href="#forms"><span class="glyphicon glyphicon-chevron-right pull-right"></span> Forms</a></li>
<li><a href="#pagination"><span class="glyphicon glyphicon-chevron-right pull-right"></span> Pagination</a></li>
<li><a href="#alerts"><span class="glyphicon glyphicon-chevron-right pull-right"></span> Alerts</a></li>
</ul>
</div>
<div class="col col-md-9">
<h1>BoostCake Examples <small>Bootstrap Version 3.0.0</small></h1>
<section id="forms">
<div class="page-header">
<h2>Forms</h2>
</div>
<h3>Default styles</h3>
<p>Individual form controls receive styling, but without any required base class on the <code>&lt;form&gt;</code> or large changes in markup. Results in stacked, left-aligned labels on top of form controls.</p>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'form-group',
'wrapInput' => false,
'class' => 'form-control'
),
'class' => 'well'
)); ?>
<fieldset>
<legend>Legend</legend>
<?php echo $this->Form->input('text', array(
'label' => 'Label name',
'placeholder' => 'Type something…',
'after' => '<span class="help-block">Example block-level help text here.</span>'
)); ?>
<?php echo $this->Form->input('checkbox', array(
'label' => 'Check me out',
'class' => false
)); ?>
<?php echo $this->Form->submit('Submit', array(
'div' => false,
'class' => 'btn btn-default'
)); ?>
</fieldset>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'form-group',
'wrapInput' => false,
'class' => 'form-control'
),
'class' => 'well'
)); ?>
<fieldset>
<legend>Legend</legend>
<?php echo \$this->Form->input('text', array(
'label' => 'Label name',
'placeholder' => 'Type something…',
'after' => '<span class=\"help-block\">Example block-level help text here.</span>'
)); ?>
<?php echo \$this->Form->input('checkbox', array(
'label' => 'Check me out',
'class' => false
)); ?>
<?php echo \$this->Form->submit('Submit', array(
'div' => false,
'class' => 'btn btn-default'
)); ?>
</fieldset>
<?php echo \$this->Form->end(); ?>");
?></pre>
<hr>
<h3>Inline form</h3>
<p>Add <code>.form-inline</code> for left-aligned labels and inline-block controls for a compact layout.</p>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'label' => false,
'wrapInput' => false,
'class' => 'form-control'
),
'class' => 'well form-inline'
)); ?>
<?php echo $this->Form->input('email', array(
'placeholder' => 'Email',
'style' => 'width:180px;'
)); ?>
<?php echo $this->Form->input('password', array(
'placeholder' => 'Password',
'style' => 'width:180px;'
)); ?>
<?php echo $this->Form->input('remember', array(
'label' => 'Remember me',
'class' => false
)); ?>
<?php echo $this->Form->submit('Sign in', array(
'div' => false,
'class' => 'btn btn-default'
)); ?>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => false,
'label' => false,
'wrapInput' => false,
'class' => 'form-control'
),
'class' => 'well form-inline'
)); ?>
<?php echo \$this->Form->input('email', array(
'placeholder' => 'Email',
'style' => 'width:180px;'
)); ?>
<?php echo \$this->Form->input('password', array(
'placeholder' => 'Password',
'style' => 'width:180px;'
)); ?>
<?php echo \$this->Form->input('remember', array(
'label' => 'Remember me',
'class' => false
)); ?>
<?php echo \$this->Form->submit('Sign in', array(
'div' => false,
'class' => 'btn btn-default'
)); ?>
<?php echo \$this->Form->end(); ?>");
?></pre>
<hr>
<h3>Horizontal form</h3>
<p>
Use Bootstrap's predefined grid classes to align labels and groups of form controls in a horizontal layout.
</p>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'form-group',
'label' => array(
'class' => 'col col-md-2 control-label'
),
'wrapInput' => 'col col-md-10',
'class' => 'form-control'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo $this->Form->input('email', array(
'placeholder' => 'Email'
)); ?>
<?php echo $this->Form->input('password', array(
'placeholder' => 'Password'
)); ?>
<?php echo $this->Form->input('remember', array(
'wrapInput' => 'col col-md-10 col-md-offset-2',
'label' => 'Remember me',
'class' => false,
'afterInput' => $this->Form->submit('Sign in', array(
'class' => 'btn btn-default'
))
)); ?>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'form-group',
'label' => array(
'class' => 'col col-md-2 control-label'
),
'wrapInput' => 'col col-md-10',
'class' => 'form-control'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo \$this->Form->input('email', array(
'placeholder' => 'Email'
)); ?>
<?php echo \$this->Form->input('password', array(
'placeholder' => 'Password'
)); ?>
<?php echo \$this->Form->input('remember', array(
'wrapInput' => 'col col-md-10 col-md-offset-2',
'label' => 'Remember me',
'class' => false,
'afterInput' => \$this->Form->submit('Sign in', array(
'class' => 'btn btn-default'
))
)); ?>
<?php echo \$this->Form->end(); ?>");
?></pre>
<hr>
<h3>Other form example</h3>
<?php
$BoostCake = ClassRegistry::getObject('BoostCake');
$BoostCake->validationErrors['password'] = array('Please provide a password');
?>
<?php echo $this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'form-group',
'label' => array(
'class' => 'col col-md-2 control-label'
),
'wrapInput' => 'col col-md-10',
'class' => 'form-control'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo $this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options'
),
'empty' => '選択してください',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
),
)); ?>
<?php echo $this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options Checkbox'
),
'class' => 'checkbox-inline',
'multiple' => 'checkbox',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
)
)); ?>
<?php echo $this->Form->input('radio', array(
'type' => 'radio',
'before' => '<label class="col col-md-2 control-label">Radio</label>',
'legend' => false,
'class' => false,
'options' => array(
1 => 'Option one is this and that—be sure to include why it\'s great',
2 => 'Option two can be something else and selecting it will deselect option one'
)
)); ?>
<?php echo $this->Form->input('username', array(
'placeholder' => 'Username',
'label' => array(
'text' => 'Prepend',
),
'between' => '<div class="col col-md-10">',
'wrapInput' => 'input-group',
'beforeInput' => '<span class="input-group-addon">@</span>',
'after' => '</div>'
)); ?>
<?php echo $this->Form->input('price', array(
'label' => array(
'text' => 'Append',
),
'between' => '<div class="col col-md-10">',
'wrapInput' => 'input-group',
'afterInput' => '<span class="input-group-addon">.00</span>',
'after' => '</div>'
)); ?>
<?php echo $this->Form->input('password', array(
'label' => array(
'text' => 'Show Error Message'
),
'placeholder' => 'Password'
)); ?>
<?php echo $this->Form->input('password', array(
'label' => array(
'text' => 'Hide Error Message'
),
'placeholder' => 'Password',
'errorMessage' => false
)); ?>
<?php echo $this->Form->input('checkbox', array(
'wrapInput' => 'col col-md-10 col-md-offset-2',
'label' => array('class' => null),
'class' => false,
'afterInput' => '<span class="help-block">Checkbox Bootstrap Style</span>'
)); ?>
<?php echo $this->Form->input('checkbox', array(
'before' => '<label class="col col-md-2 control-label">Checkbox</label>',
'label' => false,
'class' => false,
'wrapInput' => 'col col-md-10',
'afterInput' => '<span class="help-block">Checkbox CakePHP Style</span>'
)); ?>
<div class="row">
<div class="col col-md-10 col-md-offset-2">
<?php echo $this->Form->submit('Save changes', array(
'div' => false,
'class' => 'btn btn-primary'
)); ?>
<button type="button" class="btn btn-default">Cancel</button>
</div>
</div>
<?php echo $this->Form->end(); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Form->create('BoostCake', array(
'inputDefaults' => array(
'div' => 'form-group',
'label' => array(
'class' => 'col col-md-2 control-label'
),
'wrapInput' => 'col col-md-10',
'class' => 'form-control'
),
'class' => 'well form-horizontal'
)); ?>
<?php echo \$this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options'
),
'empty' => '選択してください',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
),
)); ?>
<?php echo \$this->Form->input('select', array(
'label' => array(
'text' => 'Select Nested Options Checkbox'
),
'class' => 'checkbox-inline',
'multiple' => 'checkbox',
'options' => array(
'東京' => array(
1 => '渋谷',
2 => '秋葉原'
),
'大阪' => array(
3 => '梅田',
4 => '難波'
)
)
)); ?>
<?php echo \$this->Form->input('radio', array(
'type' => 'radio',
'before' => '<label class=\"col col-md-2 control-label\">Radio</label>',
'legend' => false,
'class' => false,
'options' => array(
1 => 'Option one is this and that—be sure to include why it\'s great',
2 => 'Option two can be something else and selecting it will deselect option one'
)
)); ?>
<?php echo \$this->Form->input('username', array(
'placeholder' => 'Username',
'label' => array(
'text' => 'Prepend',
),
'between' => '<div class=\"col col-md-10\">',
'wrapInput' => 'input-group',
'beforeInput' => '<span class=\"input-group-addon\">@</span>',
'after' => '</div>'
)); ?>
<?php echo \$this->Form->input('price', array(
'label' => array(
'text' => 'Append',
),
'between' => '<div class=\"col col-md-10\">',
'wrapInput' => 'input-group',
'afterInput' => '<span class=\"input-group-addon\">.00</span>',
'after' => '</div>'
)); ?>
<?php echo \$this->Form->input('password', array(
'label' => array(
'text' => 'Show Error Message'
),
'placeholder' => 'Password'
)); ?>
<?php echo \$this->Form->input('password', array(
'label' => array(
'text' => 'Hide Error Message'
),
'placeholder' => 'Password',
'errorMessage' => false
)); ?>
<?php echo \$this->Form->input('checkbox', array(
'wrapInput' => 'col col-md-10 col-md-offset-2',
'label' => array('class' => null),
'class' => false,
'afterInput' => '<span class=\"help-block\">Checkbox Bootstrap Style</span>'
)); ?>
<?php echo \$this->Form->input('checkbox', array(
'before' => '<label class=\"col col-md-2 control-label\">Checkbox</label>',
'label' => false,
'class' => false,
'wrapInput' => 'col col-md-10',
'afterInput' => '<span class=\"help-block\">Checkbox CakePHP Style</span>'
)); ?>
<div class=\"row\">
<div class=\"col col-md-10 col-md-offset-2\">
<?php echo \$this->Form->submit('Save changes', array(
'div' => false,
'class' => 'btn btn-primary'
)); ?>
<button type=\"button\" class=\"btn btn-default\">Cancel</button>
</div>
</div>
<?php echo \$this->Form->end(); ?>");
?></pre>
</section>
<section id="pagination">
<div class="page-header">
<h2>Pagination</h2>
</div>
<h3>Standard pagination</h3>
<p>
Simple pagination inspired by Rdio, great for apps and search results.
The large block is hard to miss, easily scalable, and provides large click areas.
</p>
<?php
$this->Paginator->request->params['paging']['Post'] = array(
'page' => 10,
'current' => 20,
'count' => 1000,
'prevPage' => true,
'nextPage' => true,
'pageCount' => 200,
'order' => null,
'limit' => 20,
'options' => array(
'page' => 1,
'conditions' => array()
),
'paramType' => 'named'
);
?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'ul' => 'pagination'
)); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Paginator->pagination(array('ul' => 'pagination')); ?>");
?></pre>
<h3>Sizes</h3>
<p>
Fancy larger or smaller pagination? Add .pagination-lg,
<code>.pagination-sm</code>, or <code>.pagination-mini</code> for additional sizes.
</p>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'ul' => 'pagination pagination-lg'
)); ?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'ul' => 'pagination'
)); ?>
<?php echo $this->Paginator->pagination(array(
'model' => 'Post',
'ul' => 'pagination pagination-sm'
)); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Paginator->pagination(array(
'ul' => 'pagination pagination-lg'
)); ?>
<?php echo \$this->Paginator->pagination(array(
'ul' => 'pagination'
)); ?>
<?php echo \$this->Paginator->pagination(array(
'ul' => 'pagination pagination-sm'
)); ?>");
?></pre>
<h3>Pager</h3>
<p>
Quick previous and next links for simple pagination implementations with light markup and styles.
It's great for simple sites like blogs or magazines.
</p>
<?php echo $this->Paginator->pager(array(
'model' => 'Post',
)); ?>
<?php echo $this->Paginator->pager(array(
'model' => 'Post',
'prev' => '← Older',
'next' => 'Newer →'
)); ?>
<pre class="prettyprint"><?php
echo h("<?php echo \$this->Paginator->pager(); ?>
<?php echo \$this->Paginator->pager(array(
'prev' => '← Older',
'next' => 'Newer →'
)); ?>");
?></pre>
</section>
<section id="alerts">
<div class="page-header">
<h2>Alerts</h2>
</div>
<?php echo $this->Session->flash('success'); ?>
<?php echo $this->Session->flash('info'); ?>
<?php echo $this->Session->flash('warning'); ?>
<?php echo $this->Session->flash('danger'); ?>
<pre class="prettyprint"><?php
echo h("<?php
// View
echo \$this->Session->flash();
// Controller
\$this->Session->setFlash(__('Alert success message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-success'
));
\$this->Session->setFlash(__('Alert info message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-info'
));
\$this->Session->setFlash(__('Alert warning message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-warning'
));
\$this->Session->setFlash(__('Alert danger message testing...'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-danger'
));
?>");
?></pre>
</section>
</div>
</div>

View File

@ -0,0 +1,86 @@
<?php $this->layout = 'bootstrap3'; ?>
<?php $this->set('title_for_layout', 'Bootstrap Plugin for CakePHP'); ?>
<div class="jumbotron">
<h1>
BoostCake
<iframe src="http://ghbtns.com/github-btn.html?user=slywalker&repo=cakephp-plugin-boost_cake&type=watch&count=true&size=large" allowtransparency="true" frameborder="0" scrolling="0" width="170" height="30"></iframe>
</h1>
<p>
This is a plugin for CakePHP using Bootstrap
</p>
<p>
<a href="https://travis-ci.org/slywalker/cakephp-plugin-boost_cake">
<img src="https://travis-ci.org/slywalker/cakephp-plugin-boost_cake.png" alt="Build Status">
</a>
<a href="https://packagist.org/packages/slywalker/boost_cake">
<img src="https://poser.pugx.org/slywalker/boost_cake/d/total.png" alt="Total Downloads">
</a>
<a href="https://packagist.org/packages/slywalker/boost_cake">
<img src="https://poser.pugx.org/slywalker/boost_cake/v/stable.png" alt="Latest Stable Version">
</a>
</p>
<p>
<a href="https://github.com/slywalker/cakephp-plugin-boost_cake" class="btn btn-primary btn-large">
Github Project <i class="icon-chevron-right icon-white"></i>
</a>
<a href="https://packagist.org/packages/slywalker/boost_cake" class="btn btn-primary btn-large">
Packagist <i class="icon-chevron-right icon-white"></i>
</a>
</p>
</div>
<div class="page-header">
<h2>Installation</h2>
</div>
<h3>Composer</h3>
<p>
Ensure require is present in <code>composer.json</code>.
This will install the plugin into <code>Plugin/BoostCake</code>:
</p>
<pre class="prettyprint">{
"require": {
"slywalker/boost_cake": "*"
}
}</pre>
<h3>Enable plugin</h3>
<p>You need to enable the plugin in your app/Config/bootstrap.php file:</p>
<pre class="prettyprint">CakePlugin::load('BoostCake');</pre>
<p>If you are already using <code>CakePlugin::loadAll();</code>, then this is not necessary.</p>
<h3>Add helpers</h3>
<p>You need to add helpers at controller.</p>
<pre class="prettyprint"><?php echo h("<?php
class AppController extends Controller {
public \$helpers = array(
'Session',
'Html' => array('className' => 'BoostCake.BoostCakeHtml'),
'Form' => array('className' => 'BoostCake.BoostCakeForm'),
'Paginator' => array('className' => 'BoostCake.BoostCakePaginator'),
);
}"); ?></pre>
<h3>AuthComponent setting</h3>
<p>Substitute alert-error with alert-danger if Bootstrap 3.</p>
<pre class="prettyprint"><?php echo h("<?php
class AppController extends Controller {
public \$components = array(
'Auth' => array(
'flash' => array(
'element' => 'alert',
'key' => 'auth',
'params' => array(
'plugin' => 'BoostCake',
'class' => 'alert-error'
)
)
)
);
}"); ?></pre>

View File

@ -0,0 +1,14 @@
<?php
if (!isset($class)) {
$class = false;
}
if (!isset($close)) {
$close = true;
}
?>
<div class="alert<?php echo ($class) ? ' ' . $class : null; ?>">
<?php if ($close): ?>
<a class="close" data-dismiss="alert" href="#">×</a>
<?php endif; ?>
<?php echo $message; ?>
</div>

View File

@ -0,0 +1,276 @@
<?php
App::uses('FormHelper', 'View/Helper');
App::uses('Set', 'Utility');
class BoostCakeFormHelper extends FormHelper {
public $helpers = array('Html' => array(
'className' => 'BoostCake.BoostCakeHtml'
));
protected $_divOptions = array();
protected $_inputOptions = array();
protected $_inputType = null;
protected $_fieldName = null;
/**
* Overwrite FormHelper::input()
* Generates a form input element complete with label and wrapper div
*
* ### Options
*
* See each field type method for more information. Any options that are part of
* $attributes or $options for the different **type** methods can be included in `$options` for input().i
* Additionally, any unknown keys that are not in the list below, or part of the selected type's options
* will be treated as a regular html attribute for the generated input.
*
* - `type` - Force the type of widget you want. e.g. `type => 'select'`
* - `label` - Either a string label, or an array of options for the label. See FormHelper::label().
* - `div` - Either `false` to disable the div, or an array of options for the div.
* See HtmlHelper::div() for more options.
* - `options` - For widgets that take options e.g. radio, select.
* - `error` - Control the error message that is produced. Set to `false` to disable any kind of error reporting (field
* error and error messages).
* - `errorMessage` - Boolean to control rendering error messages (field error will still occur).
* - `empty` - String or boolean to enable empty select box options.
* - `before` - Content to place before the label + input.
* - `after` - Content to place after the label + input.
* - `between` - Content to place between the label + input.
* - `format` - Format template for element order. Any element that is not in the array, will not be in the output.
* - Default input format order: array('before', 'label', 'between', 'input', 'after', 'error')
* - Default checkbox format order: array('before', 'input', 'between', 'label', 'after', 'error')
* - Hidden input will not be formatted
* - Radio buttons cannot have the order of input and label elements controlled with these settings.
*
* Added options
* - `wrapInput` - Either `false` to disable the div wrapping input, or an array of options for the div.
* See HtmlHelper::div() for more options.
* - `checkboxDiv` - Wrap input checkbox tag's class.
* - `beforeInput` - Content to place before the input.
* - `afterInput` - Content to place after the input.
* - `errorClass` - Wrap input tag's error message class.
*
* @param string $fieldName This should be "Modelname.fieldname"
* @param array $options Each type of input takes different options.
* @return string Completed form widget.
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#creating-form-elements
*/
public function input($fieldName, $options = array()) {
$this->_fieldName = $fieldName;
$default = array(
'error' => array(
'attributes' => array(
'wrap' => 'span',
'class' => 'help-block text-danger'
)
),
'wrapInput' => array(
'tag' => 'div'
),
'checkboxDiv' => 'checkbox',
'beforeInput' => '',
'afterInput' => '',
'errorClass' => 'has-error error'
);
$options = Hash::merge(
$default,
$this->_inputDefaults,
$options
);
$this->_inputOptions = $options;
$options['error'] = false;
if (isset($options['wrapInput'])) {
unset($options['wrapInput']);
}
if (isset($options['checkboxDiv'])) {
unset($options['checkboxDiv']);
}
if (isset($options['beforeInput'])) {
unset($options['beforeInput']);
}
if (isset($options['afterInput'])) {
unset($options['afterInput']);
}
if (isset($options['errorClass'])) {
unset($options['errorClass']);
}
$inputDefaults = $this->_inputDefaults;
$this->_inputDefaults = array();
$html = parent::input($fieldName, $options);
$this->_inputDefaults = $inputDefaults;
if ($this->_inputType === 'checkbox') {
if (isset($options['before'])) {
$html = str_replace($options['before'], '%before%', $html);
}
$regex = '/(<label.*?>)(.*?<\/label>)/';
if (preg_match($regex, $html, $label)) {
$html = preg_replace($regex, '', $html);
$html = preg_replace(
'/(<input type="checkbox".*?>)/',
$label[1] . '$1 ' . $label[2],
$html
);
}
if (isset($options['before'])) {
$html = str_replace('%before%', $options['before'], $html);
}
}
return $html;
}
/**
* Overwrite FormHelper::_divOptions()
* Generate inner and outer div options
* Generate div options for input
*
* @param array $options
* @return array
*/
protected function _divOptions($options) {
$this->_inputType = $options['type'];
$divOptions = array(
'type' => $options['type'],
'div' => $this->_inputOptions['wrapInput']
);
$this->_divOptions = parent::_divOptions($divOptions);
$default = array('div' => array('class' => null));
$options = Hash::merge($default, $options);
$divOptions = parent::_divOptions($options);
if ($this->tagIsInvalid() !== false) {
$divOptions = $this->addClass($divOptions, $this->_inputOptions['errorClass']);
}
return $divOptions;
}
/**
* Overwrite FormHelper::_getInput()
* Wrap `<div>` input element
* Generates an input element
*
* @param type $args
* @return type
*/
protected function _getInput($args) {
$input = parent::_getInput($args);
if ($this->_inputType === 'checkbox' && $this->_inputOptions['checkboxDiv'] !== false) {
$input = $this->Html->div($this->_inputOptions['checkboxDiv'], $input);
}
$beforeInput = $this->_inputOptions['beforeInput'];
$afterInput = $this->_inputOptions['afterInput'];
$error = null;
$errorOptions = $this->_extractOption('error', $this->_inputOptions, null);
$errorMessage = $this->_extractOption('errorMessage', $this->_inputOptions, true);
if ($this->_inputType !== 'hidden' && $errorOptions !== false) {
$errMsg = $this->error($this->_fieldName, $errorOptions);
if ($errMsg && $errorMessage) {
$error = $errMsg;
}
}
$html = $beforeInput . $input . $error . $afterInput;
if ($this->_divOptions) {
$tag = $this->_divOptions['tag'];
unset($this->_divOptions['tag']);
$html = $this->Html->tag($tag, $html, $this->_divOptions);
}
return $html;
}
/**
* Overwrite FormHelper::_selectOptions()
* If $attributes['style'] is `<input type="checkbox">` then replace `<label>` position
* Returns an array of formatted OPTION/OPTGROUP elements
*
* @param array $elements
* @param array $parents
* @param boolean $showParents
* @param array $attributes
* @return array
*/
protected function _selectOptions($elements = array(), $parents = array(), $showParents = null, $attributes = array()) {
$selectOptions = parent::_selectOptions($elements, $parents, $showParents, $attributes);
if ($attributes['style'] === 'checkbox') {
foreach ($selectOptions as $key => $option) {
$option = preg_replace('/<div.*?>/', '', $option);
$option = preg_replace('/<\/div>/', '', $option);
if (preg_match('/>(<label.*?>)/', $option, $match)) {
$option = $match[1] . preg_replace('/<label.*?>/', ' ', $option);
if (isset($attributes['class'])) {
$option = preg_replace('/(<label.*?)(>)/', '$1 class="' . $attributes['class'] . '"$2', $option);
}
}
$selectOptions[$key] = $option;
}
}
return $selectOptions;
}
/**
* Creates an HTML link, but access the url using the method you specify (defaults to POST).
* Requires javascript to be enabled in browser.
*
* This method creates a `<form>` element. So do not use this method inside an existing form.
* Instead you should add a submit button using FormHelper::submit()
*
* ### Options:
*
* - `data` - Array with key/value to pass in input hidden
* - `method` - Request method to use. Set to 'delete' to simulate HTTP/1.1 DELETE request. Defaults to 'post'.
* - `confirm` - Can be used instead of $confirmMessage.
* - Other options is the same of HtmlHelper::link() method.
* - The option `onclick` will be replaced.
* - `block` - For nested form. use View::fetch() output form.
*
* @param string $title The content to be wrapped by <a> tags.
* @param string|array $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
* @param array $options Array of HTML attributes.
* @param bool|string $confirmMessage JavaScript confirmation message.
* @return string An `<a />` element.
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::postLink
*/
public function postLink($title, $url = null, $options = array(), $confirmMessage = false) {
$block = false;
if (!empty($options['block'])) {
$block = $options['block'];
unset($options['block']);
}
$fields = $this->fields;
$this->fields = array();
$out = parent::postLink($title, $url, $options, $confirmMessage);
$this->fields = $fields;
if ($block) {
$regex = '/<form.*?>.*?<\/form>/';
if (preg_match($regex, $out, $match)) {
$this->_View->append($block, $match[0]);
$out = preg_replace($regex, '', $out);
}
}
return $out;
}
}

View File

@ -0,0 +1,74 @@
<?php
App::uses('HtmlHelper', 'View/Helper');
App::uses('Inflector', 'Utility');
class BoostCakeHtmlHelper extends HtmlHelper {
/**
* Overwrite HtmlHelper::useTag()
* If $tag is `<input type="radio">` then replace `<label>` position
* Returns a formatted existent block of $tags
*
* @param string $tag Tag name
* @return string Formatted block
*/
public function useTag($tag) {
$args = func_get_args();
if ($tag === 'radio') {
$class = (isset($args[3]['class'])) ? $args[3]['class'] : 'radio';
unset($args[3]['class']);
}
$html = call_user_func_array(array('parent', 'useTag'), $args);
if ($tag === 'radio') {
$regex = '/(<label)(.*?>)/';
if (preg_match($regex, $html, $match)) {
$html = $match[1] . ' class="' . $class . '"' . $match[2] . preg_replace($regex, ' ', $html);
}
}
return $html;
}
/**
* Creates a formatted IMG element.
*
* This method will set an empty alt attribute if one is not supplied.
*
* ### Usage:
*
* Create a regular image:
*
* `echo $this->Html->image('cake_icon.png', array('alt' => 'CakePHP'));`
*
* Create an image link:
*
* `echo $this->Html->image('cake_icon.png', array('alt' => 'CakePHP', 'url' => 'http://cakephp.org'));`
*
* ### Options:
*
* - `url` If provided an image link will be generated and the link will point at
* `$options['url']`.
* - `fullBase` If true the src attribute will get a full address for the image file.
* - `plugin` False value will prevent parsing path as a plugin
* - `data-src` For holder.js options. If `$path` is not empty, then unset `$options['data-src']`.
*
* @param string $path Path to the image file, relative to the app/webroot/img/ directory.
* @param array $options Array of HTML attributes. See above for special options.
* @return string completed img tag
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::image
*/
public function image($path, $options = array()) {
if (empty($path)) {
$path = '/';
} else {
if (isset($options['data-src'])) {
unset($options['data-src']);
}
}
return parent::image($path, $options);
}
}

View File

@ -0,0 +1,194 @@
<?php
App::uses('PaginatorHelper', 'View/Helper');
class BoostCakePaginatorHelper extends PaginatorHelper {
public function pagination($options = array()) {
$default = array(
'div' => false,
'ul' => ''
);
$model = (empty($options['model'])) ? $this->defaultModel() : $options['model'];
$pageCount = $this->request->params['paging'][$model]['pageCount'];
if ($pageCount < 2) {
// Don't display pagination if there is only one page
return '';
}
if ($pageCount == 2) {
// If only two pages, don't show duplicate prev/next buttons
$default['units'] = array('prev', 'numbers', 'next');
} else {
$default['units'] = array('first', 'prev', 'numbers', 'next', 'last');
}
$options += $default;
$units = $options['units'];
unset($options['units']);
$div = $options['div'];
unset($options['div']);
$ul = ($options['ul']) ? array('class' => $options['ul']) : array();
unset($options['ul']);
$out = array();
foreach ($units as $unit) {
if ($unit === 'numbers') {
$out[] = $this->{$unit}($options);
} else {
$out[] = $this->{$unit}(null, $options);
}
}
$out = $this->Html->tag('ul', implode("\n", $out), $ul);
if ($div !== false) {
$out = $this->Html->div($div, $out);
}
return $out;
}
public function pager($options = array()) {
$default = array(
'ul' => 'pager',
'prev' => 'Previous',
'next' => 'Next',
'disabled' => 'hide',
);
$options += $default;
$class = $options['ul'];
unset($options['ul']);
$prev = $options['prev'];
unset($options['prev']);
$next = $options['next'];
unset($options['next']);
$out = array();
$out[] = $this->prev($prev, array_merge($options, array('class' => 'previous')));
$out[] = $this->next($next, array_merge($options, array('class' => 'next')));
return $this->Html->tag('ul', implode("\n", $out), compact('class'));
}
public function prev($title = null, $options = array(), $disabledTitle = null, $disabledOptions = array()) {
$default = array(
'title' => '<',
'tag' => 'li',
'model' => $this->defaultModel(),
'class' => null,
'disabled' => 'disabled',
);
$options += $default;
if (empty($title)) {
$title = $options['title'];
}
unset($options['title']);
$disabled = $options['disabled'];
$params = (array)$this->params($options['model']);
if ($disabled === 'hide' && !$params['prevPage']) {
return null;
}
unset($options['disabled']);
return parent::prev($title, $options, $this->link($title), array_merge($options, array(
'escape' => false,
'class' => $disabled,
)));
}
public function next($title = null, $options = array(), $disabledTitle = null, $disabledOptions = array()) {
$default = array(
'title' => '>',
'tag' => 'li',
'model' => $this->defaultModel(),
'class' => null,
'disabled' => 'disabled',
);
$options += $default;
if (empty($title)) {
$title = $options['title'];
}
unset($options['title']);
$disabled = $options['disabled'];
$params = (array)$this->params($options['model']);
if ($disabled === 'hide' && !$params['nextPage']) {
return null;
}
unset($options['disabled']);
return parent::next($title, $options, $this->link($title), array_merge($options, array(
'escape' => false,
'class' => $disabled,
)));
}
public function numbers($options = array()) {
$defaults = array(
'tag' => 'li',
'before' => null,
'after' => null,
'model' => $this->defaultModel(),
'class' => null,
'modulus' => 4,
'separator' => false,
'first' => null,
'last' => null,
'ellipsis' => '<li class="disabled"><a href="#">…</a></li>',
'currentClass' => 'current'
);
$options += $defaults;
$return = parent::numbers($options);
return preg_replace('@<li class="current">(.*?)</li>@', '<li class="current disabled"><a href="#">\1</a></li>', $return);
}
public function first($title = null, $options = array()) {
$default = array(
'title' => '<<',
'tag' => 'li',
'after' => null,
'model' => $this->defaultModel(),
'separator' => null,
'ellipsis' => null,
'class' => null,
);
$options += $default;
if (empty($title)) {
$title = $options['title'];
}
unset($options['title']);
return (parent::first($title, $options)) ? (parent::first($title, $options)) : $this->Html->tag(
$options['tag'],
$this->link($title, array(), $options),
array('class' => 'disabled')
);
}
public function last($title = null, $options = array()) {
$default = array(
'title' => '>>',
'tag' => 'li',
'after' => null,
'model' => $this->defaultModel(),
'separator' => null,
'ellipsis' => null,
'class' => null,
);
$options += $default;
if (empty($title)) {
$title = $options['title'];
}
unset($options['title']);
$params = (array)$this->params($options['model']);
return (parent::last($title, $options)) ? (parent::last($title, $options)) : $this->Html->tag(
$options['tag'],
$this->link($title, array(), $options),
array('class' => 'disabled')
);
}
}

View File

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>
BoostCake -
<?php echo $title_for_layout; ?>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<!-- Le styles -->
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<style>
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
}
.affix {
position: fixed;
top: 60px;
width: 220px;
}
</style>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<?php
echo $this->fetch('meta');
echo $this->fetch('css');
?>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<?php echo $this->Html->link('BoostCake', array(
'plugin' => 'boost_cake',
'controller' => 'boost_cake',
'action' => 'index'
), array('class' => 'brand')); ?>
<ul class="nav">
<li><?php echo $this->Html->link('Bootstrap3', array(
'action' => 'bootstrap3'
)); ?></li>
<li><?php echo $this->Html->link('Bootstrap2', array(
'action' => 'bootstrap2'
)); ?></li>
</ul>
</div>
</div>
</div>
<div class="container">
<?php echo $this->fetch('content'); ?>
</div><!-- /container -->
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="//google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
<?php echo $this->fetch('script'); ?>
</body>
</html>

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>
BoostCake -
<?php echo $title_for_layout; ?>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<!-- Le styles -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<style>
body {
padding-top: 70px; /* 70px to make the container go all the way to the bottom of the topbar */
}
.affix {
position: fixed;
top: 60px;
width: 220px;
}
</style>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<?php
echo $this->fetch('meta');
echo $this->fetch('css');
?>
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<?php echo $this->Html->link('BoostCake', array(
'plugin' => 'boost_cake',
'controller' => 'boost_cake',
'action' => 'index'
), array('class' => 'navbar-brand')); ?>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
<li><?php echo $this->Html->link('Bootstrap3', array(
'action' => 'bootstrap3'
)); ?></li>
<li><?php echo $this->Html->link('Bootstrap2', array(
'action' => 'bootstrap2'
)); ?></li>
</ul>
</div>
</div>
</nav>
<div class="container">
<?php echo $this->fetch('content'); ?>
</div><!-- /container -->
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
<?php echo $this->fetch('script'); ?>
</body>
</html>

View File

@ -0,0 +1,29 @@
{
"name": "slywalker/boost_cake",
"type": "cakephp-plugin",
"description": "BoostCake is a plugin for CakePHP using Bootstrap",
"keywords": [
"cakephp",
"bootstrap",
"twitter"
],
"homepage": "http://slywalker.github.io/cakephp-plugin-boost_cake/",
"license": "MIT",
"authors": [
{
"name": "Yasuo Harada",
"email": "slywalker.net@gmail.com"
}
],
"support": {
"issues": "https://github.com/slywalker/cakephp-plugin-boost_cake/issues",
"source": "https://github.com/slywalker/cakephp-plugin-boost_cake"
},
"require": {
"php": ">=5.3.0",
"composer/installers": "*"
},
"suggest": {
"twitter/bootstrap": "Bootstrap for Twitter"
}
}

0
web/app/Plugin/empty Normal file
View File

View File

View File

View File

0
web/app/Vendor/empty vendored Normal file
View File

View File

@ -0,0 +1,12 @@
<h2>Bandwidth</h2>
<?php
echo $this->Form->create('Bandwidth', array(
'url' => '/bandwidth',
'novalidate' => true
));
$options = array('low' => 'Low', 'medium' => 'Medium', 'high' => 'High');
echo $this->Form->input('Bandwidth', array('type' => 'select', 'options' => $options));
echo $this->Form->end('Update Bandwidth');
?>
</table>

View File

@ -0,0 +1,102 @@
<ul class="nav nav-tabs">
<?php
foreach ($categories as $key => $value) {
$category = $value['Config']['Category'];
echo '<li data-toggle="tab"><a href="#'.$category.'">' . ucfirst($category) . '</a></li>';
}
?>
</ul>
<?php echo $this->Form->create('Config', array(
'url' => '/config',
'novalidate' => true,
'class' => array('form-horizontal'),
'role' => 'form'
)); ?>
<div class="tab-content">
<?php
foreach ($options as $option => $value) {
echo "<div id=\"$option\" class=\"tab-pane\">";
foreach ($value as $val) {
$id = $val['Config']['Id'];
$name = $val['Config']['Name'];
$inputname = 'Config.' . $id . '.' . $name;
$type = $val['Config']['Type'];
$hint = $val['Config']['Hint'];
$hints = explode('|', $hint);
$selectoptions = array();
// Because I don't want to modify the database, I need
// to work with what is already there to determine
// which types of inputs to use. I can do this based
// off of hthe 'hint' fileld.
//
// If 'hint' contains '|', it is either a radio
// or select box, though I'm making all radios selects.
// If the 'hint' contains '|' && '=', it was supposed to be a
// select.
//
// This would be much easier if each Config row had an 'inputtype' column...
// If the type is supposed to be a radio...
// I'm making it a select anyway!
if (preg_match("/\|/", $hint) && ($type != 'boolean') ) {
$inputtype = 'select';
foreach ($hints as $hint) {
$foo = explode('|', $hint);
$selectoptions[$foo[0]] = $foo[0]; // I don't want my selects indexed - I want them associated.
}
}
// If the type is supposed to be a select box...
if ( preg_match("/\=/", $hint) && ($inputtype == 'select') ) {
$selectoptions = array();
foreach ($hints as $hint) {
$foo = explode('=', $hint);
$selectoptions[$foo[1]] = $foo[0];
}
}
// For all of the other types, set them appropriately.
switch ($type) {
case 'boolean':
$inputtype = 'checkbox';
break;
case 'integer':
$inputtype = 'text';
break;
case 'string':
$inputtype = 'text';
break;
case 'text':
$inputtype = 'textarea';
break;
}
// Create the actual inputs. 'options' and 'legend'
// are ignored when they're not needed, such as in
// the case of a text or checkbox input type.
echo "<div class=\"form-group\">";
echo $this->Form->label($inputname, $name, array('class' => array('col-sm-3', 'col-md-3', 'col-lg-3', 'control-label')));
echo '<div class="col-lg-9">';
echo $this->Form->$inputtype($inputname, array(
'default' => $val['Config']['Value'],
'label' => false,
'div' => false,
'title' => $val['Config']['Prompt'],
'type' => $inputtype,
'options' => $selectoptions, // Only used by cakephp when 'type' is 'select'
'legend' => false
));
echo '</div>';
echo '<span class="help-block">' . $val['Config']['Prompt'] . '</span>';
echo "</div>";
}
echo "</div>"; // End each category div
}
?>
</div> <!-- End the tabs div -->
<? echo $this->Form->end('Save Config'); ?>

View File

View File

@ -0,0 +1,13 @@
<div class="tab-pane" id="buffers">
<?php
echo $this->Form->inputs(array(
'ImageBufferCount',
'WarmupCount',
'PreEventCount',
'PostEventCount',
'StreamReplayBuffer',
'AlarmFrameCount',
'legend' => false
));
?>
</div>

View File

@ -0,0 +1,2 @@
<div class="tab-pane" id="control">
</div>

View File

@ -0,0 +1,11 @@
<div id="general" class="tab-pane active">
<?php
echo $this->Form->input('Name');
echo $this->Form->input('Type', array( 'type' => 'select', 'options' => $typeoptions));
echo $this->Form->input('Function', array('type' => 'select', 'options' => $functionoptions));
echo $this->Form->input('Enabled', array('type' => 'checkbox'));
echo $this->Form->input('MaxFPS');
echo $this->Form->input('AlarmMaxFPS');
echo $this->Form->input('RefBlendPerc');
?>
</div>

View File

@ -0,0 +1,21 @@
<div class="tab-pane" id="misc">
<?php
echo $this->Form->inputs(array(
'EventPrefix',
'SectionLength',
'FrameSkip',
'FPSReportInterval',
'DefaultView',
'DefaultRate',
'DefaultScale',
'WebColour',
'legend' => false
));
echo $this->Form->input('LinkedMonitors', array(
'type' => 'checkbox',
'options' => $linkedMonitors,
));
?>
</div>

View File

@ -0,0 +1,50 @@
<div class="tab-pane" id="source">
<?php
switch ($monitor['Type']) {
case 'Remote':
echo $this->Form->input('Protocol', array(
'type' => 'select',
'options' => $protocoloptions
));
echo $this->Form->input('Method', array(
'type' => 'select',
'options' => $methodoptions
));
echo $this->Form->input('Host');
echo $this->Form->input('Port');
echo $this->Form->input('Path');
break;
case 'Local':
echo $this->Form->input('Path');
echo $this->Form->input('Method', array(
'type' => 'select',
'options' => $optionsMethod
));
echo $this->Form->input('Channel', array(
'type' => 'select',
'options' => $channeloptions
));
echo $this->Form->input('Format', array(
'type' => 'select',
'options' => $formatoptions
));
echo $this->Form->input('Palette', array(
'type' => 'select',
'options' => $optionsPalette
));
break;
case 'File':
break;
}
echo $this->Form->input('Colours', array(
'type' => 'select',
'options' => $optionsColours
));
echo $this->Form->input('Width');
echo $this->Form->input('Height');
?>
</div>

View File

@ -0,0 +1,10 @@
<div class="tab-pane" id="timestamp">
<?php
echo $this->Form->inputs(array(
'LabelFormat',
'LabelX',
'LabelY',
'legend' => false
));
?>
</div>

View File

@ -0,0 +1,26 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.View.Emails.html
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<?php
$content = explode("\n", $content);
foreach ($content as $line):
echo '<p> ' . $line . "</p>\n";
endforeach;
?>

View File

@ -0,0 +1,20 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.View.Emails.text
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<?php echo $content; ?>

View File

@ -0,0 +1,32 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.View.Errors
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php printf(
__d('cake', 'The requested address %s was not found on this server.'),
"<strong>'{$url}'</strong>"
); ?>
</p>
<?php
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
?>

View File

@ -0,0 +1,29 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.View.Errors
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
?>
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php echo __d('cake', 'An Internal Error Has Occurred.'); ?>
</p>
<?php
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
?>

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